diff --git a/keystore-engine/Android.mk b/keystore-engine/Android.mk
index c995dfc..e65e011 100644
--- a/keystore-engine/Android.mk
+++ b/keystore-engine/Android.mk
@@ -32,7 +32,9 @@
 	libhidlbase \
 	libkeystore_aidl \
 	libkeystore_binder \
+	libkeystore_parcelables \
 	liblog \
+	libbase \
 	libutils
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
diff --git a/keystore-engine/keystore_backend_binder.cpp b/keystore-engine/keystore_backend_binder.cpp
index 79b0ec3..cd407c8 100644
--- a/keystore-engine/keystore_backend_binder.cpp
+++ b/keystore-engine/keystore_backend_binder.cpp
@@ -22,20 +22,61 @@
 
 #include "keystore_backend_binder.h"
 
+#include <android-base/logging.h>
 #include <android/security/IKeystoreService.h>
 #include <binder/IServiceManager.h>
+#include <keystore/KeyCharacteristics.h>
+#include <keystore/KeymasterArguments.h>
+#include <keystore/KeymasterBlob.h>
+#include <keystore/OperationResult.h>
+#include <keystore/keymaster_types.h>
 #include <keystore/keystore.h>
 #include <keystore/keystore_hidl_support.h>
+#include <keystore/keystore_return_types.h>
 
 using android::security::IKeystoreService;
 using namespace android;
-using keystore::blob2hidlVec;
 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;
 };
 
+#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 {};
+}
+
 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();
@@ -43,20 +84,88 @@
     sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
 
     if (service == nullptr) {
-        ALOGE("could not contact keystore");
+        LOG(ERROR) << AT << "could not contact keystore";
         return -1;
     }
 
-    auto inBlob = blob2hidlVec(in, len);
-    std::vector<uint8_t> reply_vec;
-    auto ret = service->sign(String16(key_id), inBlob, &reply_vec);
-    if (!ret.isOk()) {
+    KeyCharacteristics keyCharacteristics;
+    String16 key_name16(key_id);
+    int32_t aidl_result;
+    auto binder_result = service->getKeyCharacteristics(
+        key_name16, KeymasterBlob(), KeymasterBlob(), UID_SELF, &keyCharacteristics, &aidl_result);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
+        return -1;
+    }
+    if (KSReturn(aidl_result).isOk()) {
+        LOG(ERROR) << AT << "getKeyCharacteristics failed: " << aidl_result;
+    }
+
+    auto algorithm = getKeyAlgoritmFromKeyCharacteristics(keyCharacteristics);
+    if (!algorithm.isOk()) {
+        LOG(ERROR) << AT << "could not get algorithm from key characteristics";
         return -1;
     }
 
-    hidl_vec<uint8_t> reply_hidl(reply_vec);  // makes copy
-    *reply = reply_hidl.releaseData();
-    *reply_len = reply_vec.size();
+    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);
+    OperationResult result;
+    binder_result = service->begin(token, key_name16, (int)KeyPurpose::SIGN, true /*pruneable*/,
+                                   KeymasterArguments(params), std::vector<uint8_t>() /* entropy */,
+                                   UID_SELF, &result);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
+        return -1;
+    }
+    if (!result.resultCode.isOk()) {
+        LOG(ERROR) << AT << "begin failed: " << int32_t(result.resultCode);
+        return -1;
+    }
+    auto handle = std::move(result.token);
+
+    do {
+        binder_result = service->update(handle, KeymasterArguments(params),
+                                        std::vector<uint8_t>(in, in + len), &result);
+        if (!binder_result.isOk()) {
+            LOG(ERROR) << AT << "communication error while calling keystore";
+            return -1;
+        }
+        if (!result.resultCode.isOk()) {
+            LOG(ERROR) << AT << "update failed: " << int32_t(result.resultCode);
+            return -1;
+        }
+        if (result.inputConsumed > len) {
+            LOG(ERROR) << AT << "update consumed more data than provided";
+            service->abort(handle, &aidl_result);
+            return -1;
+        }
+        len -= result.inputConsumed;
+        in += result.inputConsumed;
+    } while (len > 0);
+
+    binder_result =
+        service->finish(handle, KeymasterArguments(params), std::vector<uint8_t>() /* signature */,
+                        std::vector<uint8_t>() /* entropy */, &result);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
+        return -1;
+    }
+    if (!result.resultCode.isOk()) {
+        LOG(ERROR) << AT << "finish failed: " << int32_t(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;
 }
 
@@ -67,18 +176,29 @@
     sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
 
     if (service == nullptr) {
-        ALOGE("could not contact keystore");
+        LOG(ERROR) << AT << "could not contact keystore";
         return -1;
     }
 
-    std::vector<uint8_t> pubkey_vec;
-    auto ret = service->get_pubkey(String16(key_id), &pubkey_vec);
-    if (!ret.isOk()) {
+    ExportResult result;
+    auto binder_result = service->exportKey(String16(key_id), static_cast<int32_t>(KeyFormat::X509),
+                                            KeymasterBlob() /* clientId */,
+                                            KeymasterBlob() /* appData */, UID_SELF, &result);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
+        return -1;
+    }
+    if (!result.resultCode.isOk()) {
+        LOG(ERROR) << AT << "exportKey failed: " << int32_t(result.resultCode);
         return -1;
     }
 
-    hidl_vec<uint8_t> hidl_pubkey(pubkey_vec);  // makes copy
-    *pubkey = hidl_pubkey.releaseData();        // caller should clean up memory.
-    *pubkey_len = pubkey_vec.size();
+    hidl_vec<uint8_t> reply_hidl(result.exportData);
+    if (pubkey_len) {
+        *pubkey_len = reply_hidl.size();
+    }
+    if (pubkey) {
+        *pubkey = reply_hidl.releaseData();
+    }
     return 0;
 }
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 210b8b5..1168e90 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -13,6 +13,7 @@
     },
 
     clang: true,
+    cpp_std: "c++17",
 }
 
 cc_binary {
@@ -32,6 +33,7 @@
         "key_store_service.cpp",
         "keyblob_utils.cpp",
         "keymaster_enforcement.cpp",
+        "keymaster_worker.cpp",
         "keystore_attestation_id.cpp",
         "keystore_main.cpp",
         "keystore_utils.cpp",
diff --git a/keystore/KeyStore.cpp b/keystore/KeyStore.cpp
index 3a8861e..8c4844f 100644
--- a/keystore/KeyStore.cpp
+++ b/keystore/KeyStore.cpp
@@ -37,6 +37,8 @@
 #include "permissions.h"
 #include <keystore/keystore_hidl_support.h>
 
+#include "keymaster_worker.h"
+
 namespace keystore {
 
 const char* KeyStore::kOldMasterKey = ".masterkey";
@@ -47,35 +49,25 @@
 
 using android::String8;
 
-sp<Keymaster>& KeymasterDevices::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 at(static_cast<uint32_t>(secLevel));
-}
-
-sp<Keymaster> KeymasterDevices::operator[](SecurityLevel secLevel) const {
-    if (static_cast<uint32_t>(secLevel) > static_cast<uint32_t>(SecurityLevel::STRONGBOX)) {
-        LOG(ERROR) << "Invalid security level requested";
-        return nullptr;
-    }
-    return (*const_cast<KeymasterDevices*>(this))[secLevel];
-}
-
 KeyStore::KeyStore(Entropy* entropy, const KeymasterDevices& kmDevices,
                    SecurityLevel minimalAllowedSecurityLevelForNewKeys)
-    : mEntropy(entropy), mKmDevices(kmDevices),
-      mAllowNewFallback(minimalAllowedSecurityLevelForNewKeys == SecurityLevel::SOFTWARE) {
+    : mEntropy(entropy),
+      mAllowNewFallback(minimalAllowedSecurityLevelForNewKeys == SecurityLevel::SOFTWARE),
+      mConfirmationManager(new ConfirmationManager(this)) {
     memset(&mMetaData, '\0', sizeof(mMetaData));
+
+    static_assert(std::tuple_size<std::decay_t<decltype(kmDevices)>>::value ==
+                      std::tuple_size<decltype(mKmDevices)>::value,
+                  "KmasterDevices and KeymasterWorkers must have the same size");
+    for (size_t i = 0; i < kmDevices.size(); ++i) {
+        if (kmDevices[SecurityLevel(i)]) {
+            mKmDevices[SecurityLevel(i)] =
+                std::make_shared<KeymasterWorker>(kmDevices[SecurityLevel(i)], this);
+        }
+    }
 }
 
 KeyStore::~KeyStore() {
-    for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); it != mMasterKeys.end();
-         it++) {
-        delete *it;
-    }
-    mMasterKeys.clear();
 }
 
 ResponseCode KeyStore::initialize() {
@@ -88,134 +80,100 @@
 }
 
 ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
-    UserState* userState = getUserState(userId);
+    auto userState = mUserStateDB.getUserState(userId);
     return userState->initialize(pw, mEntropy);
 }
 
 ResponseCode KeyStore::copyMasterKey(uid_t srcUser, uid_t dstUser) {
-    UserState* userState = getUserState(dstUser);
-    UserState* initState = getUserState(srcUser);
-    return userState->copyMasterKey(initState);
+    auto userState = mUserStateDB.getUserState(dstUser);
+    auto initState = mUserStateDB.getUserState(srcUser);
+    return userState->copyMasterKey(&initState);
 }
 
 ResponseCode KeyStore::writeMasterKey(const android::String8& pw, uid_t userId) {
-    UserState* userState = getUserState(userId);
+    auto userState = mUserStateDB.getUserState(userId);
     return userState->writeMasterKey(pw, mEntropy);
 }
 
 ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) {
-    UserState* userState = getUserState(userId);
+    auto userState = mUserStateDB.getUserState(userId);
     return userState->readMasterKey(pw, mEntropy);
 }
 
-/* Here is the encoding of keys. This is necessary in order to allow arbitrary
- * characters in keys. 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. */
-
-static size_t encode_key_length(const android::String8& keyName) {
-    const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
-    size_t length = keyName.length();
-    for (int i = length; i > 0; --i, ++in) {
-        if (*in < '0' || *in > '~') {
-            ++length;
-        }
-    }
-    return length;
+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;
 }
 
-static int encode_key(char* out, const android::String8& keyName) {
-    const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
-    size_t length = keyName.length();
-    for (int i = length; i > 0; --i, ++in, ++out) {
-        if (*in < '0' || *in > '~') {
-            *out = '+' + (*in >> 6);
-            *++out = '0' + (*in & 0x3F);
-            ++length;
-        } else {
-            *out = *in;
-        }
-    }
-    *out = '\0';
-    return length;
-}
-
-android::String8 KeyStore::getKeyName(const android::String8& keyName, const BlobType type) {
-    std::vector<char> encoded(encode_key_length(keyName) + 1);  // add 1 for null char
-    encode_key(encoded.data(), keyName);
-    if (type == TYPE_KEY_CHARACTERISTICS) {
-        return android::String8::format(".chr_%s", encoded.data());
-    } else {
-        return android::String8(encoded.data());
-    }
-}
-
-android::String8 KeyStore::getKeyNameForUid(const android::String8& keyName, uid_t uid,
-                                            const BlobType type) {
-    std::vector<char> encoded(encode_key_length(keyName) + 1);  // add 1 for null char
-    encode_key(encoded.data(), keyName);
-    if (type == TYPE_KEY_CHARACTERISTICS) {
-        return android::String8::format(".%u_chr_%s", uid, encoded.data());
-    } else {
-        return android::String8::format("%u_%s", uid, encoded.data());
-    }
-}
-
-android::String8 KeyStore::getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid,
-                                                   const BlobType type) {
-    std::vector<char> encoded(encode_key_length(keyName) + 1);  // add 1 for null char
-    encode_key(encoded.data(), keyName);
-
-    if (type == TYPE_KEY_CHARACTERISTICS) {
-        return android::String8::format("%s/.%u_chr_%s", getUserStateByUid(uid)->getUserDirName(),
-                                        uid, encoded.data());
-    } else {
-        return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid,
-                                        encoded.data());
-    }
-}
-
-NullOr<android::String8> KeyStore::getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
-                                                           const BlobType type) {
-    android::String8 filepath8(getKeyNameForUidWithDir(alias, uid, type));
-
-    if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
+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) {
-        filepath8 = getKeyNameForUidWithDir(alias, euid, type);
-        if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
+        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.string());
+    auto grant = mGrants.get(uid, alias);
     if (grant) {
-        filepath8 = String8::format(
-            "%s/%s", grant->owner_dir_name_.c_str(),
-            getKeyNameForUid(String8(grant->alias_.c_str()), grant->owner_uid_, type).c_str());
-        if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
+        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;
-    UserState* userState = getUserState(userId);
-    if (list(prefix, &aliases, userId) != ResponseCode::NO_ERROR) {
+
+    // DO NOT
+    // move
+    // auto userState = userStateDB_.getUserState(userId);
+    // here, in an attempt to replace userStateDB_.getUserState(userId) with userState.
+    // userState is a proxy that holds a lock which may 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 only briefly grabs the lock.
+    // Grabbing the user state lock after the list call is also save since workers cannot grab
+    // blob entry locks.
+
+    auto userState = mUserStateDB.getUserState(userId);
+    std::string userDirName = userState->getUserDirName();
+    auto encryptionKey = userState->getEncryptionKey();
+    auto state = userState->getState();
+    // unlock the user state
+    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 (uint32_t i = 0; i < aliases.size(); i++) {
-        android::String8 filename(aliases[i]);
-        filename = android::String8::format("%s/%s", userState->getUserDirName(),
-                                            getKeyName(filename, TYPE_ANY).string());
+
+    for (LockedKeyBlobEntry& lockedEntry : matches) {
         bool shouldDelete = true;
+
         if (keepUnenryptedEntries) {
             Blob blob;
-            ResponseCode rc = get(filename, &blob, ::TYPE_ANY, userId);
+            Blob charBlob;
+            ResponseCode rc;
+
+            std::tie(rc, blob, charBlob) = lockedEntry.readBlobs(encryptionKey, state);
 
             switch (rc) {
             case ResponseCode::SYSTEM_ERROR:
@@ -234,23 +192,18 @@
                 break;
 
             default:
-                ALOGE("Got unexpected return code %d from KeyStore::get()", rc);
+                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(filename, ::TYPE_ANY, userId);
-
-            // del() will fail silently if no cached characteristics are present for this alias.
-            android::String8 chr_filename(aliases[i]);
-            chr_filename = android::String8::format(
-                "%s/%s", userState->getUserDirName(),
-                getKeyName(chr_filename, TYPE_KEY_CHARACTERISTICS).string());
-            del(chr_filename, ::TYPE_KEY_CHARACTERISTICS, userId);
+            del(lockedEntry);
         }
     }
+
+    userState = mUserStateDB.getUserState(userId);
     if (!userState->deleteMasterKey()) {
         ALOGE("Failed to delete user %d's master key", userId);
     }
@@ -262,336 +215,138 @@
 }
 
 bool KeyStore::isEmpty(uid_t userId) const {
-    const UserState* userState = getUserState(userId);
-    if (userState == nullptr) {
-        return true;
-    }
-
-    DIR* dir = opendir(userState->getUserDirName());
-    if (!dir) {
-        return true;
-    }
-
-    bool result = true;
-    struct dirent* file;
-    while ((file = readdir(dir)) != nullptr) {
-        // We only care about files.
-        if (file->d_type != DT_REG) {
-            continue;
+    std::string userDirName;
+    {
+        // userState hold a lock which must be relinqhished before list is called. This scope
+        // prevents deadlocks.
+        auto userState = mUserStateDB.getUserState(userId);
+        if (!userState) {
+            return true;
         }
-
-        // Skip anything that starts with a "."
-        if (file->d_name[0] == '.') {
-            continue;
-        }
-
-        result = false;
-        break;
+        userDirName = userState->getUserDirName();
     }
-    closedir(dir);
-    return result;
+
+    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) {
-    UserState* userState = getUserState(userId);
+    auto userState = mUserStateDB.getUserState(userId);
     userState->zeroizeMasterKeysInMemory();
     userState->setState(STATE_LOCKED);
 }
 
-static void maybeLogKeyIntegrityViolation(const char* filename, const BlobType type);
+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());
+}
 
-ResponseCode KeyStore::get(const char* filename, Blob* keyBlob, const BlobType type, uid_t userId) {
-    UserState* userState = getUserState(userId);
-    ResponseCode rc;
+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(filename, type);
+            maybeLogKeyIntegrityViolation(blobfile, type);
         }
     });
 
-    rc = keyBlob->readBlob(filename, userState->getEncryptionKey(), userState->getState());
+    result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState());
     if (rc != ResponseCode::NO_ERROR) {
-        return rc;
+        return result;
     }
 
-    const uint8_t version = keyBlob->getVersion();
+    // 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(filename, keyBlob, version, type, userId)) {
-            if ((rc = this->put(filename, keyBlob, userId)) != ResponseCode::NO_ERROR ||
-                (rc = keyBlob->readBlob(filename, userState->getEncryptionKey(),
-                                        userState->getState())) != ResponseCode::NO_ERROR) {
-                return rc;
+        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;
             }
         }
     }
 
-    /*
-     * This will upgrade software-backed keys to hardware-backed keys.
-     */
-    if (rc == ResponseCode::NO_ERROR && type == TYPE_KEY_PAIR && keyBlob->isFallback()) {
-        ResponseCode imported =
-            importKey(keyBlob->getValue(), keyBlob->getLength(), filename, userId,
-                      keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
-
-        // The HAL allowed the import, reget the key to have the "fresh" version.
-        if (imported == ResponseCode::NO_ERROR) {
-            rc = get(filename, keyBlob, TYPE_KEY_PAIR, userId);
-        }
-    }
-
-    // Keymaster 0.3 keys are valid keymaster 1.0 keys, so silently upgrade.
-    if (keyBlob->getType() == TYPE_KEY_PAIR) {
-        keyBlob->setType(TYPE_KEYMASTER_10);
-        rc = this->put(filename, keyBlob, userId);
-    }
-
-    if (type != TYPE_ANY && keyBlob->getType() != type) {
-        ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
-        return ResponseCode::KEY_NOT_FOUND;
-    }
-
-    return rc;
+    return result;
 }
 
-ResponseCode KeyStore::put(const char* filename, Blob* keyBlob, uid_t userId) {
-    UserState* userState = getUserState(userId);
-    return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(),
-                              mEntropy);
+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(), mEntropy);
 }
 
-static NullOr<std::tuple<uid_t, std::string>> filename2UidAlias(const std::string& filename);
-
-ResponseCode KeyStore::del(const char* filename, const BlobType type, uid_t userId) {
+ResponseCode KeyStore::del(const LockedKeyBlobEntry& blobfile) {
     Blob keyBlob;
-    auto uidAlias = filename2UidAlias(filename);
-    uid_t uid;
-    std::string alias;
-    if (uidAlias.isOk()) {
-        std::tie(uid, alias) = std::move(uidAlias).value();
-    }
-    ResponseCode rc = get(filename, &keyBlob, type, userId);
-    if (rc == ResponseCode::VALUE_CORRUPTED) {
-        // The file is corrupt, the best we can do is rm it.
-        if (uidAlias.isOk()) {
-            // remove possible grants
-            mGrants.removeAllGrantsToKey(uid, alias);
-        }
-        return (unlink(filename) && errno != ENOENT) ? ResponseCode::SYSTEM_ERROR
-                                                     : ResponseCode::NO_ERROR;
-    }
+    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_KEY_PAIR || keyBlob.getType() == ::TYPE_KEYMASTER_10) {
-        auto ret = KS_HANDLE_HIDL_ERROR(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() && uidAlias.isOk()) {
-            android_log_event_list(SEC_TAG_KEY_DESTROYED)
-                << int32_t(success) << alias << int32_t(uid) << LOG_ID_SECURITY;
-        }
-        if (!success) return ResponseCode::SYSTEM_ERROR;
-    }
-
-    rc =
-        (unlink(filename) && errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::NO_ERROR;
-
-    if (rc == ResponseCode::NO_ERROR && keyBlob.getType() != ::TYPE_KEY_CHARACTERISTICS) {
-        // now that we have successfully deleted a key, let's make sure there are no stale grants
-        if (uidAlias.isOk()) {
-            mGrants.removeAllGrantsToKey(uid, alias);
-        }
-    }
-    return rc;
-}
-
-/*
- * Converts from the "escaped" format on disk to actual name.
- * This will be smaller than the input string.
- *
- * Characters that should combine with the next at the end will be truncated.
- */
-static size_t decode_key_length(const char* in, size_t length) {
-    size_t outLength = 0;
-
-    for (const char* end = in + length; in < end; in++) {
-        /* This combines with the next character. */
-        if (*in < '0' || *in > '~') {
-            continue;
-        }
-
-        outLength++;
-    }
-    return outLength;
-}
-
-static void decode_key(char* out, const char* in, size_t length) {
-    for (const char* end = in + length; in < end; in++) {
-        if (*in < '0' || *in > '~') {
-            /* Truncate combining characters at the end. */
-            if (in + 1 >= end) {
-                break;
+    if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
+        dev->deleteKey(blob2hidlVec(keyBlob), [alias, uid](Return<ErrorCode> rc) {
+            auto ret = KS_HANDLE_HIDL_ERROR(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;
             }
-
-            *out = (*in++ - '+') << 6;
-            *out++ |= (*in - '0') & 0x3F;
-        } else {
-            *out++ = *in;
-        }
-    }
-    *out = '\0';
-}
-
-static NullOr<std::tuple<uid_t, std::string>> filename2UidAlias(const std::string& filepath) {
-    auto filenamebase = filepath.find_last_of('/');
-    std::string filename =
-        filenamebase == std::string::npos ? filepath : filepath.substr(filenamebase + 1);
-
-    if (filename[0] == '.') return {};
-
-    auto sep = filename.find('_');
-    if (sep == std::string::npos) return {};
-
-    std::stringstream s(filename.substr(0, sep));
-    uid_t uid;
-    s >> uid;
-    if (!s) return {};
-
-    auto alias = filename.substr(sep + 1);
-
-    std::vector<char> alias_buffer(decode_key_length(alias.c_str(), alias.size()) + 1);
-
-    decode_key(alias_buffer.data(), alias.c_str(), alias.size());
-    return std::tuple<uid_t, std::string>(uid, alias_buffer.data());
-}
-
-ResponseCode KeyStore::list(const android::String8& prefix,
-                            android::Vector<android::String16>* matches, uid_t userId) {
-
-    UserState* userState = getUserState(userId);
-    size_t n = prefix.length();
-
-    DIR* dir = opendir(userState->getUserDirName());
-    if (!dir) {
-        ALOGW("can't open directory for user: %s", strerror(errno));
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    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;
-        }
-
-        if (!strncmp(prefix.string(), file->d_name, n)) {
-            const char* p = &file->d_name[n];
-            size_t plen = strlen(p);
-
-            size_t extra = decode_key_length(p, plen);
-            char* match = (char*)malloc(extra + 1);
-            if (match != nullptr) {
-                decode_key(match, p, plen);
-                matches->push(android::String16(match, extra));
-                free(match);
-            } else {
-                ALOGW("could not allocate match of size %zd", extra);
+            if (!success) {
+                LOG(ERROR) << "Keymaster delete for key " << alias << " of uid " << uid
+                           << " failed";
             }
-        }
+        });
     }
-    closedir(dir);
-    return ResponseCode::NO_ERROR;
+
+    return result;
 }
 
-std::string KeyStore::addGrant(const char* alias, uid_t granterUid, uid_t granteeUid) {
-    return mGrants.put(granteeUid, alias, getUserStateByUid(granterUid)->getUserDirName(),
-                       granterUid);
+std::string KeyStore::addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid) {
+    return mGrants.put(granteeUid, blobfile);
 }
 
-bool KeyStore::removeGrant(const char* alias, const uid_t granterUid, const uid_t granteeUid) {
-    return mGrants.removeByFileAlias(granteeUid, granterUid, alias);
+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);
 }
 
-ResponseCode KeyStore::importKey(const uint8_t* key, size_t keyLen, const char* filename,
-                                 uid_t userId, int32_t flags) {
-    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(nullptr, &key, keyLen));
-    if (!pkcs8.get()) {
-        return ResponseCode::SYSTEM_ERROR;
-    }
-    Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
-    if (!pkey.get()) {
-        return ResponseCode::SYSTEM_ERROR;
-    }
-    int type = EVP_PKEY_type(pkey->type);
-    AuthorizationSet params;
-    add_legacy_key_authorizations(type, &params);
-    switch (type) {
-    case EVP_PKEY_RSA:
-        params.push_back(TAG_ALGORITHM, Algorithm::RSA);
-        break;
-    case EVP_PKEY_EC:
-        params.push_back(TAG_ALGORITHM, Algorithm::EC);
-        break;
-    default:
-        ALOGW("Unsupported key type %d", type);
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    AuthorizationSet opParams(params);
-    hidl_vec<uint8_t> blob;
-
-    ErrorCode error;
-    auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
-                      const KeyCharacteristics& /* ignored */) {
-        error = ret;
-        if (error != ErrorCode::OK) return;
-        blob = keyBlob;
-    };
-    auto input = blob2hidlVec(key, keyLen);
-
-    SecurityLevel securityLevel = flagsToSecurityLevel(flags);
-    auto kmDevice = getDevice(securityLevel);
-    if (!kmDevice) {
-        // As of this writing the only caller is KeyStore::get in an attempt to import legacy
-        // software keys. It only ever requests TEE as target which must always be present.
-        // If we see this error, we probably have a new and unanticipated caller.
-        ALOGE("No implementation for security level %d. Cannot import key.", securityLevel);
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    ErrorCode rc = KS_HANDLE_HIDL_ERROR(
-        kmDevice->importKey(params.hidl_data(), KeyFormat::PKCS8, input, hidlCb));
-    if (rc != ErrorCode::OK) return ResponseCode::SYSTEM_ERROR;
-    if (error != ErrorCode::OK) {
-        ALOGE("Keymaster error %d importing key pair", error);
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    Blob keyBlob(&blob[0], blob.size(), nullptr, 0, TYPE_KEYMASTER_10);
-
-    keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
-    keyBlob.setSecurityLevel(securityLevel);
-
-    return put(filename, &keyBlob, userId);
-}
-
 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
@@ -606,74 +361,34 @@
     return keyType == kEcKeyType && version.supportsEc;
 }
 
-ResponseCode KeyStore::getKeyForName(Blob* keyBlob, const android::String8& keyName,
-                                     const uid_t uid, const BlobType type) {
-    auto filepath8 = getBlobFileNameIfExists(keyName, uid, type);
-    uid_t userId = get_user_id(uid);
+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;
 
-    if (filepath8.isOk()) return get(filepath8.value().string(), keyBlob, type, userId);
+    lockedEntry = getLockedBlobEntryIfExists(keyName.string(), uid);
 
-    return ResponseCode::KEY_NOT_FOUND;
-}
+    if (!lockedEntry) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
 
-UserState* KeyStore::getUserState(uid_t userId) {
-    for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); it != mMasterKeys.end();
-         it++) {
-        UserState* state = *it;
-        if (state->getUserId() == userId) {
-            return state;
-        }
+    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);
     }
-
-    UserState* userState = new UserState(userId);
-    if (!userState->initialize()) {
-        /* There's not much we can do if initialization fails. Trying to
-         * unlock the keystore for that user will fail as well, so any
-         * subsequent request for this user will just return SYSTEM_ERROR.
-         */
-        ALOGE("User initialization failed for %u; subsuquent operations will fail", userId);
-    }
-    mMasterKeys.add(userState);
-    return userState;
+    return result;
 }
 
-UserState* KeyStore::getUserStateByUid(uid_t uid) {
-    uid_t userId = get_user_id(uid);
-    return getUserState(userId);
-}
-
-const UserState* KeyStore::getUserState(uid_t userId) const {
-    for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin());
-         it != mMasterKeys.end(); it++) {
-        UserState* state = *it;
-        if (state->getUserId() == userId) {
-            return state;
-        }
-    }
-
-    return nullptr;
-}
-
-const UserState* KeyStore::getUserStateByUid(uid_t uid) const {
-    uid_t userId = get_user_id(uid);
-    return getUserState(userId);
-}
-
-bool KeyStore::upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion,
-                           const BlobType type, uid_t userId) {
+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) {
-        ALOGV("upgrading to version 1 and setting type %d", type);
+        ALOGE("Failed to upgrade key blob. Ancient blob version 0 is no longer supported");
 
-        blob->setType(type);
-        if (type == TYPE_KEY_PAIR) {
-            importBlobAsKey(blob, filename, userId);
-        }
-        version = 1;
-        updated = true;
+        return false;
     }
 
     /* From V1 -> V2: All old keys were encrypted */
@@ -690,7 +405,6 @@
      * and write it.
      */
     if (updated) {
-        ALOGV("updated and writing file %s", filename);
         blob->setVersion(version);
     }
 
@@ -702,43 +416,6 @@
 };
 typedef std::unique_ptr<BIO, BIO_Delete> Unique_BIO;
 
-ResponseCode KeyStore::importBlobAsKey(Blob* blob, const char* filename, uid_t userId) {
-    // We won't even write to the blob directly with this BIO, so const_cast is okay.
-    Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
-    if (b.get() == nullptr) {
-        ALOGE("Problem instantiating BIO");
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), nullptr, nullptr, nullptr));
-    if (pkey.get() == nullptr) {
-        ALOGE("Couldn't read old PEM file");
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get()));
-    int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), nullptr);
-    if (len < 0) {
-        ALOGE("Couldn't measure PKCS#8 length");
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    std::unique_ptr<unsigned char[]> pkcs8key(new unsigned char[len]);
-    uint8_t* tmp = pkcs8key.get();
-    if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
-        ALOGE("Couldn't convert to PKCS#8");
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    ResponseCode rc = importKey(pkcs8key.get(), len, filename, userId,
-                                blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
-    if (rc != ResponseCode::NO_ERROR) {
-        return rc;
-    }
-
-    return get(filename, blob, TYPE_KEY_PAIR, userId);
-}
-
 void KeyStore::readMetaData() {
     int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
     if (in < 0) {
@@ -772,14 +449,14 @@
     bool upgraded = false;
 
     if (mMetaData.version == 0) {
-        UserState* userState = getUserStateByUid(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()) < 0) {
+            if (rename(kOldMasterKey, userState->getMasterKeyFileName().c_str()) < 0) {
                 ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
                 return false;
             }
@@ -814,13 +491,13 @@
             if (end[0] != '_' || end[1] == 0) {
                 continue;
             }
-            UserState* otherUser = getUserStateByUid(thisUid);
+            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());
+            DIR* otherdir = opendir(otherUser->getUserDirName().c_str());
             if (otherdir == nullptr) {
                 ALOGW("couldn't open user directory for rename");
                 continue;
@@ -839,16 +516,11 @@
     return upgraded;
 }
 
-static void maybeLogKeyIntegrityViolation(const char* filename, const BlobType type) {
-    if (!__android_log_security() || (type != TYPE_KEY_PAIR && type != TYPE_KEYMASTER_10)) return;
-
-    auto uidAlias = filename2UidAlias(filename);
-    uid_t uid = -1;
-    std::string alias;
-
-    if (uidAlias.isOk()) std::tie(uid, alias) = std::move(uidAlias).value();
-
-    log_key_integrity_violation(alias.c_str(), uid);
+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
index 23476d2..d2049a4 100644
--- a/keystore/KeyStore.h
+++ b/keystore/KeyStore.h
@@ -23,41 +23,67 @@
 
 #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;
 
-class KeymasterDevices : public std::array<sp<Keymaster>, 3> {
+template <typename T, size_t count> class Devices : public std::array<T, count> {
   public:
-    sp<Keymaster>& operator[](SecurityLevel secLevel);
-    sp<Keymaster> operator[](SecurityLevel secLevel) const;
+    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];
+    }
 };
 
-class KeyStore {
+}  // namespace keystore
+
+namespace std {
+template <typename T, size_t count> class tuple_size<keystore::Devices<T, count>> {
+  public:
+    static constexpr size_t value = std::tuple_size<std::array<T, count>>::value;
+};
+}  // namespace std
+
+namespace keystore {
+
+using KeymasterWorkers = Devices<std::shared_ptr<KeymasterWorker>, 3>;
+using KeymasterDevices = Devices<sp<Keymaster>, 3>;
+
+class KeyStore : public ::android::IBinder::DeathRecipient {
   public:
     KeyStore(Entropy* entropy, const KeymasterDevices& kmDevices,
              SecurityLevel minimalAllowedSecurityLevelForNewKeys);
     ~KeyStore();
 
-    sp<Keymaster> getDevice(SecurityLevel securityLevel) const { return mKmDevices[securityLevel]; }
-
-    std::pair<sp<Keymaster>, SecurityLevel> getMostSecureDevice() const {
-        SecurityLevel level = SecurityLevel::STRONGBOX;
-        do {
-            if (mKmDevices[level].get()) {
-                return {mKmDevices[level], level};
-            }
-            level = static_cast<SecurityLevel>(static_cast<uint32_t>(level) - 1);
-        } while (level != SecurityLevel::SOFTWARE);
-        return {nullptr, SecurityLevel::SOFTWARE};
+    std::shared_ptr<KeymasterWorker> getDevice(SecurityLevel securityLevel) const {
+        return mKmDevices[securityLevel];
     }
 
-    sp<Keymaster> getFallbackDevice() const {
+    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) {
@@ -67,11 +93,13 @@
         }
     }
 
-    sp<Keymaster> getDevice(const Blob& blob) { return mKmDevices[blob.getSecurityLevel()]; }
+    std::shared_ptr<KeymasterWorker> getDevice(const Blob& blob) {
+        return mKmDevices[blob.getSecurityLevel()];
+    }
 
     ResponseCode initialize();
 
-    State getState(uid_t userId) { return getUserState(userId)->getState(); }
+    State getState(uid_t userId) { return mUserStateDB.getUserState(userId)->getState(); }
 
     ResponseCode initializeUser(const android::String8& pw, uid_t userId);
 
@@ -79,14 +107,9 @@
     ResponseCode writeMasterKey(const android::String8& pw, uid_t userId);
     ResponseCode readMasterKey(const android::String8& pw, uid_t userId);
 
-    android::String8 getKeyName(const android::String8& keyName, const BlobType type);
-    android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid,
-                                      const BlobType type);
-    android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid,
-                                             const BlobType type);
-    NullOr<android::String8> getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
-                                                     const BlobType type);
-
+    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
@@ -97,43 +120,28 @@
 
     void lock(uid_t userId);
 
-    ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t userId);
-    ResponseCode put(const char* filename, Blob* keyBlob, uid_t userId);
-    ResponseCode del(const char* filename, const BlobType type, uid_t userId);
-    ResponseCode list(const android::String8& prefix, android::Vector<android::String16>* matches,
-                      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 char* alias, uid_t granterUid, uid_t granteeUid);
-    bool removeGrant(const char* alias, const uid_t granterUid, const uid_t granteeUid);
+    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 char* filename, uid_t userId,
-                           int32_t flags);
+    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;
 
-    ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid,
-                               const BlobType type);
+    std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry>
+    getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type);
 
-    /**
-     * Returns any existing UserState or creates it if it doesn't exist.
-     */
-    UserState* getUserState(uid_t userId);
+    void binderDied(const ::android::wp<IBinder>& who) override;
 
-    /**
-     * Returns any existing UserState or creates it if it doesn't exist.
-     */
-    UserState* getUserStateByUid(uid_t uid);
-
-    /**
-     * Returns NULL if the UserState doesn't already exist.
-     */
-    const UserState* getUserState(uid_t userId) const;
-
-    /**
-     * Returns NULL if the UserState doesn't already exist.
-     */
-    const UserState* getUserStateByUid(uid_t uid) const;
+    UserStateDB& getUserStateDB() { return mUserStateDB; }
+    AuthTokenTable& getAuthTokenTable() { return mAuthTokenTable; }
+    KeystoreKeymasterEnforcement& getEnforcementPolicy() { return mEnforcementPolicy; }
+    ConfirmationManager& getConfirmationManager() { return *mConfirmationManager; }
 
   private:
     static const char* kOldMasterKey;
@@ -142,10 +150,14 @@
     static const android::String16 kEcKeyType;
     Entropy* mEntropy;
 
-    KeymasterDevices mKmDevices;
+    KeymasterWorkers mKmDevices;
+
     bool mAllowNewFallback;
 
-    android::Vector<UserState*> mMasterKeys;
+    UserStateDB mUserStateDB;
+    AuthTokenTable mAuthTokenTable;
+    KeystoreKeymasterEnforcement mEnforcementPolicy;
+    sp<ConfirmationManager> mConfirmationManager;
 
     ::keystore::GrantStore mGrants;
 
@@ -156,15 +168,7 @@
     /**
      * Upgrade the key from the current version to whatever is newest.
      */
-    bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion,
-                     const BlobType type, uid_t uid);
-
-    /**
-     * Takes a blob that is an PEM-encoded RSA key as a byte array and converts it to a DER-encoded
-     * PKCS#8 for import into a keymaster.  Then it overwrites the original blob with the new blob
-     * format that is returned from the keymaster.
-     */
-    ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid);
+    bool upgradeBlob(Blob* blob, const uint8_t oldVersion);
 
     void readMetaData();
     void writeMetaData();
diff --git a/keystore/KeymasterArguments.cpp b/keystore/KeymasterArguments.cpp
index 829156c..60b86cc 100644
--- a/keystore/KeymasterArguments.cpp
+++ b/keystore/KeymasterArguments.cpp
@@ -34,6 +34,9 @@
     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) {}
 
diff --git a/keystore/OperationResult.cpp b/keystore/OperationResult.cpp
index 53c8d62..f4d2cc6 100644
--- a/keystore/OperationResult.cpp
+++ b/keystore/OperationResult.cpp
@@ -55,6 +55,12 @@
     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
index 63282e6..6bffa7c 100644
--- a/keystore/auth_token_table.cpp
+++ b/keystore/auth_token_table.cpp
@@ -84,6 +84,7 @@
           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");
@@ -110,10 +111,13 @@
     return is_secret_key_operation(algorithm, purpose) && key_info.find(Tag::AUTH_TIMEOUT) == -1;
 }
 
-AuthTokenTable::Error AuthTokenTable::FindAuthorization(const AuthorizationSet& key_info,
-                                                        KeyPurpose purpose, uint64_t op_handle,
-                                                        const HardwareAuthToken** found) {
-    if (!KeyRequiresAuthentication(key_info, purpose)) return AUTH_NOT_REQUIRED;
+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);
@@ -122,55 +126,51 @@
     ExtractSids(key_info, &key_sids);
 
     if (KeyRequiresAuthPerOperation(key_info, purpose))
-        return FindAuthPerOpAuthorization(key_sids, auth_type, op_handle, found);
+        return FindAuthPerOpAuthorization(key_sids, auth_type, op_handle);
     else
-        return FindTimedAuthorization(key_sids, auth_type, key_info, found);
+        return FindTimedAuthorization(key_sids, auth_type, key_info);
 }
 
-AuthTokenTable::Error
-AuthTokenTable::FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
-                                           HardwareAuthenticatorType auth_type, uint64_t op_handle,
-                                           const HardwareAuthToken** found) {
-    if (op_handle == 0) return OP_HANDLE_REQUIRED;
+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 == entries_.end()) return {AUTH_TOKEN_NOT_FOUND, {}};
 
-    if (!matching_op->SatisfiesAuth(sids, auth_type)) return AUTH_TOKEN_WRONG_SID;
+    if (!matching_op->SatisfiesAuth(sids, auth_type)) return {AUTH_TOKEN_WRONG_SID, {}};
 
-    *found = &matching_op->token();
-    return OK;
+    return {OK, matching_op->token()};
 }
 
-AuthTokenTable::Error AuthTokenTable::FindTimedAuthorization(const std::vector<uint64_t>& sids,
-                                                             HardwareAuthenticatorType auth_type,
-                                                             const AuthorizationSet& key_info,
-                                                             const HardwareAuthToken** found) {
+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;
+    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;
+        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;
+            return {AUTH_TOKEN_EXPIRED, {}};
         }
     }
 
     newest_match->UpdateLastUse(now);
-    *found = &newest_match->token();
-    return OK;
+    return {OK, newest_match->token()};
 }
 
 void AuthTokenTable::ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids) {
@@ -190,15 +190,24 @@
 }
 
 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;
 
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index 4110370..7b48a6c 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -15,6 +15,7 @@
  */
 
 #include <memory>
+#include <mutex>
 #include <vector>
 
 #include <keystore/keymaster_types.h>
@@ -72,8 +73,8 @@
      *
      * The table retains ownership of the returned object.
      */
-    Error FindAuthorization(const AuthorizationSet& key_info, KeyPurpose purpose,
-                            uint64_t op_handle, const HardwareAuthToken** found);
+    std::tuple<Error, HardwareAuthToken> FindAuthorization(const AuthorizationSet& key_info,
+                                                           KeyPurpose purpose, uint64_t op_handle);
 
     /**
      * Mark operation completed.  This allows tokens associated with the specified operation to be
@@ -89,7 +90,13 @@
 
     void Clear();
 
-    size_t size() { return entries_.size(); }
+    /**
+     * 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;
@@ -142,16 +149,21 @@
         bool operation_completed_;
     };
 
-    Error FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
-                                     HardwareAuthenticatorType auth_type, uint64_t op_handle,
-                                     const HardwareAuthToken** found);
-    Error FindTimedAuthorization(const std::vector<uint64_t>& sids,
-                                 HardwareAuthenticatorType auth_type,
-                                 const AuthorizationSet& key_info, const HardwareAuthToken** found);
+    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_;
diff --git a/keystore/authorization_set.cpp b/keystore/authorization_set.cpp
deleted file mode 100644
index 537fe3d..0000000
--- a/keystore/authorization_set.cpp
+++ /dev/null
@@ -1,427 +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.
- */
-
-#include <keystore/keymaster_types.h>
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits>
-#include <ostream>
-#include <istream>
-
-#include <new>
-
-namespace keystore {
-
-inline bool keyParamLess(const KeyParameter& a, const KeyParameter& b) {
-    if (a.tag != b.tag) return a.tag < b.tag;
-    int retval;
-    switch (typeFromTag(a.tag)) {
-    case TagType::INVALID:
-    case TagType::BOOL:
-        return false;
-    case TagType::ENUM:
-    case TagType::ENUM_REP:
-    case TagType::UINT:
-    case TagType::UINT_REP:
-        return a.f.integer < b.f.integer;
-    case TagType::ULONG:
-    case TagType::ULONG_REP:
-        return a.f.longInteger < b.f.longInteger;
-    case TagType::DATE:
-        return a.f.dateTime < b.f.dateTime;
-    case TagType::BIGNUM:
-    case TagType::BYTES:
-        // Handle the empty cases.
-        if (a.blob.size() == 0)
-            return b.blob.size() != 0;
-        if (b.blob.size() == 0) return false;
-
-        retval = memcmp(&a.blob[0], &b.blob[0], std::min(a.blob.size(), b.blob.size()));
-        // if one is the prefix of the other the longer wins
-        if (retval == 0) return a.blob.size() < b.blob.size();
-        // Otherwise a is less if a is less.
-        else return retval < 0;
-    }
-    return false;
-}
-
-inline bool keyParamEqual(const KeyParameter& a, const KeyParameter& b) {
-    if (a.tag != b.tag) return false;
-
-    switch (typeFromTag(a.tag)) {
-    case TagType::INVALID:
-    case TagType::BOOL:
-        return true;
-    case TagType::ENUM:
-    case TagType::ENUM_REP:
-    case TagType::UINT:
-    case TagType::UINT_REP:
-        return a.f.integer == b.f.integer;
-    case TagType::ULONG:
-    case TagType::ULONG_REP:
-        return a.f.longInteger == b.f.longInteger;
-    case TagType::DATE:
-        return a.f.dateTime == b.f.dateTime;
-    case TagType::BIGNUM:
-    case TagType::BYTES:
-        if (a.blob.size() != b.blob.size()) return false;
-        return a.blob.size() == 0 ||
-                memcmp(&a.blob[0], &b.blob[0], a.blob.size()) == 0;
-    }
-    return false;
-}
-
-void AuthorizationSet::Sort() {
-    std::sort(data_.begin(), data_.end(), keyParamLess);
-}
-
-void AuthorizationSet::Deduplicate() {
-    if (data_.empty()) return;
-
-    Sort();
-    std::vector<KeyParameter> result;
-
-    auto curr = data_.begin();
-    auto prev = curr++;
-    for (; curr != data_.end(); ++prev, ++curr) {
-        if (prev->tag == Tag::INVALID) continue;
-
-        if (!keyParamEqual(*prev, *curr)) {
-            result.emplace_back(std::move(*prev));
-        }
-    }
-    result.emplace_back(std::move(*prev));
-
-    std::swap(data_, result);
-}
-
-void AuthorizationSet::Union(const AuthorizationSet& other) {
-    data_.insert(data_.end(), other.data_.begin(), other.data_.end());
-    Deduplicate();
-}
-
-void AuthorizationSet::Subtract(const AuthorizationSet& other) {
-    Deduplicate();
-
-    auto i = other.begin();
-    while (i != other.end()) {
-        int pos = -1;
-        do {
-            pos = find(i->tag, pos);
-            if (pos != -1 && keyParamEqual(*i, data_[pos])) {
-                data_.erase(data_.begin() + pos);
-                break;
-            }
-        } while (pos != -1);
-        ++i;
-    }
-}
-
-int AuthorizationSet::find(Tag tag, int begin) const {
-    auto iter = data_.begin() + (1 + begin);
-
-    while (iter != data_.end() && iter->tag != tag) ++iter;
-
-    if (iter != data_.end()) return iter - data_.begin();
-    return -1;
-}
-
-bool AuthorizationSet::erase(int index) {
-    auto pos = data_.begin() + index;
-    if (pos != data_.end()) {
-        data_.erase(pos);
-        return true;
-    }
-    return false;
-}
-
-KeyParameter& AuthorizationSet::operator[](int at) {
-    return data_[at];
-}
-
-const KeyParameter& AuthorizationSet::operator[](int at) const {
-    return data_[at];
-}
-
-void AuthorizationSet::Clear() {
-    data_.clear();
-}
-
-size_t AuthorizationSet::GetTagCount(Tag tag) const {
-    size_t count = 0;
-    for (int pos = -1; (pos = find(tag, pos)) != -1;)
-        ++count;
-    return count;
-}
-
-NullOr<const KeyParameter&> AuthorizationSet::GetEntry(Tag tag) const {
-    int pos = find(tag);
-    if (pos == -1) return {};
-    return data_[pos];
-}
-
-/**
- * Persistent format is:
- * | 32 bit indirect_size         |
- * --------------------------------
- * | indirect_size bytes of data  | this is where the blob data is stored
- * --------------------------------
- * | 32 bit element_count         | number of entries
- * | 32 bit elements_size         | total bytes used by entries (entries have variable length)
- * --------------------------------
- * | elementes_size bytes of data | where the elements are stored
- */
-
-/**
- * Persistent format of blobs and bignums:
- * | 32 bit tag             |
- * | 32 bit blob_length     |
- * | 32 bit indirect_offset |
- */
-
-struct OutStreams {
-    std::ostream& indirect;
-    std::ostream& elements;
-};
-
-OutStreams& serializeParamValue(OutStreams& out, const hidl_vec<uint8_t>& blob) {
-    uint32_t buffer;
-
-    // write blob_length
-    auto blob_length = blob.size();
-    if (blob_length > std::numeric_limits<uint32_t>::max()) {
-        out.elements.setstate(std::ios_base::badbit);
-        return out;
-    }
-    buffer = blob_length;
-    out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
-
-    // write indirect_offset
-    auto offset = out.indirect.tellp();
-    if (offset < 0 || offset > std::numeric_limits<uint32_t>::max() ||
-            uint32_t(offset) + uint32_t(blob_length) < uint32_t(offset)) { // overflow check
-        out.elements.setstate(std::ios_base::badbit);
-        return out;
-    }
-    buffer = offset;
-    out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
-
-    // write blob to indirect stream
-    if(blob_length)
-        out.indirect.write(reinterpret_cast<const char*>(&blob[0]), blob_length);
-
-    return out;
-}
-
-template <typename T>
-OutStreams& serializeParamValue(OutStreams& out, const T& value) {
-    out.elements.write(reinterpret_cast<const char*>(&value), sizeof(T));
-    return out;
-}
-
-OutStreams& serialize(TAG_INVALID_t&&, OutStreams& out, const KeyParameter&) {
-    // skip invalid entries.
-    return out;
-}
-template <typename T>
-OutStreams& serialize(T ttag, OutStreams& out, const KeyParameter& param) {
-    out.elements.write(reinterpret_cast<const char*>(&param.tag), sizeof(int32_t));
-    return serializeParamValue(out, accessTagValue(ttag, param));
-}
-
-template <typename... T>
-struct choose_serializer;
-template <typename... Tags>
-struct choose_serializer<MetaList<Tags...>> {
-    static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
-        return choose_serializer<Tags...>::serialize(out, param);
-    }
-};
-template <>
-struct choose_serializer<> {
-    static OutStreams& serialize(OutStreams& out, const KeyParameter&) {
-        return out;
-    }
-};
-template <TagType tag_type, Tag tag, typename... Tail>
-struct choose_serializer<TypedTag<tag_type, tag>, Tail...> {
-    static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
-        if (param.tag == tag) {
-            return keystore::serialize(TypedTag<tag_type, tag>(), out, param);
-        } else {
-            return choose_serializer<Tail...>::serialize(out, param);
-        }
-    }
-};
-
-OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
-    return choose_serializer<all_tags_t>::serialize(out, param);
-}
-
-std::ostream& serialize(std::ostream& out, const std::vector<KeyParameter>& params) {
-    std::stringstream indirect;
-    std::stringstream elements;
-    OutStreams streams = { indirect, elements };
-    for (const auto& param: params) {
-        serialize(streams, param);
-    }
-    if (indirect.bad() || elements.bad()) {
-        out.setstate(std::ios_base::badbit);
-        return out;
-    }
-    auto pos = indirect.tellp();
-    if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
-        out.setstate(std::ios_base::badbit);
-        return out;
-    }
-    uint32_t indirect_size = pos;
-    pos = elements.tellp();
-    if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
-        out.setstate(std::ios_base::badbit);
-        return out;
-    }
-    uint32_t elements_size = pos;
-    uint32_t element_count = params.size();
-
-    out.write(reinterpret_cast<const char*>(&indirect_size), sizeof(uint32_t));
-
-    pos = out.tellp();
-    if (indirect_size)
-        out << indirect.rdbuf();
-    assert(out.tellp() - pos == indirect_size);
-
-    out.write(reinterpret_cast<const char*>(&element_count), sizeof(uint32_t));
-    out.write(reinterpret_cast<const char*>(&elements_size), sizeof(uint32_t));
-
-    pos = out.tellp();
-    if (elements_size)
-        out << elements.rdbuf();
-    assert(out.tellp() - pos == elements_size);
-
-    return out;
-}
-
-struct InStreams {
-    std::istream& indirect;
-    std::istream& elements;
-};
-
-InStreams& deserializeParamValue(InStreams& in, hidl_vec<uint8_t>* blob) {
-    uint32_t blob_length = 0;
-    uint32_t offset = 0;
-    in.elements.read(reinterpret_cast<char*>(&blob_length), sizeof(uint32_t));
-    blob->resize(blob_length);
-    in.elements.read(reinterpret_cast<char*>(&offset), sizeof(uint32_t));
-    in.indirect.seekg(offset);
-    in.indirect.read(reinterpret_cast<char*>(&(*blob)[0]), blob->size());
-    return in;
-}
-
-template <typename T>
-InStreams& deserializeParamValue(InStreams& in, T* value) {
-    in.elements.read(reinterpret_cast<char*>(value), sizeof(T));
-    return in;
-}
-
-InStreams& deserialize(TAG_INVALID_t&&, InStreams& in, KeyParameter*) {
-    // there should be no invalid KeyParamaters but if handle them as zero sized.
-    return in;
-}
-
-template <typename T>
-InStreams& deserialize(T&& ttag, InStreams& in, KeyParameter* param) {
-    return deserializeParamValue(in, &accessTagValue(ttag, *param));
-}
-
-template <typename... T>
-struct choose_deserializer;
-template <typename... Tags>
-struct choose_deserializer<MetaList<Tags...>> {
-    static InStreams& deserialize(InStreams& in, KeyParameter* param) {
-        return choose_deserializer<Tags...>::deserialize(in, param);
-    }
-};
-template <>
-struct choose_deserializer<> {
-    static InStreams& deserialize(InStreams& in, KeyParameter*) {
-        // encountered an unknown tag -> fail parsing
-        in.elements.setstate(std::ios_base::badbit);
-        return in;
-    }
-};
-template <TagType tag_type, Tag tag, typename... Tail>
-struct choose_deserializer<TypedTag<tag_type, tag>, Tail...> {
-    static InStreams& deserialize(InStreams& in, KeyParameter* param) {
-        if (param->tag == tag) {
-            return keystore::deserialize(TypedTag<tag_type, tag>(), in, param);
-        } else {
-            return choose_deserializer<Tail...>::deserialize(in, param);
-        }
-    }
-};
-
-InStreams& deserialize(InStreams& in, KeyParameter* param) {
-    in.elements.read(reinterpret_cast<char*>(&param->tag), sizeof(Tag));
-    return choose_deserializer<all_tags_t>::deserialize(in, param);
-}
-
-std::istream& deserialize(std::istream& in, std::vector<KeyParameter>* params) {
-    uint32_t indirect_size = 0;
-    in.read(reinterpret_cast<char*>(&indirect_size), sizeof(uint32_t));
-    std::string indirect_buffer(indirect_size, '\0');
-    if (indirect_buffer.size() != indirect_size) {
-        in.setstate(std::ios_base::badbit);
-        return in;
-    }
-    in.read(&indirect_buffer[0], indirect_buffer.size());
-
-    uint32_t element_count = 0;
-    in.read(reinterpret_cast<char*>(&element_count), sizeof(uint32_t));
-    uint32_t elements_size = 0;
-    in.read(reinterpret_cast<char*>(&elements_size), sizeof(uint32_t));
-
-    std::string elements_buffer(elements_size, '\0');
-    if(elements_buffer.size() != elements_size) {
-        in.setstate(std::ios_base::badbit);
-        return in;
-    }
-    in.read(&elements_buffer[0], elements_buffer.size());
-
-    if (in.bad()) return in;
-
-    // TODO write one-shot stream buffer to avoid copying here
-    std::stringstream indirect(indirect_buffer);
-    std::stringstream elements(elements_buffer);
-    InStreams streams = { indirect, elements };
-
-    params->resize(element_count);
-
-    for (uint32_t i = 0; i < element_count; ++i) {
-        deserialize(streams, &(*params)[i]);
-    }
-    return in;
-}
-void AuthorizationSet::Serialize(std::ostream* out) const {
-    serialize(*out, data_);
-}
-void AuthorizationSet::Deserialize(std::istream* in) {
-    deserialize(*in, &data_);
-}
-
-}  // namespace keystore
diff --git a/keystore/binder/android/security/IKeystoreService.aidl b/keystore/binder/android/security/IKeystoreService.aidl
index db55062..c490eda 100644
--- a/keystore/binder/android/security/IKeystoreService.aidl
+++ b/keystore/binder/android/security/IKeystoreService.aidl
@@ -42,12 +42,6 @@
     int lock(int userId);
     int unlock(int userId, String userPassword);
     int isEmpty(int userId);
-    int generate(String name, int uid, int keyType, int keySize, int flags,
-        in KeystoreArguments args);
-    int import_key(String name, in byte[] data, int uid, int flags);
-    byte[] sign(String name, in byte[] data);
-    int verify(String name, in byte[] data, in byte[] signature);
-    byte[] get_pubkey(String name);
     String grant(String name, int granteeUid);
     int ungrant(String name, int granteeUid);
     long getmtime(String name, int uid);
@@ -70,7 +64,6 @@
     OperationResult finish(IBinder token, in KeymasterArguments params, in byte[] signature,
         in byte[] entropy);
     int abort(IBinder handle);
-    boolean isOperationAuthorized(IBinder token);
     int addAuthToken(in byte[] authToken);
     int onUserAdded(int userId, int parentId);
     int onUserRemoved(int userId);
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index b901553..f08e08d 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -28,6 +28,15 @@
 
 #include "keystore_utils.h"
 
+#include <openssl/evp.h>
+
+#include <istream>
+#include <ostream>
+#include <streambuf>
+#include <string>
+
+#include <android-base/logging.h>
+
 namespace {
 
 constexpr size_t kGcmIvSizeBytes = 96 / 8;
@@ -128,11 +137,60 @@
     return ResponseCode::NO_ERROR;
 }
 
+class ArrayStreamBuffer : public std::streambuf {
+  public:
+    template <typename T, size_t size> 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) {
-    memset(&mBlob, 0, sizeof(mBlob));
+    mBlob = std::make_unique<blobv3>();
+    memset(mBlob.get(), 0, sizeof(blobv3));
     if (valueLength > kValueSize) {
         valueLength = kValueSize;
         ALOGW("Provided blob length too large");
@@ -141,44 +199,76 @@
         infoLength = kValueSize - valueLength;
         ALOGW("Provided info length too large");
     }
-    mBlob.length = valueLength;
-    memcpy(mBlob.value, value, valueLength);
+    mBlob->length = valueLength;
+    memcpy(mBlob->value, value, valueLength);
 
-    mBlob.info = infoLength;
-    memcpy(mBlob.value + valueLength, info, infoLength);
+    mBlob->info = infoLength;
+    memcpy(mBlob->value + valueLength, info, infoLength);
 
-    mBlob.version = CURRENT_BLOB_VERSION;
-    mBlob.type = uint8_t(type);
+    mBlob->version = CURRENT_BLOB_VERSION;
+    mBlob->type = uint8_t(type);
 
     if (type == TYPE_MASTER_KEY) {
-        mBlob.flags = KEYSTORE_FLAG_ENCRYPTED;
+        mBlob->flags = KEYSTORE_FLAG_ENCRYPTED;
     } else {
-        mBlob.flags = KEYSTORE_FLAG_NONE;
+        mBlob->flags = KEYSTORE_FLAG_NONE;
     }
 }
 
 Blob::Blob(blobv3 b) {
-    mBlob = b;
+    mBlob = std::make_unique<blobv3>(b);
 }
 
 Blob::Blob() {
-    memset(&mBlob, 0, sizeof(mBlob));
+    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) {
+    if (mBlob->version < 2) {
         return true;
     }
 
-    return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED;
+    return mBlob->flags & KEYSTORE_FLAG_ENCRYPTED;
 }
 
 bool Blob::isSuperEncrypted() const {
-    return mBlob.flags & KEYSTORE_FLAG_SUPER_ENCRYPTED;
+    return mBlob->flags & KEYSTORE_FLAG_SUPER_ENCRYPTED;
 }
 
 bool Blob::isCriticalToDeviceEncryption() const {
-    return mBlob.flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
+    return mBlob->flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
 }
 
 inline uint8_t setFlag(uint8_t flags, bool set, KeyStoreFlag flag) {
@@ -186,83 +276,106 @@
 }
 
 void Blob::setEncrypted(bool encrypted) {
-    mBlob.flags = setFlag(mBlob.flags, encrypted, KEYSTORE_FLAG_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);
+    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);
+    mBlob->flags = setFlag(mBlob->flags, critical, KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
 }
 
 void Blob::setFallback(bool fallback) {
     if (fallback) {
-        mBlob.flags |= KEYSTORE_FLAG_FALLBACK;
+        mBlob->flags |= KEYSTORE_FLAG_FALLBACK;
     } else {
-        mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK;
+        mBlob->flags &= ~KEYSTORE_FLAG_FALLBACK;
     }
 }
 
-ResponseCode Blob::writeBlob(const std::string& filename, const uint8_t* aes_key, State state,
-                             Entropy* entropy) {
+static ResponseCode writeBlob(const std::string& filename, Blob blob, blobv3* rawBlob,
+                              const uint8_t* aes_key, State state, Entropy* entropy) {
     ALOGV("writing blob %s", filename.c_str());
 
-    const size_t dataLength = mBlob.length;
-    mBlob.length = htonl(mBlob.length);
+    const size_t dataLength = rawBlob->length;
+    rawBlob->length = htonl(rawBlob->length);
 
-    if (isEncrypted() || isSuperEncrypted()) {
+    if (blob.isEncrypted() || blob.isSuperEncrypted()) {
         if (state != STATE_NO_ERROR) {
             ALOGD("couldn't insert encrypted blob while not unlocked");
             return ResponseCode::LOCKED;
         }
 
-        memset(mBlob.initialization_vector, 0, AES_BLOCK_SIZE);
-        if (!entropy->generate_random_data(mBlob.initialization_vector, kGcmIvSizeBytes)) {
+        memset(rawBlob->initialization_vector, 0, AES_BLOCK_SIZE);
+        if (!entropy->generate_random_data(rawBlob->initialization_vector, kGcmIvSizeBytes)) {
             ALOGW("Could not read random data for: %s", filename.c_str());
             return ResponseCode::SYSTEM_ERROR;
         }
 
-        auto rc = AES_gcm_encrypt(mBlob.value /* in */, mBlob.value /* out */, dataLength, aes_key,
-                                  mBlob.initialization_vector, mBlob.aead_tag);
+        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 + mBlob.info;
+    size_t fileLength = offsetof(blobv3, value) + dataLength + rawBlob->info;
 
-    char tmpFileName[] = ".tmpXXXXXX";
-    int out = TEMP_FAILURE_RETRY(mkstemp(tmpFileName));
+    int out =
+        TEMP_FAILURE_RETRY(open(filename.c_str(), O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
     if (out < 0) {
-        ALOGW("could not open temporary file: %s: %s", tmpFileName, strerror(errno));
+        ALOGW("could not open file: %s: %s", filename.c_str(), strerror(errno));
         return ResponseCode::SYSTEM_ERROR;
     }
 
-    const size_t writtenBytes = writeFully(out, (uint8_t*)&mBlob, fileLength);
+    const size_t writtenBytes = writeFully(out, reinterpret_cast<uint8_t*>(rawBlob), fileLength);
     if (close(out) != 0) {
         return ResponseCode::SYSTEM_ERROR;
     }
     if (writtenBytes != fileLength) {
         ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength);
-        unlink(tmpFileName);
-        return ResponseCode::SYSTEM_ERROR;
-    }
-    if (rename(tmpFileName, filename.c_str()) == -1) {
-        ALOGW("could not rename blob to %s: %s", filename.c_str(), strerror(errno));
+        unlink(filename.c_str());
         return ResponseCode::SYSTEM_ERROR;
     }
     return ResponseCode::NO_ERROR;
 }
 
+ResponseCode LockedKeyBlobEntry::writeBlobs(Blob keyBlob, Blob characteristicsBlob,
+                                            const uint8_t* aes_key, State state,
+                                            Entropy* entropy) 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,
+                       entropy);
+        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, entropy);
+    }
+    return rc;
+}
+
 ResponseCode Blob::readBlob(const std::string& filename, const 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*)&mBlob, sizeof(mBlob));
+    const size_t fileLength = readFully(in, (uint8_t*)rawBlob.get(), sizeof(blobv3));
     if (close(in) != 0) {
         return ResponseCode::SYSTEM_ERROR;
     }
@@ -271,67 +384,329 @@
         return ResponseCode::VALUE_CORRUPTED;
     }
 
-    if ((isEncrypted() || isSuperEncrypted())) {
-        if (state == STATE_LOCKED) return ResponseCode::LOCKED;
+    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)) return ResponseCode::VALUE_CORRUPTED;
 
-    if (mBlob.version == 3) {
-        const ssize_t encryptedLength = ntohl(mBlob.length);
+    if (rawBlob->version == 3) {
+        const ssize_t encryptedLength = ntohl(rawBlob->length);
 
-        if (isEncrypted() || isSuperEncrypted()) {
-            auto rc = AES_gcm_decrypt(mBlob.value /* in */, mBlob.value /* out */, encryptedLength,
-                                      aes_key, mBlob.initialization_vector, mBlob.aead_tag);
+        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) return rc;
         }
-    } else if (mBlob.version < 3) {
-        blobv2& blob = reinterpret_cast<blobv2&>(mBlob);
+    } else if (rawBlob->version < 3) {
+        blobv2& v2blob = reinterpret_cast<blobv2&>(*rawBlob);
         const size_t headerLength = offsetof(blobv2, encrypted);
-        const ssize_t encryptedLength = fileLength - headerLength - blob.info;
+        const ssize_t encryptedLength = fileLength - headerLength - v2blob.info;
         if (encryptedLength < 0) return ResponseCode::VALUE_CORRUPTED;
 
-        if (isEncrypted() || isSuperEncrypted()) {
+        if (rawBlobIsEncrypted(*rawBlob)) {
             if (encryptedLength % AES_BLOCK_SIZE != 0) {
                 return ResponseCode::VALUE_CORRUPTED;
             }
 
             AES_KEY key;
             AES_set_decrypt_key(aes_key, kAesKeySize * 8, &key);
-            AES_cbc_encrypt(blob.encrypted, blob.encrypted, encryptedLength, &key, blob.vector,
-                            AES_DECRYPT);
+            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(blob.digested, digestedLength, computedDigest);
-            if (memcmp(blob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
+            MD5(v2blob.digested, digestedLength, computedDigest);
+            if (memcmp(v2blob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
                 return ResponseCode::VALUE_CORRUPTED;
             }
         }
     }
 
-    const ssize_t maxValueLength = fileLength - offsetof(blobv3, value) - mBlob.info;
-    mBlob.length = ntohl(mBlob.length);
-    if (mBlob.length < 0 || mBlob.length > maxValueLength ||
-        mBlob.length + mBlob.info + AES_BLOCK_SIZE > static_cast<ssize_t>(sizeof(mBlob.value))) {
+    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))) {
         return ResponseCode::VALUE_CORRUPTED;
     }
 
-    if (mBlob.info != 0 && mBlob.version < 3) {
+    if (rawBlob->info != 0 && rawBlob->version < 3) {
         // move info from after padding to after data
-        memmove(mBlob.value + mBlob.length, mBlob.value + maxValueLength, mBlob.info);
+        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 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);
+    return keystore::flagsToSecurityLevel(mBlob->flags);
 }
 
 void Blob::setSecurityLevel(keystore::SecurityLevel secLevel) {
-    mBlob.flags &= ~(KEYSTORE_FLAG_FALLBACK | KEYSTORE_FLAG_STRONGBOX);
-    mBlob.flags |= keystore::securityLevelToFlags(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. */
+
+static std::string encodeKeyName(const std::string& keyName) {
+    std::string encodedName;
+    encodedName.reserve(keyName.size() * 2);
+    auto in = keyName.begin();
+    while (in != keyName.end()) {
+        if (*in < '0' || *in > '~') {
+            encodedName.append(1, '+' + (uint8_t(*in) >> 6));
+            encodedName.append(1, '0' + (*in & 0x3F));
+        } else {
+            encodedName.append(1, *in);
+        }
+        ++in;
+    }
+    return encodedName;
+}
+
+static 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) {
+            multichar = false;
+            decodedName.append(1, c | *in);
+        } else if (*in >= '+' && *in <= '.') {
+            multichar = true;
+            c = (*in - '+') << 6;
+        } else {
+            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 {
+    return !access(getKeyBlobPath().c_str(), R_OK | W_OK);
+}
+bool KeyBlobEntry::hasCharacteristicsBlob() const {
+    return !access(getCharacteristicsBlobPath().c_str(), R_OK | W_OK);
+}
+
+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
index 665e07a..5cd1b90 100644
--- a/keystore/blob.h
+++ b/keystore/blob.h
@@ -22,8 +22,14 @@
 #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>
 
 constexpr size_t kValueSize = 32768;
 constexpr size_t kAesKeySize = 128 / 8;
@@ -80,27 +86,45 @@
     TYPE_KEY_PAIR = 3,
     TYPE_KEYMASTER_10 = 4,
     TYPE_KEY_CHARACTERISTICS = 5,
+    TYPE_KEY_CHARACTERISTICS_CACHE = 6,
 } BlobType;
 
 class Entropy;
+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() { mBlob = {}; }
+    ~Blob() {
+        if (mBlob) *mBlob = {};
+    }
 
-    const uint8_t* getValue() const { return mBlob.value; }
+    Blob& operator=(const Blob& rhs);
+    Blob& operator=(Blob&& rhs);
+    operator bool() const { return bool(mBlob); }
 
-    int32_t getLength() const { return mBlob.length; }
+    const uint8_t* getValue() const { return mBlob->value; }
 
-    const uint8_t* getInfo() const { return mBlob.value + mBlob.length; }
-    uint8_t getInfoLength() const { return mBlob.info; }
+    int32_t getLength() const { return mBlob->length; }
 
-    uint8_t getVersion() const { return mBlob.version; }
+    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);
@@ -111,22 +135,141 @@
     bool isCriticalToDeviceEncryption() const;
     void setCriticalToDeviceEncryption(bool critical);
 
-    bool isFallback() const { return mBlob.flags & KEYSTORE_FLAG_FALLBACK; }
+    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); }
+    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);
 
-    ResponseCode writeBlob(const std::string& filename, const uint8_t* aes_key, State state,
-                           Entropy* entropy);
-    ResponseCode readBlob(const std::string& filename, const uint8_t* aes_key, State state);
+    std::tuple<bool, keystore::AuthorizationSet, keystore::AuthorizationSet>
+    getKeyCharacteristics() const;
+
+    bool putKeyCharacteristics(const keystore::AuthorizationSet& hwEnforced,
+                               const keystore::AuthorizationSet& swEnforced);
 
   private:
-    blobv3 mBlob;
+    std::unique_ptr<blobv3> mBlob;
+
+    ResponseCode readBlob(const std::string& filename, const 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(alias_, user_dir_, uid_) < std::tie(rhs.alias_, rhs.user_dir_, uid_);
+    }
+    bool operator==(const KeyBlobEntry& rhs) const {
+        return std::tie(alias_, user_dir_, uid_) == std::tie(rhs.alias_, rhs.user_dir_, uid_);
+    }
+    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_;
+    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 uint8_t* aes_key,
+                            State state, Entropy* entorpy) const;
+    std::tuple<ResponseCode, Blob, Blob> readBlobs(const uint8_t* aes_key, State state) const;
+    ResponseCode deleteBlobs() const;
+
+    inline operator bool() const { return entry_ != nullptr; }
+    inline const KeyBlobEntry& operator*() const { return *entry_; }
+    inline const KeyBlobEntry* operator->() const { return entry_; }
 };
 
 #endif  // KEYSTORE_BLOB_H_
diff --git a/keystore/confirmation_manager.cpp b/keystore/confirmation_manager.cpp
index 0dee4aa..3396359 100644
--- a/keystore/confirmation_manager.cpp
+++ b/keystore/confirmation_manager.cpp
@@ -184,7 +184,7 @@
     return Return<void>();
 }
 
-// Called by keystore main thread.
+// Called by keystore main thread or keymaster worker
 hidl_vec<uint8_t> ConfirmationManager::getLatestConfirmationToken() {
     lock_guard<mutex> lock(mMutex);
     return mLatestConfirmationToken;
diff --git a/keystore/grant_store.cpp b/keystore/grant_store.cpp
index 9244b7c..9e627ce 100644
--- a/keystore/grant_store.cpp
+++ b/keystore/grant_store.cpp
@@ -16,6 +16,7 @@
 
 #include "grant_store.h"
 
+#include "blob.h"
 #include <algorithm>
 #include <sstream>
 
@@ -25,10 +26,8 @@
 static const char* kKeystoreGrantInfix = "_KEYSTOREGRANT_";
 static constexpr size_t kKeystoreGrantInfixLength = 15;
 
-Grant::Grant(const std::string& alias, const std::string& owner_dir_name, const uid_t owner_uid,
-             const uint64_t grant_no)
-        : alias_(alias), owner_dir_name_(owner_dir_name), owner_uid_(owner_uid),
-          grant_no_(grant_no) {}
+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);
@@ -41,45 +40,45 @@
     return {grant_no, wrapped_alias};
 }
 
-std::string GrantStore::put(const uid_t uid, const std::string& alias,
-                            const std::string& owner_dir_name, const uid_t owner_uid) {
+std::string GrantStore::put(const uid_t uid, const LockedKeyBlobEntry& lockedEntry) {
+    std::unique_lock<std::shared_mutex> lock(mutex_);
     std::stringstream s;
-    s << alias << kKeystoreGrantInfix;
-    auto& uid_grant_list = grants_[uid];
+    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(),
-            [&](auto& entry) {
-                return success = entry.alias_ == alias && entry.owner_dir_name_ == owner_dir_name
-                        && entry.owner_uid_ == owner_uid;
-            });
+    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(alias, owner_dir_name, owner_uid,
-                                                             std::rand());
+        std::tie(iterator, success) = uid_grant_list.emplace(blobEntry, std::rand());
     }
     s << iterator->grant_no_;
     return s.str();
 }
 
-const Grant* GrantStore::get(const uid_t uid, const std::string& alias) const {
+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 nullptr;
+    if (grant_no == kInvalidGrantNo) return {};
     auto uid_set_iter = grants_.find(uid);
-    if (uid_set_iter == grants_.end()) return nullptr;
+    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 nullptr;
-    if (grant->alias_ != wrappedAlias) return nullptr;
-    return &(*grant);
+    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 uid_t granterUid,
-        const std::string& alias) {
+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->alias_ == alias && i->owner_uid_ == granterUid) {
+        if (i->entry_ == *lockedEntry) {
             uid_grant_list.erase(i);
             return true;
         }
@@ -88,9 +87,10 @@
 }
 
 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->alias_ == alias && i->owner_uid_ == granterUid) {
+            if (i->entry_.alias() == alias && i->entry_.uid() == granterUid) {
                 uid_grant_list.second.erase(i);
                 break;
             }
@@ -99,6 +99,7 @@
 }
 
 void GrantStore::removeAllGrantsToUid(const uid_t granteeUid) {
+    std::unique_lock<std::shared_mutex> lock(mutex_);
     grants_.erase(granteeUid);
 }
 
diff --git a/keystore/grant_store.h b/keystore/grant_store.h
index 6341c76..f8e4f91 100644
--- a/keystore/grant_store.h
+++ b/keystore/grant_store.h
@@ -17,12 +17,23 @@
 #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
@@ -32,16 +43,12 @@
  */
 class Grant {
 public:
-    Grant(const std::string& alias, const std::string& owner_dir_name, const uid_t owner_uid,
-          const uint64_t grant_no);
-    // the following three field are used to recover the key filename that the grant refers to
-    std::string alias_;            ///< original/wrapped key alias
-    std::string owner_dir_name_;   ///< key owner key directory
-    uid_t owner_uid_;              ///< key owner uid
+  Grant(const KeyBlobEntry& entry, const uint64_t grant_no);
+  KeyBlobEntry entry_;
 
-    uint64_t grant_no_;            ///< numeric grant identifier - randomly assigned
+  uint64_t grant_no_;  ///< numeric grant identifier - randomly assigned
 
-    operator const uint64_t&() const { return grant_no_; }
+  operator const uint64_t&() const { return grant_no_; }
 };
 
 /**
@@ -56,10 +63,9 @@
 class GrantStore {
 public:
     GrantStore() : grants_() {}
-    std::string put(const uid_t uid, const std::string& alias, const std::string& owner_dir_name,
-                    const uid_t owner_uid);
-    const Grant* get(const uid_t uid, const std::string& alias) const;
-    bool removeByFileAlias(const uid_t granteeUid, const uid_t granterUid, const std::string& alias);
+    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);
 
@@ -68,6 +74,7 @@
     GrantStore& operator=(const GrantStore&) = delete;
 private:
     std::unordered_map<uid_t, std::set<Grant, std::less<>>> grants_;
+    mutable std::shared_mutex mutex_;
 };
 
 }  // namespace keystore
diff --git a/keystore/include/keystore/KeyCharacteristics.h b/keystore/include/keystore/KeyCharacteristics.h
index 7fc89c6..33c5c3a 100644
--- a/keystore/include/keystore/KeyCharacteristics.h
+++ b/keystore/include/keystore/KeyCharacteristics.h
@@ -27,6 +27,10 @@
 // Parcelable version of keystore::KeyCharacteristics
 struct KeyCharacteristics : public ::android::Parcelable {
     KeyCharacteristics(){};
+    KeyCharacteristics(keystore::KeyCharacteristics&& other) {
+        softwareEnforced = std::move(other.softwareEnforced);
+        hardwareEnforced = std::move(other.hardwareEnforced);
+    }
     explicit KeyCharacteristics(const keystore::KeyCharacteristics& other) {
         softwareEnforced = KeymasterArguments(other.softwareEnforced);
         hardwareEnforced = KeymasterArguments(other.hardwareEnforced);
diff --git a/keystore/include/keystore/KeymasterArguments.h b/keystore/include/keystore/KeymasterArguments.h
index 99074f8..fb35ee7 100644
--- a/keystore/include/keystore/KeymasterArguments.h
+++ b/keystore/include/keystore/KeymasterArguments.h
@@ -26,6 +26,7 @@
 // struct for serializing/deserializing a list of KeyParameters
 struct KeymasterArguments : public Parcelable {
     KeymasterArguments(){};
+    KeymasterArguments(hardware::hidl_vec<keystore::KeyParameter>&& other);
     explicit KeymasterArguments(const hardware::hidl_vec<keystore::KeyParameter>& other);
 
     status_t readFromParcel(const Parcel* in) override;
diff --git a/keystore/include/keystore/OperationResult.h b/keystore/include/keystore/OperationResult.h
index 2ceda9a..caa7cdb 100644
--- a/keystore/include/keystore/OperationResult.h
+++ b/keystore/include/keystore/OperationResult.h
@@ -39,6 +39,8 @@
     ::keystore::hidl_vec<::keystore::KeyParameter> outParams;
 };
 
+OperationResult operationFailed(const ::keystore::KeyStoreServiceReturnCode& error);
+
 }  // namespace keymaster
 }  // namespace security
 }  // namespace android
diff --git a/keystore/include/keystore/keystore.h b/keystore/include/keystore/keystore.h
index 07f645f..a1d4c81 100644
--- a/keystore/include/keystore/keystore.h
+++ b/keystore/include/keystore/keystore.h
@@ -27,22 +27,23 @@
 };
 
 // must be in sync with KeyStore.java,
-enum class ResponseCode: int32_t {
-    NO_ERROR          =  STATE_NO_ERROR, // 1
-    LOCKED            =  STATE_LOCKED, // 2
-    UNINITIALIZED     =  STATE_UNINITIALIZED, // 3
-    SYSTEM_ERROR      =  4,
-    PROTOCOL_ERROR    =  5,
-    PERMISSION_DENIED =  6,
-    KEY_NOT_FOUND     =  7,
-    VALUE_CORRUPTED   =  8,
-    UNDEFINED_ACTION  =  9,
-    WRONG_PASSWORD_0  = 10,
-    WRONG_PASSWORD_1  = 11,
-    WRONG_PASSWORD_2  = 12,
-    WRONG_PASSWORD_3  = 13, // MAX_RETRY = 4
+enum class ResponseCode : int32_t {
+    NO_ERROR = STATE_NO_ERROR,            // 1
+    LOCKED = STATE_LOCKED,                // 2
+    UNINITIALIZED = STATE_UNINITIALIZED,  // 3
+    SYSTEM_ERROR = 4,
+    PROTOCOL_ERROR = 5,
+    PERMISSION_DENIED = 6,
+    KEY_NOT_FOUND = 7,
+    VALUE_CORRUPTED = 8,
+    UNDEFINED_ACTION = 9,
+    WRONG_PASSWORD_0 = 10,
+    WRONG_PASSWORD_1 = 11,
+    WRONG_PASSWORD_2 = 12,
+    WRONG_PASSWORD_3 = 13,  // MAX_RETRY = 4
     SIGNATURE_INVALID = 14,
-    OP_AUTH_NEEDED    = 15, // Auth is needed for this operation before it can be used.
+    OP_AUTH_NEEDED = 15,  // Auth is needed for this operation before it can be used.
+    KEY_ALREADY_EXISTS = 16,
 };
 
 /*
diff --git a/keystore/include/keystore/keystore_concurrency.h b/keystore/include/keystore/keystore_concurrency.h
new file mode 100644
index 0000000..b60b7a6
--- /dev/null
+++ b/keystore/include/keystore/keystore_concurrency.h
@@ -0,0 +1,113 @@
+/*
+**
+** 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_INCLUDE_KEYSTORE_KEYSTORE_CONCURRENCY_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_CONCURRENCY_H_
+
+#include <type_traits>
+
+namespace keystore {
+
+template <typename LockedType> class UnlockProxyLockHelper {
+  private:
+    std::function<void(LockedType*)> unlock_;
+    LockedType* value_;
+
+  public:
+    using lockedType = LockedType;
+    UnlockProxyLockHelper() : value_(nullptr) {}
+    UnlockProxyLockHelper(LockedType* value, std::function<void(LockedType*)>&& unlock)
+        : unlock_(std::move(unlock)), value_(value) {}
+    ~UnlockProxyLockHelper() {
+        if (unlock_) unlock_(value_);
+    }
+    UnlockProxyLockHelper(UnlockProxyLockHelper&& rhs)
+        : unlock_(std::move(rhs.unlock_)), value_(rhs.value_) {
+        rhs.value_ = nullptr;
+        rhs.unlock_ = {};
+    }
+    UnlockProxyLockHelper& operator=(UnlockProxyLockHelper&& rhs) {
+        if (this != &rhs) {
+            UnlockProxyLockHelper dummy(std::move(*this));
+            unlock_ = std::move(rhs.unlock_);
+            value_ = std::move(rhs.value_);
+            rhs.value_ = nullptr;
+            rhs.unlock_ = {};
+        }
+        return *this;
+    }
+    UnlockProxyLockHelper(const UnlockProxyLockHelper& rhs) = delete;
+    UnlockProxyLockHelper& operator=(const UnlockProxyLockHelper& rhs) = delete;
+
+    template <typename T = LockedType>
+    std::enable_if_t<!std::is_const<LockedType>::value, T*> value() {
+        return value_;
+    }
+    const LockedType* value() const { return value_; }
+};
+
+template <typename LockedType, typename MutexType, template <typename> class GuardType>
+class MutexProxyLockHelper {
+  private:
+    GuardType<MutexType> lock_;
+    LockedType* value_;
+
+  public:
+    using lockedType = LockedType;
+    MutexProxyLockHelper() : value_(nullptr) {}
+    MutexProxyLockHelper(LockedType* value, GuardType<MutexType>&& lock)
+        : lock_(std::move(lock)), value_(value) {}
+
+    template <typename T = LockedType>
+    std::enable_if_t<!std::is_const<LockedType>::value, T*> value() {
+        return value_;
+    }
+    const LockedType* value() const { return value_; }
+};
+
+template <typename Implementation> class ProxyLock {
+  private:
+    Implementation impl_;
+
+  public:
+    ProxyLock() : impl_() {}
+    template <typename... Args> ProxyLock(Args&&... args) : impl_{std::forward<Args>(args)...} {}
+    ProxyLock(Implementation&& impl) : impl_(std::move(impl)) {}
+    operator bool() const { return impl_.value() != nullptr; }
+
+    template <typename T = typename Implementation::lockedType>
+    std::enable_if_t<!std::is_const<typename Implementation::lockedType>::value, T*> operator->() {
+        return impl_.value();
+    }
+
+    template <typename T = typename Implementation::lockedType>
+    std::enable_if_t<!std::is_const<typename Implementation::lockedType>::value, T&> operator*() {
+        return *impl_.value();
+    }
+
+    const std::remove_const_t<typename Implementation::lockedType>* operator->() const {
+        return impl_.value();
+    }
+
+    const std::remove_const_t<typename Implementation::lockedType>& operator*() const {
+        return *impl_.value();
+    }
+};
+
+}  // namespace keystore
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_CONCURRENCY_H_
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 2aaa625..7ce58ca 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -23,6 +23,7 @@
 #include <sys/stat.h>
 
 #include <algorithm>
+#include <atomic>
 #include <sstream>
 
 #include <android-base/scopeguard.h>
@@ -36,6 +37,7 @@
 #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 "defaults.h"
@@ -44,6 +46,7 @@
 #include "keystore_keymaster_enforcement.h"
 #include "keystore_utils.h"
 #include <keystore/keystore_hidl_support.h>
+#include <keystore/keystore_return_types.h>
 
 #include <hardware/hw_auth_token.h>
 
@@ -59,10 +62,10 @@
 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;
 
-constexpr size_t kMaxOperations = 15;
 constexpr double kIdRotationPeriod = 30 * 24 * 60 * 60; /* Thirty days, in seconds */
 const char* kTimestampFilePath = "timestamp";
 const int ID_ATTESTATION_REQUEST_GENERIC_INFO = 1 << 0;
@@ -74,12 +77,9 @@
 typedef std::unique_ptr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
 
 bool containsTag(const hidl_vec<KeyParameter>& params, Tag tag) {
-    return params.end() != std::find_if(params.begin(), params.end(),
-                                        [&](auto& param) { return param.tag == tag; });
-}
-
-bool isAuthenticationBound(const hidl_vec<KeyParameter>& params) {
-    return !containsTag(params, Tag::NO_AUTH_REQUIRED);
+    return params.end() !=
+           std::find_if(params.begin(), params.end(),
+                        [&](const KeyParameter& param) { return param.tag == tag; });
 }
 
 std::pair<KeyStoreServiceReturnCode, bool> hadFactoryResetSinceIdRotation() {
@@ -143,15 +143,6 @@
 
 }  // anonymous namespace
 
-void KeyStoreService::binderDied(const wp<IBinder>& who) {
-    auto operations = mOperationMap.getOperationsForToken(who.unsafe_get());
-    for (const auto& token : operations) {
-        int32_t unused_result;
-        abort(token, &unused_result);
-    }
-    mConfirmationManager->binderDied(who);
-}
-
 Status KeyStoreService::getState(int32_t userId, int32_t* aidl_return) {
     if (!checkBinderPermission(P_GET_STATE)) {
         *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
@@ -170,10 +161,14 @@
     }
 
     String8 name8(name);
+    ResponseCode rc;
     Blob keyBlob;
-    KeyStoreServiceReturnCode rc =
-        mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_GENERIC);
-    if (!rc.isOk()) {
+    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.
@@ -196,13 +191,18 @@
     }
 
     String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_GENERIC));
+    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(filename.string(), &keyBlob, get_user_id(targetUid)));
+    *aidl_return = static_cast<int32_t>(mKeyStore->put(lockedEntry, keyBlob, {}));
     return Status::ok();
 }
 
@@ -214,26 +214,15 @@
     }
     String8 name8(name);
     ALOGI("del %s %d", name8.string(), targetUid);
-    auto filename = mKeyStore->getBlobFileNameIfExists(name8, targetUid, ::TYPE_ANY);
-    if (!filename.isOk()) {
+    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(filename.value().string(), ::TYPE_ANY, get_user_id(targetUid));
-    if (result != ResponseCode::NO_ERROR) {
-        *aidl_return = static_cast<int32_t>(result);
-        return Status::ok();
-    }
+    ResponseCode result = mKeyStore->del(lockedEntry);
 
-    filename = mKeyStore->getBlobFileNameIfExists(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS);
-    if (filename.isOk()) {
-        *aidl_return = static_cast<int32_t>(mKeyStore->del(
-            filename.value().string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid)));
-        return Status::ok();
-    }
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+    *aidl_return = static_cast<int32_t>(result);
     return Status::ok();
 }
 
@@ -244,13 +233,14 @@
         return Status::ok();
     }
 
-    auto filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid, ::TYPE_ANY);
-    *aidl_return = static_cast<int32_t>(filename.isOk() ? ResponseCode::NO_ERROR
-                                                        : ResponseCode::KEY_NOT_FOUND);
+    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, int targetUid,
+Status KeyStoreService::list(const String16& prefix, int32_t targetUid,
                              ::std::vector<::android::String16>* matches) {
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_LIST, targetUid)) {
@@ -258,15 +248,26 @@
             static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
     }
     const String8 prefix8(prefix);
-    String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid, TYPE_ANY));
-    android::Vector<android::String16> matches_internal;
-    if (mKeyStore->list(filename, &matches_internal, get_user_id(targetUid)) !=
-        ResponseCode::NO_ERROR) {
-        return Status::fromServiceSpecificError(static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+    const std::string stdPrefix(prefix8.string());
+
+    ResponseCode rc;
+    std::list<LockedKeyBlobEntry> internal_matches;
+
+    std::tie(rc, internal_matches) = LockedKeyBlobEntry::list(
+        mKeyStore->getUserStateDB().getUserStateByUid(targetUid)->getUserDirName(),
+        [&](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));
     }
-    matches->clear();
-    for (size_t i = 0; i < matches_internal.size(); ++i) {
-        matches->push_back(matches_internal[i]);
+
+    for (LockedKeyBlobEntry& entry : internal_matches) {
+        matches->push_back(String16(entry->alias().substr(prefix8.size()).c_str()));
     }
     return Status::ok();
 }
@@ -293,7 +294,7 @@
     const String8 password8(password);
     // Flush the auth token table to prevent stale tokens from sticking
     // around.
-    mAuthTokenTable.Clear();
+    mKeyStore->getAuthTokenTable().Clear();
 
     if (password.size() == 0) {
         ALOGI("Secure lockscreen for user %d removed, deleting encrypted entries", userId);
@@ -374,7 +375,7 @@
         return Status::ok();
     }
 
-    enforcement_policy.set_device_locked(true, userId);
+    mKeyStore->getEnforcementPolicy().set_device_locked(true, userId);
     mKeyStore->lock(userId);
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
     return Status::ok();
@@ -403,7 +404,7 @@
         return Status::ok();
     }
 
-    enforcement_policy.set_device_locked(false, userId);
+    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));
@@ -420,188 +421,6 @@
     return Status::ok();
 }
 
-Status KeyStoreService::generate(const String16& name, int32_t targetUid, int32_t keyType,
-                                 int32_t keySize, int32_t flags,
-                                 const ::android::security::KeystoreArguments& keystoreArgs,
-                                 int32_t* aidl_return) {
-    const Vector<sp<KeystoreArg>>* args = &(keystoreArgs.getArguments());
-    targetUid = getEffectiveUid(targetUid);
-    KeyStoreServiceReturnCode result =
-        checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (!result.isOk()) {
-        *aidl_return = static_cast<int32_t>(result);
-        return Status::ok();
-    }
-
-    keystore::AuthorizationSet params;
-    add_legacy_key_authorizations(keyType, &params);
-
-    switch (keyType) {
-    case EVP_PKEY_EC: {
-        params.push_back(TAG_ALGORITHM, Algorithm::EC);
-        if (keySize == -1) {
-            keySize = EC_DEFAULT_KEY_SIZE;
-        } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
-            ALOGI("invalid key size %d", keySize);
-            *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-            return Status::ok();
-        }
-        params.push_back(TAG_KEY_SIZE, keySize);
-        break;
-    }
-    case EVP_PKEY_RSA: {
-        params.push_back(TAG_ALGORITHM, Algorithm::RSA);
-        if (keySize == -1) {
-            keySize = RSA_DEFAULT_KEY_SIZE;
-        } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
-            ALOGI("invalid key size %d", keySize);
-            *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-            return Status::ok();
-        }
-        params.push_back(TAG_KEY_SIZE, keySize);
-        unsigned long exponent = RSA_DEFAULT_EXPONENT;
-        if (args->size() > 1) {
-            ALOGI("invalid number of arguments: %zu", args->size());
-            *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-            return Status::ok();
-        } else if (args->size() == 1) {
-            const sp<KeystoreArg>& expArg = args->itemAt(0);
-            if (expArg != nullptr) {
-                Unique_BIGNUM pubExpBn(BN_bin2bn(
-                    reinterpret_cast<const unsigned char*>(expArg->data()), expArg->size(), nullptr));
-                if (pubExpBn.get() == nullptr) {
-                    ALOGI("Could not convert public exponent to BN");
-                    *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-                    return Status::ok();
-                }
-                exponent = BN_get_word(pubExpBn.get());
-                if (exponent == 0xFFFFFFFFL) {
-                    ALOGW("cannot represent public exponent as a long value");
-                    *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-                    return Status::ok();
-                }
-            } else {
-                ALOGW("public exponent not read");
-                *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-                return Status::ok();
-            }
-        }
-        params.push_back(TAG_RSA_PUBLIC_EXPONENT, exponent);
-        break;
-    }
-    default: {
-        ALOGW("Unsupported key type %d", keyType);
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-    }
-
-    int32_t aidl_result;
-    android::security::keymaster::KeyCharacteristics unused_characteristics;
-    auto rc = generateKey(name, KeymasterArguments(params.hidl_data()), ::std::vector<uint8_t>(),
-                          targetUid, flags, &unused_characteristics, &aidl_result);
-    if (!KeyStoreServiceReturnCode(aidl_result).isOk()) {
-        ALOGW("generate failed: %d", int32_t(aidl_result));
-    }
-    *aidl_return = aidl_result;
-    return Status::ok();
-}
-
-Status KeyStoreService::import_key(const String16& name, const ::std::vector<uint8_t>& data,
-                                   int targetUid, int32_t flags, int32_t* aidl_return) {
-
-    const uint8_t* ptr = &data[0];
-
-    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(nullptr, &ptr, data.size()));
-    if (!pkcs8.get()) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-    Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
-    if (!pkey.get()) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-    int type = EVP_PKEY_type(pkey->type);
-    AuthorizationSet params;
-    add_legacy_key_authorizations(type, &params);
-    switch (type) {
-    case EVP_PKEY_RSA:
-        params.push_back(TAG_ALGORITHM, Algorithm::RSA);
-        break;
-    case EVP_PKEY_EC:
-        params.push_back(TAG_ALGORITHM, Algorithm::EC);
-        break;
-    default:
-        ALOGW("Unsupported key type %d", type);
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-
-    int import_result;
-    auto rc = importKey(name, KeymasterArguments(params.hidl_data()),
-                        static_cast<int32_t>(KeyFormat::PKCS8), data, targetUid, flags,
-                        /*outCharacteristics*/ nullptr, &import_result);
-
-    if (!KeyStoreServiceReturnCode(import_result).isOk()) {
-        ALOGW("importKey failed: %d", int32_t(import_result));
-    }
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return Status::ok();
-}
-
-Status KeyStoreService::sign(const String16& name, const ::std::vector<uint8_t>& data,
-                             ::std::vector<uint8_t>* out) {
-    if (!checkBinderPermission(P_SIGN)) {
-        return Status::fromServiceSpecificError(
-            static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
-    }
-    hidl_vec<uint8_t> legacy_out;
-    KeyStoreServiceReturnCode res =
-        doLegacySignVerify(name, data, &legacy_out, hidl_vec<uint8_t>(), KeyPurpose::SIGN);
-    if (!res.isOk()) {
-        return Status::fromServiceSpecificError((res));
-    }
-    *out = legacy_out;
-    return Status::ok();
-}
-
-Status KeyStoreService::verify(const String16& name, const ::std::vector<uint8_t>& data,
-                               const ::std::vector<uint8_t>& signature, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_VERIFY)) {
-        return Status::fromServiceSpecificError(
-            static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
-    }
-    *aidl_return = static_cast<int32_t>(
-        doLegacySignVerify(name, data, nullptr, signature, KeyPurpose::VERIFY));
-    return Status::ok();
-}
-
-/*
- * TODO: The abstraction between things stored in hardware and regular blobs
- * of data stored on the filesystem should be moved down to keystore itself.
- * Unfortunately the Java code that calls this has naming conventions that it
- * knows about. Ideally keystore shouldn't be used to store random blobs of
- * data.
- *
- * Until that happens, it's necessary to have a separate "get_pubkey" and
- * "del_key" since the Java code doesn't really communicate what it's
- * intentions are.
- */
-Status KeyStoreService::get_pubkey(const String16& name, ::std::vector<uint8_t>* pubKey) {
-    android::security::keymaster::ExportResult result;
-    KeymasterBlob clientId;
-    KeymasterBlob appData;
-    exportKey(name, static_cast<int32_t>(KeyFormat::X509), clientId, appData, UID_SELF, &result);
-    if (!result.resultCode.isOk()) {
-        ALOGW("export failed: %d", int32_t(result.resultCode));
-        return Status::fromServiceSpecificError(static_cast<int32_t>(result.resultCode));
-    }
-
-    if (pubKey) *pubKey = std::move(result.exportData);
-    return Status::ok();
-}
-
 Status KeyStoreService::grant(const String16& name, int32_t granteeUid,
                               ::android::String16* aidl_return) {
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -613,15 +432,13 @@
     }
 
     String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
-
-    if (access(filename.string(), R_OK) == -1) {
+    auto lockedEntry = mKeyStore->getLockedBlobEntryIfExists(name8.string(), callingUid);
+    if (!lockedEntry) {
         *aidl_return = String16();
         return Status::ok();
     }
 
-    *aidl_return =
-        String16(mKeyStore->addGrant(String8(name).string(), callingUid, granteeUid).c_str());
+    *aidl_return = String16(mKeyStore->addGrant(lockedEntry, granteeUid).c_str());
     return Status::ok();
 }
 
@@ -635,17 +452,13 @@
     }
 
     String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
 
-    if (access(filename.string(), R_OK) == -1) {
-        *aidl_return = static_cast<int32_t>((errno != ENOENT) ? ResponseCode::SYSTEM_ERROR
-                                                              : ResponseCode::KEY_NOT_FOUND);
-        return Status::ok();
+    auto lockedEntry = mKeyStore->getLockedBlobEntryIfExists(name8.string(), callingUid);
+    if (!lockedEntry) {
+        *aidl_return = static_cast<int32_t>(ResponseCode::KEY_NOT_FOUND);
     }
 
-    *aidl_return = static_cast<int32_t>(mKeyStore->removeGrant(name8, callingUid, granteeUid)
-                                            ? ResponseCode::NO_ERROR
-                                            : ResponseCode::KEY_NOT_FOUND);
+    *aidl_return = mKeyStore->removeGrant(lockedEntry, granteeUid);
     return Status::ok();
 }
 
@@ -656,18 +469,20 @@
         *time = -1L;
         return Status::ok();
     }
+    String8 name8(name);
 
-    auto filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid, ::TYPE_ANY);
-
-    if (!filename.isOk()) {
-        ALOGW("could not access %s for getmtime", filename.value().string());
+    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();
     }
 
-    int fd = TEMP_FAILURE_RETRY(open(filename.value().string(), O_NOFOLLOW, O_RDONLY));
+    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.value().string());
+        ALOGW("could not open %s for getmtime", filename.c_str());
         *time = -1L;
         return Status::ok();
     }
@@ -676,7 +491,7 @@
     int ret = fstat(fd, &s);
     close(fd);
     if (ret == -1) {
-        ALOGW("could not stat %s for getmtime", filename.value().string());
+        ALOGW("could not stat %s for getmtime", filename.c_str());
         *time = -1L;
         return Status::ok();
     }
@@ -700,33 +515,31 @@
 
     mKeyStore->removeAllGrantsToUid(targetUid);
 
-    String8 prefix = String8::format("%u_", targetUid);
-    Vector<String16> aliases;
-    if (mKeyStore->list(prefix, &aliases, get_user_id(targetUid)) != ResponseCode::NO_ERROR) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+    ResponseCode rc;
+    std::list<LockedKeyBlobEntry> entries;
+
+    // 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(
+        mKeyStore->getUserStateDB().getUserStateByUid(targetUid)->getUserDirName(),
+        [&](uid_t uid, const std::string&) -> bool { return uid == targetUid; });
+
+    if (rc != ResponseCode::NO_ERROR) {
+        *aidl_return = static_cast<int32_t>(rc);
         return Status::ok();
     }
 
-    for (uint32_t i = 0; i < aliases.size(); i++) {
-        String8 name8(aliases[i]);
-        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
-
+    for (LockedKeyBlobEntry& lockedEntry : entries) {
         if (get_app_id(targetUid) == AID_SYSTEM) {
             Blob keyBlob;
-            ResponseCode responseCode =
-                mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, get_user_id(targetUid));
-            if (responseCode == ResponseCode::NO_ERROR && keyBlob.isCriticalToDeviceEncryption()) {
+            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(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
-
-        // del() will fail silently if no cached characteristics are present for this alias.
-        String8 chr_filename(
-            mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS));
-        mKeyStore->del(chr_filename.string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid));
+        mKeyStore->del(lockedEntry);
     }
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
     return Status::ok();
@@ -737,10 +550,15 @@
     auto device = mKeyStore->getDevice(flagsToSecurityLevel(flags));
     if (!device) {
         *aidl_return = static_cast<int32_t>(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
-    } else {
-        *aidl_return = static_cast<int32_t>(
-            KeyStoreServiceReturnCode(KS_HANDLE_HIDL_ERROR(device->addRngEntropy(entropy))));
+        return Status::ok();
     }
+    std::promise<KeyStoreServiceReturnCode> resultPromise;
+    auto resultFuture = resultPromise.get_future();
+
+    device->addRngEntropy(
+        entropy, [&](Return<ErrorCode> rc) { resultPromise.set_value(KS_HANDLE_HIDL_ERROR(rc)); });
+    resultFuture.wait();
+    *aidl_return = int32_t(resultFuture.get());
     return Status::ok();
 }
 
@@ -786,105 +604,34 @@
         *aidl_return = static_cast<int32_t>(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
         return Status::ok();
     }
-    AuthorizationSet keyCharacteristics = params.getParameters();
 
-    // TODO: Seed from Linux RNG before this.
-    rc = KS_HANDLE_HIDL_ERROR(dev->addRngEntropy(entropy));
-    if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
-    }
-
-    KeyStoreServiceReturnCode error;
-    auto hidl_cb = [&](ErrorCode ret, const ::std::vector<uint8_t>& hidlKeyBlob,
-                       const KeyCharacteristics& keyCharacteristics) {
-        error = ret;
-        if (!error.isOk()) {
-            return;
-        }
-        if (outCharacteristics)
-            *outCharacteristics =
-                ::android::security::keymaster::KeyCharacteristics(keyCharacteristics);
-
-        // Write the key
-        String8 name8(name);
-        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
-
-        Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
-        keyBlob.setSecurityLevel(securityLevel);
-        keyBlob.setCriticalToDeviceEncryption(flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
-        if (isAuthenticationBound(params.getParameters()) &&
-            !keyBlob.isCriticalToDeviceEncryption()) {
-            keyBlob.setSuperEncrypted(true);
-        }
-        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
-
-        error = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
-    };
-
-    rc = KS_HANDLE_HIDL_ERROR(dev->generateKey(params.getParameters(), hidl_cb));
-    if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
-    }
-    if (!error.isOk()) {
-        ALOGE("Failed to generate key -> falling back to software keymaster");
-        uploadKeyCharacteristicsAsProto(params.getParameters(), false /* wasCreationSuccessful */);
-        securityLevel = SecurityLevel::SOFTWARE;
-
-        // No fall back for 3DES
-        for (auto& param : params.getParameters()) {
-            auto algorithm = authorizationValue(TAG_ALGORITHM, param);
-            if (algorithm.isOk() && algorithm.value() == Algorithm::TRIPLE_DES) {
-                *aidl_return = static_cast<int32_t>(ErrorCode::UNSUPPORTED_ALGORITHM);
-                return Status::ok();
-            }
-        }
-
-        auto fallback = mKeyStore->getFallbackDevice();
-        if (!fallback) {
-            *aidl_return = static_cast<int32_t>(error);
-            return Status::ok();
-        }
-        rc = KS_HANDLE_HIDL_ERROR(fallback->generateKey(params.getParameters(), hidl_cb));
-        if (!rc.isOk()) {
-            *aidl_return = static_cast<int32_t>(rc);
-            return Status::ok();
-        }
-        if (!error.isOk()) {
-            *aidl_return = static_cast<int32_t>(error);
-            return Status::ok();
-        }
-    } else {
-        uploadKeyCharacteristicsAsProto(params.getParameters(), true /* wasCreationSuccessful */);
-    }
-
-    if (!containsTag(params.getParameters(), Tag::USER_ID)) {
-        // Most Java processes don't have access to this tag
-        KeyParameter user_id;
-        user_id.tag = Tag::USER_ID;
-        user_id.f.integer = multiuser_get_user_id(uid);
-        keyCharacteristics.push_back(user_id);
-    }
-
-    // Write the characteristics:
     String8 name8(name);
-    String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
-
-    std::stringstream kc_stream;
-    keyCharacteristics.Serialize(&kc_stream);
-    if (kc_stream.bad()) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+    auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), uid);
+    if (!lockedEntry) {
+        *aidl_return = static_cast<int32_t>(ResponseCode::KEY_ALREADY_EXISTS);
         return Status::ok();
     }
-    auto kc_buf = kc_stream.str();
-    Blob charBlob(reinterpret_cast<const uint8_t*>(kc_buf.data()), kc_buf.size(), nullptr, 0,
-                  ::TYPE_KEY_CHARACTERISTICS);
-    charBlob.setSecurityLevel(securityLevel);
-    charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
 
-    *aidl_return =
-        static_cast<int32_t>(mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid)));
+    logOnScopeExit.Disable();
+
+    std::promise<KeyStoreServiceReturnCode> resultPromise;
+    auto resultFuture = resultPromise.get_future();
+
+    dev->generateKey(std::move(lockedEntry), params.getParameters(), entropy, flags,
+                     [&, uid](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+                         if (outCharacteristics && rc.isOk()) {
+                             *outCharacteristics = android::security::keymaster::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;
+                         }
+                         resultPromise.set_value(rc);
+                     });
+
+    resultFuture.wait();
+    *aidl_return = int32_t(resultFuture.get());
     return Status::ok();
 }
 
@@ -907,87 +654,45 @@
         return Status::ok();
     }
 
-    Blob keyBlob;
     String8 name8(name);
 
-    KeyStoreServiceReturnCode rc =
-        mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
-    if (rc == ResponseCode::UNINITIALIZED) {
-        /*
-         * If we fail reading the blob because the master key is missing we try to retrieve the
-         * key characteristics from the characteristics file. This happens when auth-bound
-         * keys are used after a screen lock has been removed by the user.
-         */
-        rc = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEY_CHARACTERISTICS);
-        if (!rc.isOk()) {
-            *aidl_return = static_cast<int32_t>(rc);
-            return Status::ok();
-        }
-        AuthorizationSet keyCharacteristics;
-        // TODO write one shot stream buffer to avoid copying (twice here)
-        std::string charBuffer(reinterpret_cast<const char*>(keyBlob.getValue()),
-                               keyBlob.getLength());
-        std::stringstream charStream(charBuffer);
-        keyCharacteristics.Deserialize(&charStream);
+    ResponseCode rc;
+    Blob keyBlob;
+    Blob charBlob;
+    LockedKeyBlobEntry lockedEntry;
 
-        outCharacteristics->softwareEnforced = KeymasterArguments(keyCharacteristics.hidl_data());
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
-    } else if (!rc.isOk()) {
+    std::tie(rc, keyBlob, charBlob, lockedEntry) =
+        mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
+
+    if (rc != ResponseCode::NO_ERROR) {
         *aidl_return = static_cast<int32_t>(rc);
         return Status::ok();
     }
 
-    auto hidlKeyBlob = blob2hidlVec(keyBlob);
     auto dev = mKeyStore->getDevice(keyBlob);
-
-    KeyStoreServiceReturnCode error;
-
-    auto hidlCb = [&](ErrorCode ret, const KeyCharacteristics& keyCharacteristics) {
-        error = ret;
-        if (!error.isOk()) {
-            if (error == ErrorCode::INVALID_KEY_BLOB) {
-                log_key_integrity_violation(name8, targetUid);
-            }
-            return;
-        }
-        *outCharacteristics =
-            ::android::security::keymaster::KeyCharacteristics(keyCharacteristics);
-    };
-
-    rc = KS_HANDLE_HIDL_ERROR(
-        dev->getKeyCharacteristics(hidlKeyBlob, clientId.getData(), appData.getData(), hidlCb));
-    if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
+    if (!dev) {
+        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
         return Status::ok();
     }
 
-    if (error == ErrorCode::KEY_REQUIRES_UPGRADE) {
-        AuthorizationSet upgradeParams;
-        if (clientId.getData().size()) {
-            upgradeParams.push_back(TAG_APPLICATION_ID, clientId.getData());
-        }
-        if (appData.getData().size()) {
-            upgradeParams.push_back(TAG_APPLICATION_DATA, appData.getData());
-        }
-        rc = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
-        if (!rc.isOk()) {
-            *aidl_return = static_cast<int32_t>(rc);
-            return Status::ok();
-        }
+    // 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.
+    std::promise<KeyStoreServiceReturnCode> resultPromise;
+    auto resultFuture = resultPromise.get_future();
 
-        auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
+    dev->getKeyCharacteristics(
+        std::move(lockedEntry), clientId.getData(), appData.getData(), std::move(keyBlob),
+        std::move(charBlob),
+        [&](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+            if (outCharacteristics && rc.isOk()) {
+                *outCharacteristics = std::move(keyCharacteristics);
+            }
+            resultPromise.set_value(rc);
+        });
 
-        rc = KS_HANDLE_HIDL_ERROR(dev->getKeyCharacteristics(
-            upgradedHidlKeyBlob, clientId.getData(), appData.getData(), hidlCb));
-        if (!rc.isOk()) {
-            *aidl_return = static_cast<int32_t>(rc);
-            return Status::ok();
-        }
-        // Note that, on success, "error" will have been updated by the hidlCB callback.
-        // So it is fine to return "error" below.
-    }
-    *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(error));
+    resultFuture.wait();
+    *aidl_return = int32_t(resultFuture.get());
     return Status::ok();
 }
 
@@ -1007,6 +712,7 @@
     KeyStoreServiceReturnCode rc =
         checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
     if (!rc.isOk()) {
+        LOG(ERROR) << "permissission denied";
         *aidl_return = static_cast<int32_t>(rc);
         return Status::ok();
     }
@@ -1019,110 +725,40 @@
     SecurityLevel securityLevel = flagsToSecurityLevel(flags);
     auto dev = mKeyStore->getDevice(securityLevel);
     if (!dev) {
+        LOG(ERROR) << "importKey - cound not get keymaster device";
         *aidl_return = static_cast<int32_t>(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
         return Status::ok();
     }
 
     String8 name8(name);
-
-    KeyStoreServiceReturnCode error;
-
-    auto hidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& keyBlob,
-                      const KeyCharacteristics& keyCharacteristics) {
-        error = ret;
-        if (!error.isOk()) {
-            return;
-        }
-        if (outCharacteristics)
-            *outCharacteristics =
-                ::android::security::keymaster::KeyCharacteristics(keyCharacteristics);
-
-        // Write the key:
-        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
-
-        Blob ksBlob(&keyBlob[0], keyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
-        ksBlob.setSecurityLevel(securityLevel);
-        ksBlob.setCriticalToDeviceEncryption(flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
-        if (isAuthenticationBound(params.getParameters()) &&
-            !ksBlob.isCriticalToDeviceEncryption()) {
-            ksBlob.setSuperEncrypted(true);
-        }
-        ksBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
-
-        error = mKeyStore->put(filename.string(), &ksBlob, get_user_id(uid));
-    };
-
-    rc = KS_HANDLE_HIDL_ERROR(
-        dev->importKey(params.getParameters(), KeyFormat(format), keyData, hidlCb));
-    // possible hidl error
-    if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
+    auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), uid);
+    if (!lockedEntry) {
+        LOG(ERROR) << "importKey - key: " << name8.string() << " " << int(uid)
+                   << " already exists.";
+        *aidl_return = static_cast<int32_t>(ResponseCode::KEY_ALREADY_EXISTS);
         return Status::ok();
     }
-    // now check error from callback
-    if (!error.isOk()) {
-        ALOGE("Failed to import key -> falling back to software keymaster");
-        uploadKeyCharacteristicsAsProto(params.getParameters(), false /* wasCreationSuccessful */);
-        securityLevel = SecurityLevel::SOFTWARE;
 
-        // No fall back for 3DES
-        for (auto& param : params.getParameters()) {
-            auto algorithm = authorizationValue(TAG_ALGORITHM, param);
-            if (algorithm.isOk() && algorithm.value() == Algorithm::TRIPLE_DES) {
-                *aidl_return = static_cast<int32_t>(ErrorCode::UNSUPPORTED_ALGORITHM);
-                return Status::ok();
-            }
-        }
+    logOnScopeExit.Disable();
 
-        auto fallback = mKeyStore->getFallbackDevice();
-        if (!fallback) {
-            *aidl_return = static_cast<int32_t>(error);
-            return Status::ok();
-        }
-        rc = KS_HANDLE_HIDL_ERROR(
-            fallback->importKey(params.getParameters(), KeyFormat(format), keyData, hidlCb));
-        // possible hidl error
-        if (!rc.isOk()) {
-            *aidl_return = static_cast<int32_t>(rc);
-            return Status::ok();
-        }
-        // now check error from callback
-        if (!error.isOk()) {
-            *aidl_return = static_cast<int32_t>(error);
-            return Status::ok();
-        }
-    } else {
-        uploadKeyCharacteristicsAsProto(params.getParameters(), true /* wasCreationSuccessful */);
-    }
+    std::promise<KeyStoreServiceReturnCode> resultPromise;
+    auto resultFuture = resultPromise.get_future();
 
-    // Write the characteristics:
-    String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
+    dev->importKey(std::move(lockedEntry), params.getParameters(), KeyFormat(format), keyData,
+                   flags,
+                   [&, uid](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+                       if (outCharacteristics && rc.isOk()) {
+                           *outCharacteristics = std::move(keyCharacteristics);
+                       }
+                       if (__android_log_security()) {
+                           android_log_event_list(SEC_TAG_KEY_IMPORTED)
+                               << rc.isOk() << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
+                       }
+                       resultPromise.set_value(rc);
+                   });
 
-    AuthorizationSet opParams = params.getParameters();
-    if (!containsTag(params.getParameters(), Tag::USER_ID)) {
-        // Most Java processes don't have access to this tag
-        KeyParameter user_id;
-        user_id.tag = Tag::USER_ID;
-        user_id.f.integer = multiuser_get_user_id(uid);
-        opParams.push_back(user_id);
-    }
-
-    std::stringstream kcStream;
-    opParams.Serialize(&kcStream);
-    if (kcStream.bad()) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-    auto kcBuf = kcStream.str();
-
-    Blob charBlob(reinterpret_cast<const uint8_t*>(kcBuf.data()), kcBuf.size(), nullptr, 0,
-                  ::TYPE_KEY_CHARACTERISTICS);
-    charBlob.setSecurityLevel(securityLevel);
-    charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
-
-    *aidl_return =
-        static_cast<int32_t>(mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid)));
-
+    resultFuture.wait();
+    *aidl_return = int32_t(resultFuture.get());
     return Status::ok();
 }
 
@@ -1139,56 +775,31 @@
         return Status::ok();
     }
 
-    Blob keyBlob;
     String8 name8(name);
 
-    result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
-    if (!result->resultCode.isOk()) {
+    KeyStoreServiceReturnCode rc;
+    Blob keyBlob;
+    Blob charBlob;
+    LockedKeyBlobEntry lockedEntry;
+
+    std::tie(rc, keyBlob, charBlob, lockedEntry) =
+        mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
+    if (!rc) {
+        result->resultCode = rc;
         return Status::ok();
     }
 
-    auto key = blob2hidlVec(keyBlob);
     auto dev = mKeyStore->getDevice(keyBlob);
+    std::promise<void> resultPromise;
+    auto resultFuture = resultPromise.get_future();
 
-    auto hidlCb = [&](ErrorCode ret, const ::android::hardware::hidl_vec<uint8_t>& keyMaterial) {
-        result->resultCode = ret;
-        if (!result->resultCode.isOk()) {
-            if (result->resultCode == ErrorCode::INVALID_KEY_BLOB) {
-                log_key_integrity_violation(name8, targetUid);
-            }
-            return;
-        }
-        result->exportData = keyMaterial;
-    };
-    KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
-        dev->exportKey(KeyFormat(format), key, clientId.getData(), appData.getData(), hidlCb));
-    // Overwrite result->resultCode only on HIDL error. Otherwise we want the result set in the
-    // callback hidlCb.
-    if (!rc.isOk()) {
-        result->resultCode = rc;
-    }
+    dev->exportKey(std::move(lockedEntry), KeyFormat(format), clientId.getData(), appData.getData(),
+                   std::move(keyBlob), std::move(charBlob), [&](ExportResult exportResult) {
+                       *result = std::move(exportResult);
+                       resultPromise.set_value();
+                   });
 
-    if (result->resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
-        AuthorizationSet upgradeParams;
-        if (clientId.getData().size()) {
-            upgradeParams.push_back(TAG_APPLICATION_ID, clientId.getData());
-        }
-        if (appData.getData().size()) {
-            upgradeParams.push_back(TAG_APPLICATION_DATA, appData.getData());
-        }
-        result->resultCode = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
-        if (!result->resultCode.isOk()) {
-            return Status::ok();
-        }
-
-        auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
-
-        result->resultCode = KS_HANDLE_HIDL_ERROR(dev->exportKey(
-            KeyFormat(format), upgradedHidlKeyBlob, clientId.getData(), appData.getData(), hidlCb));
-        if (!result->resultCode.isOk()) {
-            return Status::ok();
-        }
-    }
+    resultFuture.wait();
     return Status::ok();
 }
 
@@ -1196,8 +807,6 @@
                               bool pruneable, const KeymasterArguments& params,
                               const ::std::vector<uint8_t>& entropy, int32_t uid,
                               OperationResult* result) {
-    auto keyPurpose = static_cast<KeyPurpose>(purpose);
-
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     uid_t targetUid = getEffectiveUid(uid);
     if (!is_granted_to(callingUid, targetUid)) {
@@ -1215,217 +824,42 @@
         return Status::ok();
     }
 
-    Blob keyBlob;
     String8 name8(name);
-    result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
-    if (result->resultCode == ResponseCode::LOCKED && keyBlob.isSuperEncrypted()) {
-        result->resultCode = ErrorCode::KEY_USER_NOT_AUTHENTICATED;
-    }
-    if (!result->resultCode.isOk()) return Status::ok();
+    Blob keyBlob;
+    Blob charBlob;
+    LockedKeyBlobEntry lockedEntry;
+    ResponseCode rc;
 
-    auto key = blob2hidlVec(keyBlob);
+    std::tie(rc, keyBlob, charBlob, lockedEntry) =
+        mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
+
+    if (rc == ResponseCode::LOCKED && keyBlob.isSuperEncrypted()) {
+        return result->resultCode = ErrorCode::KEY_USER_NOT_AUTHENTICATED, Status::ok();
+    }
+    if (rc != ResponseCode::NO_ERROR) return result->resultCode = rc, Status::ok();
+
     auto dev = mKeyStore->getDevice(keyBlob);
     AuthorizationSet opParams = params.getParameters();
     KeyCharacteristics characteristics;
-    result->resultCode = getOperationCharacteristics(key, &dev, opParams, &characteristics);
 
-    if (result->resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
-        result->resultCode = upgradeKeyBlob(name, targetUid, opParams, &keyBlob);
-        if (!result->resultCode.isOk()) {
-            return Status::ok();
-        }
-        key = blob2hidlVec(keyBlob);
-        result->resultCode = getOperationCharacteristics(key, &dev, opParams, &characteristics);
-    }
-    if (!result->resultCode.isOk()) {
-        return Status::ok();
-    }
+    std::promise<void> resultPromise;
+    auto resultFuture = resultPromise.get_future();
 
-    // Merge these characteristics with the ones cached when the key was generated or imported
-    Blob charBlob;
-    AuthorizationSet persistedCharacteristics;
-    result->resultCode =
-        mKeyStore->getKeyForName(&charBlob, name8, targetUid, TYPE_KEY_CHARACTERISTICS);
-    if (result->resultCode.isOk()) {
-        // TODO write one shot stream buffer to avoid copying (twice here)
-        std::string charBuffer(reinterpret_cast<const char*>(charBlob.getValue()),
-                               charBlob.getLength());
-        std::stringstream charStream(charBuffer);
-        persistedCharacteristics.Deserialize(&charStream);
-    } else {
-        ALOGD("Unable to read cached characteristics for key");
-    }
+    dev->begin(std::move(lockedEntry), appToken, std::move(keyBlob), std::move(charBlob), pruneable,
+               static_cast<KeyPurpose>(purpose), std::move(opParams), entropy,
+               [&, this](OperationResult result_) {
+                   if (result_.resultCode.isOk() ||
+                       result_.resultCode == ResponseCode::OP_AUTH_NEEDED) {
+                       addOperationDevice(result_.token, dev);
+                   }
+                   if (result) *result = std::move(result_);
+                   resultPromise.set_value();
+               });
 
-    // Replace the sw_enforced set with those persisted to disk, minus hw_enforced
-    AuthorizationSet softwareEnforced = characteristics.softwareEnforced;
-    AuthorizationSet hardwareEnforced = characteristics.hardwareEnforced;
-    persistedCharacteristics.Union(softwareEnforced);
-    persistedCharacteristics.Subtract(hardwareEnforced);
-    characteristics.softwareEnforced = persistedCharacteristics.hidl_data();
-
-    KeyStoreServiceReturnCode authResult;
-    HardwareAuthToken authToken;
-    std::tie(authResult, authToken) =
-        getAuthToken(characteristics, 0 /* no challenge */, keyPurpose,
-                     /*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 (!authResult.isOk() && authResult != ResponseCode::OP_AUTH_NEEDED) {
-        result->resultCode = authResult;
-        return Status::ok();
-    }
-
-    // Add entropy to the device first.
-    if (entropy.size()) {
-        result->resultCode = KS_HANDLE_HIDL_ERROR(dev->addRngEntropy(entropy));
-        if (!result->resultCode.isOk()) {
-            return Status::ok();
-        }
-    }
-
-    // Create a keyid for this key.
-    km_id_t keyid;
-    if (!enforcement_policy.CreateKeyId(key, &keyid)) {
-        ALOGE("Failed to create a key ID for authorization checking.");
-        result->resultCode = ErrorCode::UNKNOWN_ERROR;
-        return Status::ok();
-    }
-
-    // Check that all key authorization policy requirements are met.
-    AuthorizationSet key_auths = characteristics.hardwareEnforced;
-    key_auths.append(characteristics.softwareEnforced.begin(),
-                     characteristics.softwareEnforced.end());
-
-    result->resultCode =
-        enforcement_policy.AuthorizeOperation(keyPurpose, keyid, key_auths, opParams, authToken,
-                                              0 /* op_handle */, true /* is_begin_operation */);
-    if (!result->resultCode.isOk()) {
-        return Status::ok();
-    }
-
-    // If there are more than kMaxOperations, abort the oldest operation that was started as
-    // pruneable.
-    while (mOperationMap.getOperationCount() >= kMaxOperations) {
-        ALOGD("Reached or exceeded concurrent operations limit");
-        if (!pruneOperation()) {
-            break;
-        }
-    }
-
-    auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
-                      uint64_t operationHandle) {
-        result->resultCode = ret;
-        if (!result->resultCode.isOk()) {
-            if (result->resultCode == ErrorCode::INVALID_KEY_BLOB) {
-                log_key_integrity_violation(name8, targetUid);
-            }
-            return;
-        }
-        result->handle = operationHandle;
-        result->outParams = outParams;
-    };
-
-    KeyStoreServiceReturnCode rc =
-        KS_HANDLE_HIDL_ERROR(dev->begin(keyPurpose, key, opParams.hidl_data(), authToken, hidlCb));
-    if (!rc.isOk()) {
-        LOG(ERROR) << "Got error " << rc << " from begin()";
-        result->resultCode = ResponseCode::SYSTEM_ERROR;
-        return Status::ok();
-    }
-
-    rc = result->resultCode;
-
-    // If there are too many operations abort the oldest operation that was
-    // started as pruneable and try again.
-    LOG(INFO) << rc << " " << mOperationMap.hasPruneableOperation();
-    while (rc == ErrorCode::TOO_MANY_OPERATIONS && mOperationMap.hasPruneableOperation()) {
-        LOG(INFO) << "Ran out of operation handles";
-        if (!pruneOperation()) {
-            break;
-        }
-        rc = KS_HANDLE_HIDL_ERROR(
-            dev->begin(keyPurpose, key, opParams.hidl_data(), authToken, hidlCb));
-        if (!rc.isOk()) {
-            LOG(ERROR) << "Got error " << rc << " from begin()";
-            result->resultCode = ResponseCode::SYSTEM_ERROR;
-            return Status::ok();
-        }
-        rc = result->resultCode;
-    }
-    if (!rc.isOk()) {
-        result->resultCode = rc;
-        return Status::ok();
-    }
-
-    VerificationToken verificationToken;
-    if (authResult.isOk() && authToken.mac.size() &&
-        dev->halVersion().securityLevel == SecurityLevel::STRONGBOX) {
-        // This operation needs an auth token, but the device is a STRONGBOX, so it can't check the
-        // timestamp in the auth token.  Get a VerificationToken from the TEE, which will be passed
-        // to update() and begin().
-        rc = KS_HANDLE_HIDL_ERROR(mKeyStore->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)
-                                      ->verifyAuthorization(result->handle,
-                                                            {} /* parametersToVerify */, authToken,
-                                                            [&](auto error, const auto& token) {
-                                                                result->resultCode = error;
-                                                                verificationToken = token;
-                                                            }));
-
-        if (!rc.isOk()) result->resultCode = rc;
-        if (!result->resultCode.isOk()) {
-            LOG(ERROR) << "Failed to verify authorization " << rc << " from begin()";
-            rc = KS_HANDLE_HIDL_ERROR(dev->abort(result->handle));
-            if (!rc.isOk()) {
-                LOG(ERROR) << "Failed to abort operation " << rc << " from begin()";
-            }
-            return Status::ok();
-        }
-    }
-
-    // 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 =
-        mOperationMap.addOperation(result->handle, keyid, keyPurpose, dev, appToken,
-                                   std::move(characteristics), params.getParameters(), pruneable);
-    assert(characteristics.hardwareEnforced.size() == 0);
-    assert(characteristics.softwareEnforced.size() == 0);
-    result->token = operationToken;
-
-    mOperationMap.setOperationAuthToken(operationToken, std::move(authToken));
-    mOperationMap.setOperationVerificationToken(operationToken, std::move(verificationToken));
-
-    // 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 == ErrorCode::OK) {
-        result->resultCode = authResult;
-    }
-
-    // Other result fields were set in the begin operation's callback.
+    resultFuture.wait();
     return Status::ok();
 }
 
-void KeyStoreService::appendConfirmationTokenIfNeeded(const KeyCharacteristics& keyCharacteristics,
-                                                      std::vector<KeyParameter>* params) {
-    if (!(containsTag(keyCharacteristics.softwareEnforced, Tag::TRUSTED_CONFIRMATION_REQUIRED) ||
-          containsTag(keyCharacteristics.hardwareEnforced, Tag::TRUSTED_CONFIRMATION_REQUIRED))) {
-        return;
-    }
-
-    hidl_vec<uint8_t> confirmationToken = mConfirmationManager->getLatestConfirmationToken();
-    if (confirmationToken.size() == 0) {
-        return;
-    }
-
-    params->push_back(
-        Authorization(keymaster::TAG_CONFIRMATION_TOKEN, std::move(confirmationToken)));
-    ALOGD("Appending confirmation token\n");
-}
-
 Status KeyStoreService::update(const sp<IBinder>& token, const KeymasterArguments& params,
                                const ::std::vector<uint8_t>& data, OperationResult* result) {
     if (!checkAllowedOperationParams(params.getParameters())) {
@@ -1433,140 +867,70 @@
         return Status::ok();
     }
 
-    auto getOpResult = mOperationMap.getOperation(token);
-    if (!getOpResult.isOk()) {
-        result->resultCode = ErrorCode::INVALID_OPERATION_HANDLE;
+    std::promise<void> resultPromise;
+    auto resultFuture = resultPromise.get_future();
+
+    auto dev = getOperationDevice(token);
+    if (!dev) {
+        *result = operationFailed(ErrorCode::INVALID_OPERATION_HANDLE);
         return Status::ok();
     }
-    const auto& op = getOpResult.value();
 
-    HardwareAuthToken authToken;
-    std::tie(result->resultCode, authToken) = getOperationAuthTokenIfNeeded(token);
-    if (!result->resultCode.isOk()) return Status::ok();
-
-    // 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());
-
-    result->resultCode = enforcement_policy.AuthorizeOperation(
-        op.purpose, op.keyid, key_auths, params.getParameters(), authToken, op.handle,
-        false /* is_begin_operation */);
-    if (!result->resultCode.isOk()) return Status::ok();
-
-    std::vector<KeyParameter> inParams = params.getParameters();
-
-    auto hidlCb = [&](ErrorCode ret, uint32_t inputConsumed,
-                      const hidl_vec<KeyParameter>& outParams,
-                      const ::std::vector<uint8_t>& output) {
-        result->resultCode = ret;
-        if (result->resultCode.isOk()) {
-            result->inputConsumed = inputConsumed;
-            result->outParams = outParams;
-            result->data = output;
+    dev->update(token, params.getParameters(), data, [&](OperationResult result_) {
+        if (!result_.resultCode.isOk()) {
+            removeOperationDevice(token);
         }
-    };
+        if (result) *result = std::move(result_);
+        resultPromise.set_value();
+    });
 
-    KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
-        op.device->update(op.handle, inParams, data, 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;
-        // removeOperation() will free the memory 'op' used, so the order is important
-        mAuthTokenTable.MarkCompleted(op.handle);
-        mOperationMap.removeOperation(token, /* wasOpSuccessful */ false);
-    }
-
+    resultFuture.wait();
     return Status::ok();
 }
 
 Status KeyStoreService::finish(const sp<IBinder>& token, const KeymasterArguments& params,
                                const ::std::vector<uint8_t>& signature,
                                const ::std::vector<uint8_t>& entropy, OperationResult* result) {
-    auto getOpResult = mOperationMap.getOperation(token);
-    if (!getOpResult.isOk()) {
-        result->resultCode = ErrorCode::INVALID_OPERATION_HANDLE;
-        return Status::ok();
-    }
-    const auto& op = std::move(getOpResult.value());
     if (!checkAllowedOperationParams(params.getParameters())) {
         result->resultCode = ErrorCode::INVALID_ARGUMENT;
         return Status::ok();
     }
 
-    HardwareAuthToken authToken;
-    std::tie(result->resultCode, authToken) = getOperationAuthTokenIfNeeded(token);
-    if (!result->resultCode.isOk()) return Status::ok();
+    std::promise<void> resultPromise;
+    auto resultFuture = resultPromise.get_future();
 
-    if (entropy.size()) {
-        result->resultCode = KS_HANDLE_HIDL_ERROR(op.device->addRngEntropy(entropy));
-        if (!result->resultCode.isOk()) {
-            return Status::ok();
-        }
+    auto dev = getOperationDevice(token);
+    if (!dev) {
+        *result = operationFailed(ErrorCode::INVALID_OPERATION_HANDLE);
+        return Status::ok();
     }
 
-    // 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());
+    dev->finish(token, params.getParameters(), {}, signature, entropy,
+                [&](OperationResult result_) {
+                    if (!result_.resultCode.isOk()) {
+                        removeOperationDevice(token);
+                    }
+                    if (result) *result = std::move(result_);
+                    resultPromise.set_value();
+                });
 
-    std::vector<KeyParameter> inParams = params.getParameters();
-    appendConfirmationTokenIfNeeded(op.characteristics, &inParams);
-
-    result->resultCode = enforcement_policy.AuthorizeOperation(
-        op.purpose, op.keyid, key_auths, params.getParameters(), authToken, op.handle,
-        false /* is_begin_operation */);
-    if (!result->resultCode.isOk()) return Status::ok();
-
-    auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
-                      const ::std::vector<uint8_t>& output) {
-        result->resultCode = ret;
-        if (result->resultCode.isOk()) {
-            result->outParams = outParams;
-            result->data = output;
-        }
-    };
-
-    KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
-        op.device->finish(op.handle, inParams,
-                          ::std::vector<uint8_t>() /* TODO(swillden): wire up input to finish() */,
-                          signature, authToken, op.verificationToken, hidlCb));
-
-    bool wasOpSuccessful = true;
-    // 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;
-        wasOpSuccessful = false;
-    }
-
-    // removeOperation() will free the memory 'op' used, so the order is important
-    mAuthTokenTable.MarkCompleted(op.handle);
-    mOperationMap.removeOperation(token, wasOpSuccessful);
+    resultFuture.wait();
     return Status::ok();
 }
 
 Status KeyStoreService::abort(const sp<IBinder>& token, int32_t* aidl_return) {
-    auto getOpResult = mOperationMap.removeOperation(token, false /* wasOpSuccessful */);
-    if (!getOpResult.isOk()) {
+    auto dev = getOperationDevice(token);
+    if (!dev) {
         *aidl_return = static_cast<int32_t>(ErrorCode::INVALID_OPERATION_HANDLE);
         return Status::ok();
     }
-    auto op = std::move(getOpResult.value());
-    mAuthTokenTable.MarkCompleted(op.handle);
+    std::promise<KeyStoreServiceReturnCode> resultPromise;
+    auto resultFuture = resultPromise.get_future();
 
-    ErrorCode error_code = KS_HANDLE_HIDL_ERROR(op.device->abort(op.handle));
-    *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(error_code));
-    return Status::ok();
-}
+    dev->abort(token, [&](KeyStoreServiceReturnCode rc) { resultPromise.set_value(rc); });
 
-Status KeyStoreService::isOperationAuthorized(const sp<IBinder>& token, bool* aidl_return) {
-    AuthorizationSet ignored;
-    KeyStoreServiceReturnCode rc;
-    std::tie(rc, std::ignore) = getOperationAuthTokenIfNeeded(token);
-    *aidl_return = rc.isOk();
+    resultFuture.wait();
+    *aidl_return = int32_t(resultFuture.get());
     return Status::ok();
 }
 
@@ -1593,7 +957,8 @@
         return Status::ok();
     }
 
-    mAuthTokenTable.AddAuthenticationToken(hidlVec2AuthToken(hidl_vec<uint8_t>(authTokenAsVector)));
+    mKeyStore->getAuthTokenTable().AddAuthenticationToken(
+        hidlVec2AuthToken(hidl_vec<uint8_t>(authTokenAsVector)));
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
     return Status::ok();
 }
@@ -1653,33 +1018,35 @@
         return Status::ok();
     }
 
-    Blob keyBlob;
     String8 name8(name);
-    rc = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, TYPE_KEYMASTER_10);
-    if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
-    }
+    Blob keyBlob;
+    Blob charBlob;
+    LockedKeyBlobEntry lockedEntry;
 
-    KeyStoreServiceReturnCode error;
-    auto hidlCb = [&](ErrorCode ret, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
-        error = ret;
-        if (!error.isOk()) {
+    std::tie(rc, keyBlob, charBlob, lockedEntry) =
+        mKeyStore->getKeyForName(name8, callingUid, TYPE_KEYMASTER_10);
+
+    std::promise<KeyStoreServiceReturnCode> resultPromise;
+    auto resultFuture = resultPromise.get_future();
+
+    auto worker_cb = [&](Return<void> rc,
+                         std::tuple<ErrorCode, hidl_vec<hidl_vec<uint8_t>>>&& hidlResult) {
+        auto& [ret, certChain] = hidlResult;
+        if (!rc.isOk()) {
+            resultPromise.set_value(ResponseCode::SYSTEM_ERROR);
             return;
         }
-        if (chain) {
+        if (ret == ErrorCode::OK && chain) {
             *chain = KeymasterCertificateChain(certChain);
         }
+        resultPromise.set_value(ret);
     };
-
-    auto hidlKey = blob2hidlVec(keyBlob);
     auto dev = mKeyStore->getDevice(keyBlob);
-    rc = KS_HANDLE_HIDL_ERROR(dev->attestKey(hidlKey, mutableParams.hidl_data(), hidlCb));
-    if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
-    }
-    *aidl_return = static_cast<int32_t>(error);
+    auto hidlKey = blob2hidlVec(keyBlob);
+    dev->attestKey(std::move(hidlKey), mutableParams.hidl_data(), worker_cb);
+
+    resultFuture.wait();
+    *aidl_return = static_cast<int32_t>(resultFuture.get());
     return Status::ok();
 }
 
@@ -1723,15 +1090,13 @@
     }
 
     // Generate temporary key.
-    sp<Keymaster> dev = mKeyStore->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
+    auto dev = mKeyStore->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
 
     if (!dev) {
         *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
         return Status::ok();
     }
 
-    KeyStoreServiceReturnCode error;
-    ::std::vector<uint8_t> hidlKey;
 
     AuthorizationSet keyCharacteristics;
     keyCharacteristics.push_back(TAG_PURPOSE, KeyPurpose::VERIFY);
@@ -1739,54 +1104,55 @@
     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);
-    auto generateHidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& hidlKeyBlob,
-                              const KeyCharacteristics&) {
-        error = ret;
-        if (!error.isOk()) {
-            return;
-        }
-        hidlKey = hidlKeyBlob;
-    };
 
-    rc = KS_HANDLE_HIDL_ERROR(dev->generateKey(keyCharacteristics.hidl_data(), generateHidlCb));
-    if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
-    }
-    if (!error.isOk()) {
-        *aidl_return = static_cast<int32_t>(error);
-        return Status::ok();
-    }
+    std::promise<KeyStoreServiceReturnCode> resultPromise;
+    auto resultFuture = resultPromise.get_future();
 
-    // Attest key and device IDs.
-    auto attestHidlCb = [&](ErrorCode ret, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
-        error = ret;
-        if (!error.isOk()) {
-            return;
-        }
-        *chain = ::android::security::keymaster::KeymasterCertificateChain(certChain);
-    };
-    KeyStoreServiceReturnCode attestationRc =
-        KS_HANDLE_HIDL_ERROR(dev->attestKey(hidlKey, mutableParams.hidl_data(), attestHidlCb));
+    dev->generateKey(
+        keyCharacteristics.hidl_data(),
+        [&, dev](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()) {
+                resultPromise.set_value(ResponseCode::SYSTEM_ERROR);
+                return;
+            }
+            if (ret != ErrorCode::OK) {
+                resultPromise.set_value(ret);
+                return;
+            }
+            dev->attestKey(
+                hidlKeyBlob, mutableParams.hidl_data(),
+                [&, dev,
+                 hidlKeyBlob](Return<void> rc,
+                              std::tuple<ErrorCode, hidl_vec<hidl_vec<uint8_t>>>&& hidlResult) {
+                    auto& [ret, certChain] = hidlResult;
+                    // shedule temp key for deletion
+                    dev->deleteKey(std::move(hidlKeyBlob), [](Return<ErrorCode> rc) {
+                        // log error but don't return an error
+                        KS_HANDLE_HIDL_ERROR(rc);
+                    });
+                    if (!rc.isOk()) {
+                        resultPromise.set_value(ResponseCode::SYSTEM_ERROR);
+                        return;
+                    }
+                    if (ret == ErrorCode::OK && chain) {
+                        *chain =
+                            ::android::security::keymaster::KeymasterCertificateChain(certChain);
+                    }
+                    resultPromise.set_value(ret);
+                });
+        });
 
-    // Delete temporary key.
-    KeyStoreServiceReturnCode deletionRc = KS_HANDLE_HIDL_ERROR(dev->deleteKey(hidlKey));
-
-    if (!attestationRc.isOk()) {
-        *aidl_return = static_cast<int32_t>(attestationRc);
-        return Status::ok();
-    }
-    if (!error.isOk()) {
-        *aidl_return = static_cast<int32_t>(error);
-        return Status::ok();
-    }
-    *aidl_return = static_cast<int32_t>(deletionRc);
+    resultFuture.wait();
+    *aidl_return = static_cast<int32_t>(resultFuture.get());
     return Status::ok();
 }
 
 Status KeyStoreService::onDeviceOffBody(int32_t* aidl_return) {
     // TODO(tuckeris): add permission check.  This should be callable from ClockworkHome only.
-    mAuthTokenTable.onDeviceOffBody();
+    mKeyStore->getAuthTokenTable().onDeviceOffBody();
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
     return Status::ok();
 }
@@ -1806,80 +1172,48 @@
         return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
     }
 
-    Blob wrappingKeyBlob;
     String8 wrappingKeyName8(wrappingKeyAlias);
-    KeyStoreServiceReturnCode rc =
-        mKeyStore->getKeyForName(&wrappingKeyBlob, wrappingKeyName8, callingUid, TYPE_KEYMASTER_10);
-    if (!rc.isOk()) {
+
+    KeyStoreServiceReturnCode rc;
+    Blob wrappingKeyBlob;
+    Blob wrappingCharBlob;
+    LockedKeyBlobEntry wrappingLockedEntry;
+
+    std::tie(rc, wrappingKeyBlob, wrappingCharBlob, wrappingLockedEntry) =
+        mKeyStore->getKeyForName(wrappingKeyName8, callingUid, TYPE_KEYMASTER_10);
+    if (!rc) {
         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);
     }
 
-    auto hidlWrappingKey = blob2hidlVec(wrappingKeyBlob);
-    String8 wrappedKeyAlias8(wrappedKeyAlias);
+    std::promise<KeyStoreServiceReturnCode> resultPromise;
+    auto resultFuture = resultPromise.get_future();
 
-    KeyStoreServiceReturnCode error;
+    dev->importWrappedKey(
+        std::move(wrappingLockedEntry), std::move(wrappedLockedEntry), wrappedKey, maskingKey,
+        params.getParameters(), std::move(wrappingKeyBlob), std::move(wrappingCharBlob), rootSid,
+        fingerprintSid, [&](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+            if (rc.isOk() && outCharacteristics) {
+                *outCharacteristics =
+                    ::android::security::keymaster::KeyCharacteristics(keyCharacteristics);
+            }
+            resultPromise.set_value(rc);
+        });
 
-    auto hidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& keyBlob,
-                      const KeyCharacteristics& keyCharacteristics) {
-        error = ret;
-        if (!error.isOk()) {
-            return;
-        }
-        if (outCharacteristics) {
-            *outCharacteristics =
-                ::android::security::keymaster::KeyCharacteristics(keyCharacteristics);
-        }
-
-        // Write the key:
-        String8 filename(
-            mKeyStore->getKeyNameForUidWithDir(wrappedKeyAlias8, callingUid, ::TYPE_KEYMASTER_10));
-
-        Blob ksBlob(&keyBlob[0], keyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
-        ksBlob.setSecurityLevel(securityLevel);
-
-        if (containsTag(keyCharacteristics.hardwareEnforced, Tag::USER_SECURE_ID)) {
-            ksBlob.setSuperEncrypted(true);
-        }
-
-        error = mKeyStore->put(filename.string(), &ksBlob, get_user_id(callingUid));
-    };
-
-    rc = KS_HANDLE_HIDL_ERROR(dev->importWrappedKey(wrappedKey, hidlWrappingKey, maskingKey,
-                                                    params.getParameters(), rootSid, fingerprintSid,
-                                                    hidlCb));
-
-    // possible hidl error
-    if (!rc.isOk()) {
-        return AIDL_RETURN(rc);
-    }
-    // now check error from callback
-    if (!error.isOk()) {
-        return AIDL_RETURN(error);
-    }
-
-    // Write the characteristics:
-    String8 cFilename(mKeyStore->getKeyNameForUidWithDir(wrappedKeyAlias8, callingUid,
-                                                         ::TYPE_KEY_CHARACTERISTICS));
-
-    AuthorizationSet opParams = params.getParameters();
-    std::stringstream kcStream;
-    opParams.Serialize(&kcStream);
-    if (kcStream.bad()) {
-        return AIDL_RETURN(ResponseCode::SYSTEM_ERROR);
-    }
-    auto kcBuf = kcStream.str();
-
-    Blob charBlob(reinterpret_cast<const uint8_t*>(kcBuf.data()), kcBuf.size(), nullptr, 0,
-                  ::TYPE_KEY_CHARACTERISTICS);
-    charBlob.setSecurityLevel(securityLevel);
-
-    return AIDL_RETURN(mKeyStore->put(cFilename.string(), &charBlob, get_user_id(callingUid)));
+    resultFuture.wait();
+    return AIDL_RETURN(resultFuture.get());
 }
 
 Status KeyStoreService::presentConfirmationPrompt(const sp<IBinder>& listener,
@@ -1887,35 +1221,17 @@
                                                   const ::std::vector<uint8_t>& extraData,
                                                   const String16& locale, int32_t uiOptionsAsFlags,
                                                   int32_t* aidl_return) {
-    return mConfirmationManager->presentConfirmationPrompt(listener, promptText, extraData, locale,
-                                                           uiOptionsAsFlags, 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 mConfirmationManager->cancelConfirmationPrompt(listener, aidl_return);
+    return mKeyStore->getConfirmationManager().cancelConfirmationPrompt(listener, aidl_return);
 }
 
 Status KeyStoreService::isConfirmationPromptSupported(bool* aidl_return) {
-    return mConfirmationManager->isConfirmationPromptSupported(aidl_return);
-}
-
-/**
- * Prune the oldest pruneable operation.
- */
-bool KeyStoreService::pruneOperation() {
-    sp<IBinder> oldest = mOperationMap.getOldestPruneableOperation();
-    ALOGD("Trying to prune operation %p", oldest.get());
-    size_t op_count_before_abort = mOperationMap.getOperationCount();
-    // We mostly ignore errors from abort() because all we care about is whether at least
-    // one operation has been removed.
-    int32_t abort_error;
-    abort(oldest, &abort_error);
-    if (mOperationMap.getOperationCount() >= op_count_before_abort) {
-        ALOGE("Failed to abort pruneable operation %p, error: %d", oldest.get(), abort_error);
-        return false;
-    }
-    return true;
+    return mKeyStore->getConfirmationManager().isConfirmationPromptSupported(aidl_return);
 }
 
 /**
@@ -2028,293 +1344,9 @@
     return true;
 }
 
-ErrorCode KeyStoreService::getOperationCharacteristics(const hidl_vec<uint8_t>& key,
-                                                       sp<Keymaster>* dev,
-                                                       const AuthorizationSet& params,
-                                                       KeyCharacteristics* out) {
-    ::std::vector<uint8_t> clientId;
-    ::std::vector<uint8_t> appData;
-    for (auto param : params) {
-        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();
-        }
-    }
-    ErrorCode error = ErrorCode::OK;
-
-    auto hidlCb = [&](ErrorCode ret, const KeyCharacteristics& keyCharacteristics) {
-        error = ret;
-        if (error != ErrorCode::OK) {
-            return;
-        }
-        if (out) *out = keyCharacteristics;
-    };
-
-    ErrorCode rc =
-        KS_HANDLE_HIDL_ERROR((*dev)->getKeyCharacteristics(key, clientId, appData, hidlCb));
-    if (rc != ErrorCode::OK) {
-        return rc;
-    }
-    return error;
-}
-
-/**
- * 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>
-KeyStoreService::getAuthToken(const KeyCharacteristics& characteristics, uint64_t handle,
-                              KeyPurpose purpose, bool failOnTokenMissing) {
-
-    AuthorizationSet allCharacteristics(characteristics.softwareEnforced);
-    allCharacteristics.append(characteristics.hardwareEnforced.begin(),
-                              characteristics.hardwareEnforced.end());
-
-    const HardwareAuthToken* authToken = nullptr;
-    AuthTokenTable::Error err = mAuthTokenTable.FindAuthorization(
-        allCharacteristics, static_cast<KeyPurpose>(purpose), handle, &authToken);
-
-    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, authToken ? std::move(*authToken) : HardwareAuthToken()};
-}
-
-/**
- * Add the auth token for the operation to the param list if the operation
- * requires authorization. Uses the cached result in the OperationMap if available
- * otherwise gets the token from the AuthTokenTable and caches the result.
- *
- * Returns ResponseCode::NO_ERROR if the auth token was added or not needed.
- *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not
- *         authenticated.
- *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid
- *         operation token.
- */
-std::pair<KeyStoreServiceReturnCode, const HardwareAuthToken&>
-KeyStoreService::getOperationAuthTokenIfNeeded(const sp<IBinder>& token) {
-    static HardwareAuthToken emptyToken = {};
-
-    auto getOpResult = mOperationMap.getOperation(token);
-    if (!getOpResult.isOk()) return {ErrorCode::INVALID_OPERATION_HANDLE, emptyToken};
-    const auto& op = getOpResult.value();
-
-    if (!op.hasAuthToken()) {
-        KeyStoreServiceReturnCode rc;
-        HardwareAuthToken found;
-        std::tie(rc, found) = getAuthToken(op.characteristics, op.handle, op.purpose);
-        if (!rc.isOk()) return {rc, emptyToken};
-        mOperationMap.setOperationAuthToken(token, std::move(found));
-    }
-
-    return {ResponseCode::NO_ERROR, op.authToken};
-}
-
-/**
- * Translate a result value to a legacy return value. All keystore errors are
- * preserved and keymaster errors become SYSTEM_ERRORs
- */
-KeyStoreServiceReturnCode KeyStoreService::translateResultToLegacyResult(int32_t result) {
-    if (result > 0) return static_cast<ResponseCode>(result);
-    return ResponseCode::SYSTEM_ERROR;
-}
-
-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 {};
-}
-
-void KeyStoreService::addLegacyBeginParams(const String16& name, AuthorizationSet* params) {
-    // All legacy keys are DIGEST_NONE/PAD_NONE.
-    params->push_back(TAG_DIGEST, Digest::NONE);
-    params->push_back(TAG_PADDING, PaddingMode::NONE);
-
-    // Look up the algorithm of the key.
-    ::android::security::keymaster::KeyCharacteristics characteristics;
-    int32_t result;
-    auto rc = getKeyCharacteristics(name, ::android::security::keymaster::KeymasterBlob(),
-                                    ::android::security::keymaster::KeymasterBlob(), UID_SELF,
-                                    &characteristics, &result);
-    if (!rc.isOk()) {
-        ALOGE("Failed to get key characteristics");
-        return;
-    }
-    auto algorithm = getKeyAlgoritmFromKeyCharacteristics(characteristics);
-    if (!algorithm.isOk()) {
-        ALOGE("getKeyCharacteristics did not include KM_TAG_ALGORITHM");
-        return;
-    }
-    params->push_back(TAG_ALGORITHM, algorithm.value());
-}
-
-KeyStoreServiceReturnCode KeyStoreService::doLegacySignVerify(const String16& name,
-                                                              const hidl_vec<uint8_t>& data,
-                                                              hidl_vec<uint8_t>* out,
-                                                              const hidl_vec<uint8_t>& signature,
-                                                              KeyPurpose purpose) {
-
-    std::basic_stringstream<uint8_t> outBuffer;
-    OperationResult result;
-    AuthorizationSet inArgs;
-    addLegacyBeginParams(name, &inArgs);
-    sp<IBinder> appToken(new BBinder);
-    sp<IBinder> token;
-
-    begin(appToken, name, static_cast<int32_t>(purpose), true,
-          KeymasterArguments(inArgs.hidl_data()), ::std::vector<uint8_t>(), UID_SELF, &result);
-    if (!result.resultCode.isOk()) {
-        if (result.resultCode == ResponseCode::KEY_NOT_FOUND) {
-            ALOGW("Key not found");
-        } else {
-            ALOGW("Error in begin: %d", int32_t(result.resultCode));
-        }
-        return translateResultToLegacyResult(result.resultCode);
-    }
-    inArgs.Clear();
-    token = result.token;
-    size_t consumed = 0;
-    size_t lastConsumed = 0;
-    hidl_vec<uint8_t> data_view;
-    do {
-        data_view.setToExternal(const_cast<uint8_t*>(&data[consumed]), data.size() - consumed);
-        update(token, KeymasterArguments(inArgs.hidl_data()), data_view, &result);
-        if (result.resultCode != ResponseCode::NO_ERROR) {
-            ALOGW("Error in update: %d", int32_t(result.resultCode));
-            return translateResultToLegacyResult(result.resultCode);
-        }
-        if (out) {
-            outBuffer.write(&result.data[0], result.data.size());
-        }
-        lastConsumed = result.inputConsumed;
-        consumed += lastConsumed;
-    } while (consumed < data.size() && lastConsumed > 0);
-
-    if (consumed != data.size()) {
-        ALOGW("Not all data consumed. Consumed %zu of %zu", consumed, data.size());
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    finish(token, KeymasterArguments(inArgs.hidl_data()), signature, ::std::vector<uint8_t>(),
-           &result);
-    if (result.resultCode != ResponseCode::NO_ERROR) {
-        ALOGW("Error in finish: %d", int32_t(result.resultCode));
-        return translateResultToLegacyResult(result.resultCode);
-    }
-    if (out) {
-        outBuffer.write(&result.data[0], result.data.size());
-    }
-
-    if (out) {
-        auto buf = outBuffer.str();
-        out->resize(buf.size());
-        memcpy(&(*out)[0], buf.data(), out->size());
-    }
-
-    return ResponseCode::NO_ERROR;
-}
-
-KeyStoreServiceReturnCode KeyStoreService::upgradeKeyBlob(const String16& name, uid_t uid,
-                                                          const AuthorizationSet& params,
-                                                          Blob* blob) {
-    // Read the blob rather than assuming the caller provided the right name/uid/blob triplet.
-    String8 name8(name);
-    KeyStoreServiceReturnCode responseCode =
-        mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
-    if (responseCode != ResponseCode::NO_ERROR) {
-        return responseCode;
-    }
-    ALOGI("upgradeKeyBlob %s %d", name8.string(), uid);
-
-    auto hidlKey = blob2hidlVec(*blob);
-    auto dev = mKeyStore->getDevice(*blob);
-
-    KeyStoreServiceReturnCode error;
-    auto hidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& upgradedKeyBlob) {
-        error = ret;
-        if (!error.isOk()) {
-            if (error == ErrorCode::INVALID_KEY_BLOB) {
-                log_key_integrity_violation(name8, uid);
-            }
-            return;
-        }
-
-        auto filename = mKeyStore->getBlobFileNameIfExists(name8, uid, ::TYPE_KEYMASTER_10);
-        if (!filename.isOk()) {
-            ALOGI("trying to upgrade a non existing blob");
-            return;
-        }
-        error = mKeyStore->del(filename.value().string(), ::TYPE_ANY, get_user_id(uid));
-        if (!error.isOk()) {
-            ALOGI("upgradeKeyBlob keystore->del failed %d", (int)error);
-            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 = mKeyStore->put(filename.value().string(), &newBlob, get_user_id(uid));
-        if (!error.isOk()) {
-            ALOGI("upgradeKeyBlob keystore->put failed %d", (int)error);
-            return;
-        }
-
-        // Re-read blob for caller.  We can't use newBlob because writing it modified it.
-        error = mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
-    };
-
-    KeyStoreServiceReturnCode rc =
-        KS_HANDLE_HIDL_ERROR(dev->upgradeKey(hidlKey, params.hidl_data(), hidlCb));
-    if (!rc.isOk()) {
-        return rc;
-    }
-
-    return error;
-}
-
 Status KeyStoreService::onKeyguardVisibilityChanged(bool isShowing, int32_t userId,
                                                     int32_t* aidl_return) {
-    enforcement_policy.set_device_locked(isShowing, userId);
+    mKeyStore->getEnforcementPolicy().set_device_locked(isShowing, userId);
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
 
     return Status::ok();
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index 8d3f1f2..29369d0 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -27,6 +27,14 @@
 #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>
+
 namespace keystore {
 
 // Class provides implementation for generated BnKeystoreService.h based on
@@ -34,12 +42,9 @@
 // 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::BnKeystoreService,
-                        android::IBinder::DeathRecipient {
+class KeyStoreService : public android::security::BnKeystoreService {
   public:
-    explicit KeyStoreService(KeyStore* keyStore)
-        : mKeyStore(keyStore), mOperationMap(this),
-          mConfirmationManager(new ConfirmationManager(this)) {}
+    explicit KeyStoreService(sp<KeyStore> keyStore) : mKeyStore(keyStore) {}
     virtual ~KeyStoreService() = default;
 
     void binderDied(const android::wp<android::IBinder>& who);
@@ -64,33 +69,6 @@
     ::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 generate(const ::android::String16& name, int32_t uid,
-                                       int32_t keyType, int32_t keySize, int32_t flags,
-                                       const ::android::security::KeystoreArguments& args,
-                                       int32_t* _aidl_return) override;
-    ::android::binder::Status import_key(const ::android::String16& name,
-                                         const ::std::vector<uint8_t>& data, int32_t uid,
-                                         int32_t flags, int32_t* _aidl_return) override;
-    ::android::binder::Status sign(const ::android::String16& name,
-                                   const ::std::vector<uint8_t>& data,
-                                   ::std::vector<uint8_t>* _aidl_return) override;
-    ::android::binder::Status verify(const ::android::String16& name,
-                                     const ::std::vector<uint8_t>& data,
-                                     const ::std::vector<uint8_t>& signature,
-                                     int32_t* _aidl_return) override;
-    /*
-     * TODO: The abstraction between things stored in hardware and regular blobs
-     * of data stored on the filesystem should be moved down to keystore itself.
-     * Unfortunately the Java code that calls this has naming conventions that it
-     * knows about. Ideally keystore shouldn't be used to store random blobs of
-     * data.
-     *
-     * Until that happens, it's necessary to have a separate "get_pubkey" and
-     * "del_key" since the Java code doesn't really communicate what it's
-     * intentions are.
-     */
-    ::android::binder::Status get_pubkey(const ::android::String16& name,
-                                         ::std::vector<uint8_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,
@@ -143,8 +121,6 @@
            ::android::security::keymaster::OperationResult* _aidl_return) override;
     ::android::binder::Status abort(const ::android::sp<::android::IBinder>& handle,
                                     int32_t* _aidl_return) override;
-    ::android::binder::Status isOperationAuthorized(const ::android::sp<::android::IBinder>& token,
-                                                    bool* _aidl_return) override;
     ::android::binder::Status addAuthToken(const ::std::vector<uint8_t>& authToken,
                                            int32_t* _aidl_return) override;
     ::android::binder::Status onUserAdded(int32_t userId, int32_t parentId,
@@ -178,17 +154,12 @@
     ::android::binder::Status isConfirmationPromptSupported(bool* _aidl_return) override;
 
     ::android::binder::Status onKeyguardVisibilityChanged(bool isShowing, int32_t userId,
-                                                          int32_t* _aidl_return);
+                                                          int32_t* _aidl_return) override;
 
   private:
     static const int32_t UID_SELF = -1;
 
     /**
-     * Prune the oldest pruneable operation.
-     */
-    bool pruneOperation();
-
-    /**
      * Get the effective target uid for a binder operation that takes an
      * optional uid as the target.
      */
@@ -235,41 +206,6 @@
      */
     bool checkAllowedOperationParams(const hidl_vec<KeyParameter>& params);
 
-    ErrorCode getOperationCharacteristics(const hidl_vec<uint8_t>& key, sp<Keymaster>* dev,
-                                          const AuthorizationSet& params, KeyCharacteristics* out);
-
-    /**
-     * 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);
-
-    /**
-     * Get the auth token for the operation if the operation requires authorization. Uses the cached
-     * result in the OperationMap if available otherwise gets the token from the AuthTokenTable and
-     * caches the result.
-     *
-     * Returns NO_ERROR if the auth token was found or not needed.  If not needed, the token will
-     *             be empty (which keymaster interprets as no auth token).
-     *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not authenticated.
-     *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid operation token.
-     */
-    std::pair<KeyStoreServiceReturnCode, const HardwareAuthToken&>
-    getOperationAuthTokenIfNeeded(const sp<android::IBinder>& token);
-
-    /**
-     * Translate a result value to a legacy return value. All keystore errors are
-     * preserved and keymaster errors become SYSTEM_ERRORs
-     */
-    KeyStoreServiceReturnCode translateResultToLegacyResult(int32_t result);
-
     void addLegacyBeginParams(const android::String16& name, AuthorizationSet* params);
 
     KeyStoreServiceReturnCode doLegacySignVerify(const android::String16& name,
@@ -279,27 +215,32 @@
                                                  KeyPurpose purpose);
 
     /**
-     * Upgrade a key blob under alias "name", returning the new blob in "blob".  If "blob"
-     * previously contained data, it will be overwritten.
-     *
-     * Returns ::NO_ERROR if the key was upgraded successfully.
-     *         KM_ERROR_VERSION_MISMATCH if called on a key whose patch level is greater than or
-     *         equal to the current system patch level.
-     */
-    KeyStoreServiceReturnCode upgradeKeyBlob(const android::String16& name, uid_t targetUid,
-                                             const AuthorizationSet& params, Blob* blob);
-
-    /**
      * Adds a Confirmation Token to the key parameters if needed.
      */
     void appendConfirmationTokenIfNeeded(const KeyCharacteristics& keyCharacteristics,
                                          std::vector<KeyParameter>* params);
 
-    KeyStore* mKeyStore;
-    OperationMap mOperationMap;
-    android::sp<ConfirmationManager> mConfirmationManager;
-    keystore::AuthTokenTable mAuthTokenTable;
-    KeystoreKeymasterEnforcement enforcement_policy;
+    sp<KeyStore> mKeyStore;
+
+    std::mutex operationDeviceMapMutex_;
+    std::map<sp<IBinder>, std::shared_ptr<KeymasterWorker>> operationDeviceMap_;
+
+    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);
+    }
 };
 
 };  // namespace keystore
diff --git a/keystore/keymaster_enforcement.cpp b/keystore/keymaster_enforcement.cpp
index 1a7fa80..a17cd94 100644
--- a/keystore/keymaster_enforcement.cpp
+++ b/keystore/keymaster_enforcement.cpp
@@ -34,49 +34,6 @@
 
 namespace keystore {
 
-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:
-    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:
-    struct AccessCount {
-        km_id_t keyid;
-        uint64_t access_count;
-    };
-    std::list<AccessCount> access_count_list_;
-    const uint32_t max_size_;
-};
-
 bool is_public_key_algorithm(const AuthorizationSet& auth_set) {
     auto algorithm = auth_set.GetTagValue(TAG_ALGORITHM);
     return algorithm.isOk() &&
@@ -107,12 +64,9 @@
 
 KeymasterEnforcement::KeymasterEnforcement(uint32_t max_access_time_map_size,
                                            uint32_t max_access_count_map_size)
-    : access_time_map_(new (std::nothrow) AccessTimeMap(max_access_time_map_size)),
-      access_count_map_(new (std::nothrow) AccessCountMap(max_access_count_map_size)) {}
+    : access_time_map_(max_access_time_map_size), access_count_map_(max_access_count_map_size) {}
 
 KeymasterEnforcement::~KeymasterEnforcement() {
-    delete access_time_map_;
-    delete access_count_map_;
 }
 
 ErrorCode KeymasterEnforcement::AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid,
@@ -390,24 +344,14 @@
         return ErrorCode::CALLER_NONCE_PROHIBITED;
 
     if (min_ops_timeout != UINT32_MAX) {
-        if (!access_time_map_) {
-            ALOGE("Rate-limited keys table not allocated.  Rate-limited keys disabled");
-            return ErrorCode::MEMORY_ALLOCATION_FAILED;
-        }
-
-        if (!access_time_map_->UpdateKeyAccessTime(keyid, get_current_time(), min_ops_timeout)) {
+        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_) {
-            ALOGE("Usage-count limited keys tabel not allocated.  Count-limited keys disabled");
-            return ErrorCode::MEMORY_ALLOCATION_FAILED;
-        }
-
-        if (!access_count_map_->IncrementKeyAccessCount(keyid)) {
+        if (!access_count_map_.IncrementKeyAccessCount(keyid)) {
             ALOGE("Usage count-limited keys table full, until reboot.");
             return ErrorCode::TOO_MANY_OPERATIONS;
         }
@@ -428,35 +372,32 @@
 };
 
 /* static */
-bool KeymasterEnforcement::CreateKeyId(const hidl_vec<uint8_t>& key_blob, km_id_t* keyid) {
+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 true;
+        assert(hash_len >= sizeof(keyid));
+        memcpy(&keyid, hash, sizeof(keyid));
+        return keyid;
     }
 
-    return false;
+    return {};
 }
 
 bool KeymasterEnforcement::MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid) {
-    if (!access_time_map_) return false;
-
     uint32_t last_access_time;
-    if (!access_time_map_->LastKeyAccessTime(keyid, &last_access_time)) return true;
+    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) {
-    if (!access_count_map_) return false;
-
     uint32_t key_access_count;
-    if (!access_count_map_->KeyAccessCount(keyid, &key_access_count)) return true;
+    if (!access_count_map_.KeyAccessCount(keyid, &key_access_count)) return true;
     return key_access_count < max_uses;
 }
 
@@ -545,6 +486,7 @@
 }
 
 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;
@@ -554,6 +496,7 @@
 }
 
 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;
@@ -579,6 +522,7 @@
 }
 
 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;
@@ -588,6 +532,7 @@
 }
 
 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
diff --git a/keystore/keymaster_enforcement.h b/keystore/keymaster_enforcement.h
index 6e6c54f..9bfb225 100644
--- a/keystore/keymaster_enforcement.h
+++ b/keystore/keymaster_enforcement.h
@@ -21,6 +21,10 @@
 
 #include <keystore/keymaster_types.h>
 
+#include <list>
+#include <mutex>
+#include <optional>
+
 namespace keystore {
 
 typedef uint64_t km_id_t;
@@ -33,8 +37,50 @@
      */
 };
 
-class AccessTimeMap;
-class AccessCountMap;
+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:
@@ -92,7 +138,7 @@
      *
      * Returns false if an error in the crypto library prevents creation of an ID.
      */
-    static bool CreateKeyId(const hidl_vec<uint8_t>& key_blob, km_id_t* keyid);
+    static std::optional<km_id_t> CreateKeyId(const hidl_vec<uint8_t>& key_blob);
 
     //
     // Methods that must be implemented by subclasses
@@ -158,8 +204,8 @@
                           const int auth_timeout_index, const uint64_t op_handle,
                           bool is_begin_operation) const;
 
-    AccessTimeMap* access_time_map_;
-    AccessCountMap* access_count_map_;
+    AccessTimeMap access_time_map_;
+    AccessCountMap access_count_map_;
 };
 
 }; /* namespace keystore */
diff --git a/keystore/keymaster_worker.cpp b/keystore/keymaster_worker.cpp
new file mode 100644
index 0000000..1002b8d
--- /dev/null
+++ b/keystore/keymaster_worker.cpp
@@ -0,0 +1,1074 @@
+/*
+**
+** 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 "KeyStore.h"
+#include "keymaster_enforcement.h"
+
+#include "key_proto_handler.h"
+#include "keystore_utils.h"
+
+namespace keystore {
+
+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_ = std::thread([this] {
+        std::unique_lock<std::mutex> lock(pending_requests_mutex_);
+        running_ = true;
+        while (running_) {
+            pending_requests_cond_var_.wait(
+                lock, [this]() { return !pending_requests_.empty() || !running_; });
+            if (!running_) break;
+            auto request = std::move(pending_requests_.front());
+            pending_requests_.pop();
+            lock.unlock();
+            request();
+            lock.lock();
+        }
+    });
+}
+Worker::~Worker() {
+    if (worker_.joinable()) {
+        running_ = false;
+        pending_requests_cond_var_.notify_all();
+        worker_.join();
+    }
+}
+void Worker::addRequest(WorkerTask request) {
+    std::unique_lock<std::mutex> lock(pending_requests_mutex_);
+    pending_requests_.push(std::move(request));
+    lock.unlock();
+    pending_requests_cond_var_.notify_all();
+}
+
+KeymasterWorker::KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore)
+    : keymasterDevice_(std::move(keymasterDevice)), operationMap_(keyStore), keyStore_(keyStore) {
+    // make sure that hal version is cached.
+    if (keymasterDevice_) keymasterDevice_->halVersion();
+}
+
+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());
+
+    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) {
+        error = ret;
+        if (!error.isOk()) {
+            if (error == ErrorCode::INVALID_KEY_BLOB) {
+                log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
+            }
+            return;
+        }
+
+        error = keyStore_->del(lockedEntry);
+        if (!error.isOk()) {
+            ALOGI("upgradeKeyBlob keystore->del failed %d", (int)error);
+            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", (int)error);
+            return;
+        }
+        blob = std::move(newBlob);
+    };
+
+    KeyStoreServiceReturnCode error2;
+    error2 = KS_HANDLE_HIDL_ERROR(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) {
+        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->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->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) {
+    auto op = operationMap_.removeOperation(token, false /* wasOpSuccessful */);
+    if (op) {
+        keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
+        return KS_HANDLE_HIDL_ERROR(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);
+    if (operationMap_.getOperationCount() >= op_count_before_abort) {
+        ALOGE("Failed to abort pruneable operation %p, error: %d", oldest.get(), int32_t(rc));
+        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 key = blob2hidlVec(keyBlob);
+        auto& dev = keymasterDevice_;
+
+        KeyCharacteristics characteristics;
+
+        {
+            hidl_vec<uint8_t> clientId;
+            hidl_vec<uint8_t> appData;
+            for (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->addRngEntropy(entropy));
+            if (!rc.isOk()) {
+                return worker_cb(operationFailed(rc));
+            }
+        }
+
+        // Create a keyid for this key.
+        auto keyid = KeymasterEnforcement::CreateKeyId(key);
+        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) {
+            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->begin(purpose, key, 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:
+    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);
+            keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
+            KS_HANDLE_HIDL_ERROR(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) {
+            result.resultCode = ret;
+            if (result.resultCode.isOk()) {
+                result.inputConsumed = inputConsumed;
+                result.outParams = outParams;
+                result.data = output;
+            }
+        };
+
+        rc = KS_HANDLE_HIDL_ERROR(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());
+            keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
+            if (!finished) KS_HANDLE_HIDL_ERROR(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->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) {
+            result.resultCode = ret;
+            if (result.resultCode.isOk()) {
+                result.outParams = outParams;
+                result.data = output;
+            }
+        };
+
+        rc = KS_HANDLE_HIDL_ERROR(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)); });
+}
+
+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_->verifyAuthorization(
+            challenge, params, token, [&](ErrorCode error_, const VerificationToken& vToken) {
+                error = error_;
+                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_->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(
+            [&] { uploadKeyCharacteristicsAsProto(keyParams, false /* wasCreationSuccessful */); });
+
+        KeyCharacteristics outCharacteristics;
+        KeyStoreServiceReturnCode error;
+        auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
+                           const KeyCharacteristics& keyCharacteristics) {
+            error = ret;
+            if (!error.isOk()) {
+                return;
+            }
+            consider_fallback = false;
+            outCharacteristics = keyCharacteristics;
+
+            Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
+            keyBlob.setSecurityLevel(securityLevel);
+            keyBlob.setCriticalToDeviceEncryption(flags &
+                                                  KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
+            if (isAuthenticationBound(keyParams) && !keyBlob.isCriticalToDeviceEncryption()) {
+                keyBlob.setSuperEncrypted(true);
+            }
+            keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
+
+            AuthorizationSet sw_enforced = keyParams;
+            sw_enforced.Subtract(outCharacteristics.hardwareEnforced);
+            sw_enforced.Union(outCharacteristics.softwareEnforced);
+            sw_enforced.Filter([](const KeyParameter& param) -> bool {
+                return !(param.tag == Tag::APPLICATION_DATA || param.tag == Tag::APPLICATION_ID);
+            });
+            if (!sw_enforced.Contains(Tag::USER_ID)) {
+                // Most Java processes don't have access to this tag
+                sw_enforced.push_back(keymaster::TAG_USER_ID, get_user_id(lockedEntry->uid()));
+            }
+            Blob keyCharBlob;
+            keyCharBlob.putKeyCharacteristics(outCharacteristics.hardwareEnforced, sw_enforced);
+            error = keyStore_->put(lockedEntry, std::move(keyBlob), std::move(keyCharBlob));
+        };
+
+        rc = KS_HANDLE_HIDL_ERROR(keymasterDevice_->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();
+        uploadKeyCharacteristicsAsProto(keyParams, true /* wasCreationSuccessful */);
+
+        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;
+
+        Finalize logOnFail(
+            [&] { uploadKeyCharacteristicsAsProto(keyParams, false /* wasCreationSuccessful */); });
+
+        KeyCharacteristics outCharacteristics;
+        KeyStoreServiceReturnCode error;
+        auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
+                           const KeyCharacteristics& keyCharacteristics) {
+            error = ret;
+            if (!error.isOk()) {
+                LOG(INFO) << "importKey failed";
+                return;
+            }
+            consider_fallback = false;
+            outCharacteristics = keyCharacteristics;
+
+            Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
+            keyBlob.setSecurityLevel(securityLevel);
+            keyBlob.setCriticalToDeviceEncryption(flags &
+                                                  KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
+            if (isAuthenticationBound(keyParams) && !keyBlob.isCriticalToDeviceEncryption()) {
+                keyBlob.setSuperEncrypted(true);
+            }
+            keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
+
+            AuthorizationSet sw_enforced = keyParams;
+            sw_enforced.Subtract(outCharacteristics.hardwareEnforced);
+            sw_enforced.Union(outCharacteristics.softwareEnforced);
+            sw_enforced.Filter([](const KeyParameter& param) -> bool {
+                return !(param.tag == Tag::APPLICATION_DATA || param.tag == Tag::APPLICATION_ID);
+            });
+            if (!sw_enforced.Contains(Tag::USER_ID)) {
+                // Most Java processes don't have access to this tag
+                sw_enforced.push_back(keymaster::TAG_USER_ID, get_user_id(lockedEntry->uid()));
+            }
+            Blob keyCharBlob;
+            keyCharBlob.putKeyCharacteristics(outCharacteristics.hardwareEnforced, sw_enforced);
+            error = keyStore_->put(lockedEntry, std::move(keyBlob), std::move(keyCharBlob));
+        };
+
+        KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
+            keymasterDevice_->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();
+        uploadKeyCharacteristicsAsProto(keyParams, true /* wasCreationSuccessful */);
+
+        return worker_cb(error, std::move(outCharacteristics));
+    });
+}
+
+void KeymasterWorker::importWrappedKey(LockedKeyBlobEntry wrappingLockedEntry,
+                                       LockedKeyBlobEntry wrapppedLockedEntry,
+                                       hidl_vec<uint8_t> wrappedKeyData,
+                                       hidl_vec<uint8_t> maskingKey,
+                                       hidl_vec<KeyParameter> unwrappingParams, Blob wrappingBlob,
+                                       Blob wrappingCharBlob, uint64_t passwordSid,
+                                       uint64_t biometricSid, importWrappedKey_cb worker_cb) {
+    Worker::addRequest([this, CAPTURE_MOVE(wrappingLockedEntry), CAPTURE_MOVE(wrapppedLockedEntry),
+                        CAPTURE_MOVE(wrappedKeyData), CAPTURE_MOVE(maskingKey),
+                        CAPTURE_MOVE(unwrappingParams), CAPTURE_MOVE(wrappingBlob),
+                        CAPTURE_MOVE(wrappingCharBlob), passwordSid, biometricSid,
+                        CAPTURE_MOVE(worker_cb)]() mutable {
+        auto hidlWrappingKey = blob2hidlVec(wrappingBlob);
+
+        SecurityLevel securityLevel = keymasterDevice_->halVersion().securityLevel;
+
+        KeyCharacteristics outCharacteristics;
+        KeyStoreServiceReturnCode error;
+
+        auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
+                          const KeyCharacteristics& keyCharacteristics) {
+            error = ret;
+            if (!error.isOk()) {
+                return;
+            }
+            outCharacteristics = keyCharacteristics;
+
+            Blob keyBlob(hidlKeyBlob.data(), hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
+            keyBlob.setSecurityLevel(securityLevel);
+            if (isAuthenticationBound(keyCharacteristics.hardwareEnforced)) {
+                keyBlob.setSuperEncrypted(true);
+            }
+
+            AuthorizationSet sw_enforced = outCharacteristics.softwareEnforced;
+            if (!sw_enforced.Contains(Tag::USER_ID)) {
+                // Most Java processes don't have access to this tag
+                sw_enforced.push_back(keymaster::TAG_USER_ID,
+                                      get_user_id(wrapppedLockedEntry->uid()));
+            }
+            Blob keyCharBlob;
+            keyCharBlob.putKeyCharacteristics(outCharacteristics.hardwareEnforced, sw_enforced);
+            error = keyStore_->put(wrapppedLockedEntry, std::move(keyBlob), std::move(keyCharBlob));
+        };
+
+        KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(keymasterDevice_->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_->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) {
+            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_->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_->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::upgradeKey(hidl_vec<uint8_t> keyBlobToUpgrade,
+                                 hidl_vec<KeyParameter> upgradeParams, upgradeKey_cb _hidl_cb) {
+    addRequest(&Keymaster::upgradeKey, std::move(_hidl_cb), std::move(keyBlobToUpgrade),
+               std::move(upgradeParams));
+}
+
+void KeymasterWorker::deleteKey(hidl_vec<uint8_t> keyBlob, deleteKey_cb _hidl_cb) {
+    addRequest(&Keymaster::deleteKey, std::move(_hidl_cb), std::move(keyBlob));
+}
+void KeymasterWorker::deleteAllKeys(deleteAllKeys_cb _hidl_cb) {
+    addRequest(&Keymaster::deleteAllKeys, std::move(_hidl_cb));
+}
+void KeymasterWorker::destroyAttestationIds(destroyAttestationIds_cb _hidl_cb) {
+    addRequest(&Keymaster::destroyAttestationIds, move(_hidl_cb));
+}
+
+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);
+        }
+    });
+}
+
+}  // namespace keystore
diff --git a/keystore/keymaster_worker.h b/keystore/keymaster_worker.h
new file mode 100644
index 0000000..b39ae83
--- /dev/null
+++ b/keystore/keymaster_worker.h
@@ -0,0 +1,306 @@
+/*
+**
+** 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_0/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/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_0::ErrorCode;
+using android::hardware::keymaster::V4_0::HardwareAuthToken;
+using android::hardware::keymaster::V4_0::HmacSharingParameters;
+using android::hardware::keymaster::V4_0::KeyCharacteristics;
+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::VerificationToken;
+using android::hardware::keymaster::V4_0::support::Keymaster;
+// using KeystoreCharacteristics = ::android::security::keymaster::KeyCharacteristics;
+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;
+        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_;
+    std::thread worker_;
+    bool running_ = false;
+
+  public:
+    Worker();
+    ~Worker();
+    void addRequest(WorkerTask request);
+};
+
+template <typename... Args> struct MakeKeymasterWorkerCB;
+
+template <typename ErrorType, typename... Args>
+struct MakeKeymasterWorkerCB<ErrorType, std::function<void(Args...)>> {
+    using type = std::function<void(ErrorType, std::tuple<std::decay_t<Args>...>&&)>;
+};
+
+template <typename ErrorType> struct MakeKeymasterWorkerCB<ErrorType> {
+    using type = std::function<void(ErrorType)>;
+};
+
+template <typename... Args>
+using MakeKeymasterWorkerCB_t = typename MakeKeymasterWorkerCB<Args...>::type;
+
+class KeymasterWorker : protected Worker {
+  private:
+    sp<Keymaster> keymasterDevice_;
+    OperationMap operationMap_;
+    KeyStore* keyStore_;
+
+    template <typename KMFn, typename ErrorType, typename... Args, size_t... I>
+    void unwrap_tuple(KMFn kmfn, std::function<void(ErrorType)> cb,
+                      const std::tuple<Args...>& tuple, std::index_sequence<I...>) {
+        cb(((*keymasterDevice_).*kmfn)(std::get<I>(tuple)...));
+    }
+
+    template <typename KMFn, typename ErrorType, typename... ReturnTypes, typename... Args,
+              size_t... I>
+    void unwrap_tuple(KMFn kmfn, std::function<void(ErrorType, std::tuple<ReturnTypes...>&&)> cb,
+                      const std::tuple<Args...>& tuple, std::index_sequence<I...>) {
+        std::tuple<ReturnTypes...> returnValue;
+        auto result = ((*keymasterDevice_).*kmfn)(
+            std::get<I>(tuple)...,
+            [&returnValue](const ReturnTypes&... args) { returnValue = std::make_tuple(args...); });
+        cb(std::move(result), std::move(returnValue));
+    }
+
+    template <typename KMFn, typename ErrorType, typename... Args>
+    void addRequest(KMFn kmfn, std::function<void(ErrorType)> cb, Args&&... args) {
+        Worker::addRequest([this, kmfn, cb = std::move(cb),
+                            tuple = std::make_tuple(std::forward<Args>(args)...)]() {
+            unwrap_tuple(kmfn, std::move(cb), tuple, std::index_sequence_for<Args...>{});
+        });
+    }
+
+    template <typename KMFn, typename ErrorType, typename... ReturnTypes, typename... Args>
+    void addRequest(KMFn kmfn, std::function<void(ErrorType, std::tuple<ReturnTypes...>&&)> cb,
+                    Args&&... args) {
+        Worker::addRequest([this, kmfn, cb = std::move(cb),
+                            tuple = std::make_tuple(std::forward<Args>(args)...)]() {
+            unwrap_tuple(kmfn, std::move(cb), tuple, std::index_sequence_for<Args...>{});
+        });
+    }
+    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);
+
+    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);
+
+    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 upgradeKey_cb = MakeKeymasterWorkerCB_t<Return<void>, Keymaster::upgradeKey_cb>;
+    void upgradeKey(hidl_vec<uint8_t> keyBlobToUpgrade, hidl_vec<KeyParameter> upgradeParams,
+                    upgradeKey_cb _hidl_cb);
+
+    using deleteKey_cb = MakeKeymasterWorkerCB_t<Return<ErrorCode>>;
+    void deleteKey(hidl_vec<uint8_t> keyBlob, deleteKey_cb _hidl_cb);
+
+    using deleteAllKeys_cb = MakeKeymasterWorkerCB_t<Return<ErrorCode>>;
+    void deleteAllKeys(deleteAllKeys_cb _hidl_cb);
+
+    using destroyAttestationIds_cb = MakeKeymasterWorkerCB_t<Return<ErrorCode>>;
+    void destroyAttestationIds(destroyAttestationIds_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_cli.cpp b/keystore/keystore_cli.cpp
index d5a8afa..b58735e 100644
--- a/keystore/keystore_cli.cpp
+++ b/keystore/keystore_cli.cpp
@@ -254,8 +254,6 @@
 
     // TODO: generate
 
-    SINGLE_ARG_DATA_RETURN(get_pubkey);
-
     // TODO: grant
 
     // TODO: ungrant
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
index 82d4e69..c05d142 100644
--- a/keystore/keystore_main.cpp
+++ b/keystore/keystore_main.cpp
@@ -155,10 +155,11 @@
     SecurityLevel minimalAllowedSecurityLevelForNewKeys =
         halVersion.majorVersion >= 2 ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE;
 
-    keystore::KeyStore keyStore(&entropy, kmDevices, minimalAllowedSecurityLevelForNewKeys);
-    keyStore.initialize();
+    android::sp<keystore::KeyStore> keyStore(
+        new keystore::KeyStore(&entropy, kmDevices, minimalAllowedSecurityLevelForNewKeys));
+    keyStore->initialize();
     android::sp<android::IServiceManager> sm = android::defaultServiceManager();
-    android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(&keyStore);
+    android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(keyStore);
     android::status_t ret = sm->addService(android::String16("android.security.keystore"), service);
     CHECK(ret == android::OK) << "Couldn't register binder service!";
 
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
index 4069060..07f9d6c 100644
--- a/keystore/operation.cpp
+++ b/keystore/operation.cpp
@@ -18,6 +18,8 @@
 #include "operation.h"
 
 #include <algorithm>
+#include <android-base/logging.h>
+#include <mutex>
 
 namespace keystore {
 
@@ -29,20 +31,22 @@
                                        KeyCharacteristics&& characteristics,
                                        const hidl_vec<KeyParameter>& params, bool pruneable) {
     sp<IBinder> token = new ::android::BBinder();
-    mMap.emplace(token, Operation(handle, keyid, purpose, dev, std::move(characteristics), appToken,
-                                  params));
+    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;
 }
 
-NullOr<const Operation&> OperationMap::getOperation(const sp<IBinder>& 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 entry->second;
+    return op;
 }
 
 void OperationMap::updateLru(const sp<IBinder>& token) {
@@ -53,17 +57,18 @@
     }
 }
 
-NullOr<Operation> OperationMap::removeOperation(const sp<IBinder>& token, bool wasSuccessful) {
+std::shared_ptr<Operation> OperationMap::removeOperation(const sp<IBinder>& token,
+                                                         bool wasSuccessful) {
     auto entry = mMap.find(token);
     if (entry == mMap.end()) return {};
 
-    Operation op = std::move(entry->second);
-    uploadOpAsProto(op, wasSuccessful);
+    auto op = entry->second;
+    uploadOpAsProto(*op, wasSuccessful);
     mMap.erase(entry);
 
     auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
     if (lruEntry != mLru.end()) mLru.erase(lruEntry);
-    removeOperationTracking(token, op.appToken);
+    removeOperationTracking(token, op->appToken);
     return op;
 }
 
@@ -82,32 +87,10 @@
     }
 }
 
-bool OperationMap::hasPruneableOperation() const {
-    return !mLru.empty();
-}
-
-size_t OperationMap::getPruneableOperationCount() const {
-    return mLru.size();
-}
-
 sp<IBinder> OperationMap::getOldestPruneableOperation() {
-    if (!hasPruneableOperation()) return sp<IBinder>(nullptr);
-    return mLru.front();
-}
+    if (mLru.size() == 0) return {};
 
-void OperationMap::setOperationAuthToken(const sp<IBinder>& token, HardwareAuthToken authToken) {
-    auto entry = mMap.find(token);
-    if (entry == mMap.end()) return;
-
-    entry->second.authToken = std::move(authToken);
-}
-
-void OperationMap::setOperationVerificationToken(const sp<IBinder>& token,
-                                                 VerificationToken verificationToken) {
-    auto entry = mMap.find(token);
-    if (entry == mMap.end()) return;
-
-    entry->second.verificationToken = std::move(verificationToken);
+    return {mLru.front()};
 }
 
 std::vector<sp<IBinder>> OperationMap::getOperationsForToken(const sp<IBinder>& appToken) {
diff --git a/keystore/operation.h b/keystore/operation.h
index 4888bfa..efe791f 100644
--- a/keystore/operation.h
+++ b/keystore/operation.h
@@ -17,7 +17,11 @@
 #ifndef KEYSTORE_OPERATION_H_
 #define KEYSTORE_OPERATION_H_
 
+#include <list>
 #include <map>
+#include <memory>
+#include <mutex>
+#include <optional>
 #include <vector>
 
 #include <binder/Binder.h>
@@ -26,6 +30,7 @@
 #include <utils/StrongPointer.h>
 
 #include <keystore/keymaster_types.h>
+#include <keystore/keystore_concurrency.h>
 #include <keystore/keystore_hidl_support.h>
 
 #include "operation_proto_handler.h"
@@ -51,21 +56,18 @@
                              const sp<Keymaster>& dev, const sp<IBinder>& appToken,
                              KeyCharacteristics&& characteristics,
                              const hidl_vec<KeyParameter>& params, bool pruneable);
-    NullOr<const Operation&> getOperation(const sp<IBinder>& token);
-    NullOr<Operation> removeOperation(const sp<IBinder>& token, bool wasSuccessful);
-    bool hasPruneableOperation() const;
+    std::shared_ptr<Operation> getOperation(const sp<IBinder>& token);
+    std::shared_ptr<Operation> removeOperation(const sp<IBinder>& token, bool wasSuccessful);
     size_t getOperationCount() const { return mMap.size(); }
-    size_t getPruneableOperationCount() const;
-    void setOperationAuthToken(const sp<IBinder>& token, HardwareAuthToken authToken);
-    void setOperationVerificationToken(const sp<IBinder>& token, VerificationToken authToken);
     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>, Operation> mMap;
-    std::vector<sp<IBinder>> mLru;
+
+    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;
 };
diff --git a/keystore/operation_struct.h b/keystore/operation_struct.h
index 00f1fe2..84265b6 100644
--- a/keystore/operation_struct.h
+++ b/keystore/operation_struct.h
@@ -24,6 +24,9 @@
 
 #include <keystore/keymaster_types.h>
 #include <keystore/keystore_hidl_support.h>
+#include <keystore/keystore_return_types.h>
+
+#include <future>
 
 namespace keystore {
 
@@ -37,7 +40,8 @@
               KeyCharacteristics&& characteristics_, sp<IBinder> appToken_,
               const hidl_vec<KeyParameter> params_)
         : handle(handle_), keyid(keyid_), purpose(purpose_), device(device_),
-          characteristics(characteristics_), appToken(appToken_), params(params_) {}
+          characteristics(characteristics_), appToken(appToken_), authToken(), verificationToken(),
+          params(params_) {}
     Operation(Operation&&) = default;
     Operation(const Operation&) = delete;
 
@@ -49,6 +53,8 @@
     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;
diff --git a/keystore/tests/auth_token_table_test.cpp b/keystore/tests/auth_token_table_test.cpp
index 29aa71e..f6ce10e 100644
--- a/keystore/tests/auth_token_table_test.cpp
+++ b/keystore/tests/auth_token_table_test.cpp
@@ -96,30 +96,36 @@
     table.AddAuthenticationToken(make_token(3, 4));
     EXPECT_EQ(2U, table.size());
 
-    const HardwareAuthToken* found;
+    AuthTokenTable::Error rc;
+    HardwareAuthToken found;
 
-    ASSERT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(1U, found->userId);
-    EXPECT_EQ(2U, found->authenticatorId);
+    ASSERT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(1U, found.userId);
+    EXPECT_EQ(2U, found.authenticatorId);
 
-    ASSERT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(1U, found->userId);
-    EXPECT_EQ(2U, found->authenticatorId);
+    ASSERT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(1U, found.userId);
+    EXPECT_EQ(2U, found.authenticatorId);
 
-    ASSERT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(3U, found->userId);
-    EXPECT_EQ(4U, found->authenticatorId);
+    ASSERT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(3U, found.userId);
+    EXPECT_EQ(4U, found.authenticatorId);
 
-    ASSERT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(3U, found->userId);
-    EXPECT_EQ(4U, found->authenticatorId);
+    ASSERT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(3U, found.userId);
+    EXPECT_EQ(4U, found.authenticatorId);
 
-    ASSERT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
+    ASSERT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0), rc));
 }
 
 TEST(AuthTokenTableTest, FlushTable) {
@@ -129,16 +135,20 @@
     table.AddAuthenticationToken(make_token(2));
     table.AddAuthenticationToken(make_token(3));
 
-    const HardwareAuthToken* found;
+    AuthTokenTable::Error rc;
+    HardwareAuthToken found;
 
     // All three should be in the table.
     EXPECT_EQ(3U, table.size());
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0), rc));
 
     table.Clear();
     EXPECT_EQ(0U, table.size());
@@ -151,61 +161,78 @@
     table.AddAuthenticationToken(make_token(2));
     table.AddAuthenticationToken(make_token(3));
 
-    const HardwareAuthToken* found;
+    AuthTokenTable::Error rc;
+    HardwareAuthToken found;
 
     // All three should be in the table.
     EXPECT_EQ(3U, table.size());
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0), rc));
 
     table.AddAuthenticationToken(make_token(4));
 
     // Oldest should be gone.
     EXPECT_EQ(3U, table.size());
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0), rc));
 
     // Others should be there, including the new one (4).  Search for it first, then the others, so
     // 4 becomes the least recently used.
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0), rc));
 
     table.AddAuthenticationToken(make_token(5));
 
     // 5 should have replaced 4.
     EXPECT_EQ(3U, table.size());
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0), rc));
 
     table.AddAuthenticationToken(make_token(6));
     table.AddAuthenticationToken(make_token(7));
 
     // 2 and 5 should be gone
     EXPECT_EQ(3U, table.size());
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(6), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(7), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(6), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(7), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0), rc));
 
     table.AddAuthenticationToken(make_token(8));
     table.AddAuthenticationToken(make_token(9));
@@ -213,77 +240,100 @@
 
     // Only the three most recent should be there.
     EXPECT_EQ(3U, table.size());
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(6), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(7), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(8), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(9), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(10), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(6), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(7), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(8), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(9), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(10), KeyPurpose::SIGN, 0), rc));
 }
 
 TEST(AuthTokenTableTest, AuthenticationNotRequired) {
     AuthTokenTable table;
-    const HardwareAuthToken* found;
+    AuthTokenTable::Error rc;
+    HardwareAuthToken found;
 
     EXPECT_EQ(AuthTokenTable::AUTH_NOT_REQUIRED,
-              table.FindAuthorization(AuthorizationSetBuilder().Authorization(TAG_NO_AUTH_REQUIRED),
-                                      KeyPurpose::SIGN, 0 /* no challenge */, &found));
+              (std::tie(rc, found) = table.FindAuthorization(
+                   AuthorizationSetBuilder().Authorization(TAG_NO_AUTH_REQUIRED), KeyPurpose::SIGN,
+                   0 /* no challenge */),
+               rc));
 }
 
 TEST(AuthTokenTableTest, OperationHandleNotFound) {
     AuthTokenTable table;
-    const HardwareAuthToken* found;
+    AuthTokenTable::Error rc;
+    HardwareAuthToken found;
 
     table.AddAuthenticationToken(make_token(1, 0, 1, 5));
     EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      2 /* non-matching challenge */, &found));
+              (std::tie(rc, found) =
+                   table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
+                                           2 /* non-matching challenge */),
+               rc));
     EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      1 /* matching challenge */, &found));
+              (std::tie(rc, found) = table.FindAuthorization(
+                   make_set(1, 0 /* no timeout */), KeyPurpose::SIGN, 1 /* matching challenge */),
+               rc));
     table.MarkCompleted(1);
     EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      1 /* used challenge */, &found));
+              (std::tie(rc, found) = table.FindAuthorization(
+                   make_set(1, 0 /* no timeout */), KeyPurpose::SIGN, 1 /* used challenge */),
+               rc));
 }
 
 TEST(AuthTokenTableTest, OperationHandleRequired) {
     AuthTokenTable table;
-    const HardwareAuthToken* found;
+    AuthTokenTable::Error rc;
+    HardwareAuthToken found;
 
     table.AddAuthenticationToken(make_token(1));
     EXPECT_EQ(AuthTokenTable::OP_HANDLE_REQUIRED,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      0 /* no op handle */, &found));
+              (std::tie(rc, found) = table.FindAuthorization(
+                   make_set(1, 0 /* no timeout */), KeyPurpose::SIGN, 0 /* no op handle */),
+               rc));
 }
 
 TEST(AuthTokenTableTest, AuthSidChanged) {
     AuthTokenTable table;
-    const HardwareAuthToken* found;
+    AuthTokenTable::Error rc;
+    HardwareAuthToken found;
 
     table.AddAuthenticationToken(make_token(1, 3, /* op handle */ 1));
     EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_WRONG_SID,
-              table.FindAuthorization(make_set(2, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      1 /* op handle */, &found));
+              (std::tie(rc, found) = table.FindAuthorization(make_set(2, 0 /* no timeout */),
+                                                             KeyPurpose::SIGN, 1 /* op handle */),
+               rc));
 }
 
 TEST(AuthTokenTableTest, TokenExpired) {
     AuthTokenTable table(5, monotonic_clock);
-    const HardwareAuthToken* found;
+    AuthTokenTable::Error rc;
+    HardwareAuthToken found;
 
     auto key_info = make_set(1, 5 /* five second timeout */);
 
@@ -294,18 +344,25 @@
     // expired.  An additional check of the secure timestamp (in the token) will be made by
     // keymaster when the found token is passed to it.
     table.AddAuthenticationToken(make_token(1, 0));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       key_info, KeyPurpose::SIGN, 0 /* no op handle */),
+                                   rc));
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       key_info, KeyPurpose::SIGN, 0 /* no op handle */),
+                                   rc));
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       key_info, KeyPurpose::SIGN, 0 /* no op handle */),
+                                   rc));
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       key_info, KeyPurpose::SIGN, 0 /* no op handle */),
+                                   rc));
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       key_info, KeyPurpose::SIGN, 0 /* no op handle */),
+                                   rc));
     EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_EXPIRED,
-              table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
+              (std::tie(rc, found) =
+                   table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */),
+               rc));
 }
 
 TEST(AuthTokenTableTest, MarkNonexistentEntryCompleted) {
@@ -316,16 +373,18 @@
 
 TEST(AuthTokenTableTest, SupersededEntries) {
     AuthTokenTable table;
-    const HardwareAuthToken* found;
+    AuthTokenTable::Error rc;
+    HardwareAuthToken found;
 
     // Add two identical tokens, without challenges.  The second should supersede the first, based
     // on timestamp (fourth arg to make_token).
     table.AddAuthenticationToken(make_token(1, 0, 0, 0));
     table.AddAuthenticationToken(make_token(1, 0, 0, 1));
     EXPECT_EQ(1U, table.size());
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(1U, found->timestamp);
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(1U, found.timestamp);
 
     // Add a third token, this with a different RSID.  It should not be superseded.
     table.AddAuthenticationToken(make_token(2, 0, 0, 2));
@@ -335,12 +394,14 @@
     table.AddAuthenticationToken(make_token(1, 0, 0, 3));
     table.AddAuthenticationToken(make_token(2, 0, 0, 4));
     EXPECT_EQ(2U, table.size());
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(3U, found->timestamp);
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(4U, found->timestamp);
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(3U, found.timestamp);
+    EXPECT_EQ(
+        AuthTokenTable::OK,
+        (std::tie(rc, found) = table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0), rc));
+    EXPECT_EQ(4U, found.timestamp);
 
     // Add another, this one with a challenge value.  It should supersede the old one since it is
     // newer, and matches other than the challenge.
@@ -355,45 +416,52 @@
     // Should be able to find each of them, by specifying their challenge, with a key that is not
     // timed (timed keys don't care about challenges).
     EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1, 0 /* no timeout*/), KeyPurpose::SIGN,
-                                      1 /* challenge */, &found));
-    EXPECT_EQ(5U, found->timestamp);
+              (std::tie(rc, found) = table.FindAuthorization(make_set(1, 0 /* no timeout*/),
+                                                             KeyPurpose::SIGN, 1 /* challenge */),
+               rc));
+    EXPECT_EQ(5U, found.timestamp);
     EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      2 /* challenge */, &found));
-    EXPECT_EQ(6U, found->timestamp);
+              (std::tie(rc, found) = table.FindAuthorization(make_set(1, 0 /* no timeout */),
+                                                             KeyPurpose::SIGN, 2 /* challenge */),
+               rc));
+    EXPECT_EQ(6U, found.timestamp);
 
     // Add another, without a challenge, and the same timestamp as the last one.  This new one
     // actually could be considered already-superseded, but the table doesn't handle that case,
     // since it seems unlikely to occur in practice.
     table.AddAuthenticationToken(make_token(1, 0, 0, 6));
     EXPECT_EQ(4U, table.size());
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(6U, found->timestamp);
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       make_set(1), KeyPurpose::SIGN, 0 /* challenge */),
+                                   rc));
+    EXPECT_EQ(6U, found.timestamp);
 
     // Add another without a challenge but an increased timestamp. This should supersede the
     // previous challenge-free entry.
     table.AddAuthenticationToken(make_token(1, 0, 0, 7));
     EXPECT_EQ(4U, table.size());
     EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      2 /* challenge */, &found));
-    EXPECT_EQ(6U, found->timestamp);
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(7U, found->timestamp);
+              (std::tie(rc, found) = table.FindAuthorization(make_set(1, 0 /* no timeout */),
+                                                             KeyPurpose::SIGN, 2 /* challenge */),
+               rc));
+    EXPECT_EQ(6U, found.timestamp);
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       make_set(1), KeyPurpose::SIGN, 0 /* challenge */),
+                                   rc));
+    EXPECT_EQ(7U, found.timestamp);
 
     // Mark the entry with challenge 2 as complete.  Since there's a newer challenge-free entry, the
     // challenge entry will be superseded.
     table.MarkCompleted(2);
     EXPECT_EQ(3U, table.size());
     EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      2 /* challenge */, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(7U, found->timestamp);
+              (std::tie(rc, found) = table.FindAuthorization(make_set(1, 0 /* no timeout */),
+                                                             KeyPurpose::SIGN, 2 /* challenge */),
+               rc));
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       make_set(1), KeyPurpose::SIGN, 0 /* challenge */),
+                                   rc));
+    EXPECT_EQ(7U, found.timestamp);
 
     // Add another SID 1 entry with a challenge.  It supersedes the previous SID 1 entry with
     // no challenge (timestamp 7), but not the one with challenge 1 (timestamp 5).
@@ -401,19 +469,22 @@
     EXPECT_EQ(3U, table.size());
 
     EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      1 /* challenge */, &found));
-    EXPECT_EQ(5U, found->timestamp);
+              (std::tie(rc, found) = table.FindAuthorization(make_set(1, 0 /* no timeout */),
+                                                             KeyPurpose::SIGN, 1 /* challenge */),
+               rc));
+    EXPECT_EQ(5U, found.timestamp);
 
     EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      3 /* challenge */, &found));
-    EXPECT_EQ(8U, found->timestamp);
+              (std::tie(rc, found) = table.FindAuthorization(make_set(1, 0 /* no timeout */),
+                                                             KeyPurpose::SIGN, 3 /* challenge */),
+               rc));
+    EXPECT_EQ(8U, found.timestamp);
 
     // SID 2 entry is still there.
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(4U, found->timestamp);
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       make_set(2), KeyPurpose::SIGN, 0 /* challenge */),
+                                   rc));
+    EXPECT_EQ(4U, found.timestamp);
 
     // Mark the entry with challenge 3 as complete.  Since the older challenge 1 entry is
     // incomplete, nothing is superseded.
@@ -421,24 +492,28 @@
     EXPECT_EQ(3U, table.size());
 
     EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      1 /* challenge */, &found));
-    EXPECT_EQ(5U, found->timestamp);
+              (std::tie(rc, found) = table.FindAuthorization(make_set(1, 0 /* no timeout */),
+                                                             KeyPurpose::SIGN, 1 /* challenge */),
+               rc));
+    EXPECT_EQ(5U, found.timestamp);
 
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(8U, found->timestamp);
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       make_set(1), KeyPurpose::SIGN, 0 /* challenge */),
+                                   rc));
+    EXPECT_EQ(8U, found.timestamp);
 
     // Mark the entry with challenge 1 as complete.  Since there's a newer one (with challenge 3,
     // completed), the challenge 1 entry is superseded and removed.
     table.MarkCompleted(1);
     EXPECT_EQ(2U, table.size());
     EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
-              table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
-                                      1 /* challenge */, &found));
-    EXPECT_EQ(AuthTokenTable::OK,
-              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(8U, found->timestamp);
+              (std::tie(rc, found) = table.FindAuthorization(make_set(1, 0 /* no timeout */),
+                                                             KeyPurpose::SIGN, 1 /* challenge */),
+               rc));
+    EXPECT_EQ(AuthTokenTable::OK, (std::tie(rc, found) = table.FindAuthorization(
+                                       make_set(1), KeyPurpose::SIGN, 0 /* challenge */),
+                                   rc));
+    EXPECT_EQ(8U, found.timestamp);
 }
 
 }  // namespace test
diff --git a/keystore/user_state.cpp b/keystore/user_state.cpp
index af3336b..c9a2d72 100644
--- a/keystore/user_state.cpp
+++ b/keystore/user_state.cpp
@@ -31,25 +31,32 @@
 #include "blob.h"
 #include "keystore_utils.h"
 
+namespace keystore {
 
-UserState::UserState(uid_t userId) :
-        mUserId(userId), mState(STATE_UNINITIALIZED), mRetry(MAX_RETRY) {
-    asprintf(&mUserDir, "user_%u", mUserId);
-    asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir);
+UserState::UserState(uid_t userId)
+    : mMasterKeyEntry(".masterkey", "user_" + std::to_string(userId), userId, /* masterkey */ true),
+      mUserId(userId), mState(STATE_UNINITIALIZED), mRetry(MAX_RETRY) {}
+
+bool UserState::operator<(const UserState& rhs) const {
+    return getUserId() < rhs.getUserId();
 }
 
-UserState::~UserState() {
-    free(mUserDir);
-    free(mMasterKeyFile);
+bool UserState::operator<(uid_t userId) const {
+    return getUserId() < userId;
+}
+
+bool operator<(uid_t userId, const UserState& rhs) {
+    return userId < rhs.getUserId();
 }
 
 bool UserState::initialize() {
-    if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) {
-        ALOGE("Could not create directory '%s'", mUserDir);
+    if ((mkdir(mMasterKeyEntry.user_dir().c_str(), S_IRUSR | S_IWUSR | S_IXUSR) < 0) &&
+        (errno != EEXIST)) {
+        ALOGE("Could not create directory '%s'", mMasterKeyEntry.user_dir().c_str());
         return false;
     }
 
-    if (access(mMasterKeyFile, R_OK) == 0) {
+    if (mMasterKeyEntry.hasKeyBlob()) {
         setState(STATE_LOCKED);
     } else {
         setState(STATE_UNINITIALIZED);
@@ -73,7 +80,7 @@
 bool UserState::deleteMasterKey() {
     setState(STATE_UNINITIALIZED);
     zeroizeMasterKeysInMemory();
-    return unlink(mMasterKeyFile) == 0 || errno == ENOENT;
+    return unlink(mMasterKeyEntry.getKeyBlobPath().c_str()) == 0 || errno == ENOENT;
 }
 
 ResponseCode UserState::initialize(const android::String8& pw, Entropy* entropy) {
@@ -88,23 +95,23 @@
     return ResponseCode::NO_ERROR;
 }
 
-ResponseCode UserState::copyMasterKey(UserState* src) {
+ResponseCode UserState::copyMasterKey(LockedUserState<UserState>* src) {
     if (mState != STATE_UNINITIALIZED) {
         return ResponseCode::SYSTEM_ERROR;
     }
-    if (src->getState() != STATE_NO_ERROR) {
+    if ((*src)->getState() != STATE_NO_ERROR) {
         return ResponseCode::SYSTEM_ERROR;
     }
-    memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES);
+    memcpy(mMasterKey, (*src)->mMasterKey, MASTER_KEY_SIZE_BYTES);
     setupMasterKeys();
     return copyMasterKeyFile(src);
 }
 
-ResponseCode UserState::copyMasterKeyFile(UserState* src) {
+ResponseCode UserState::copyMasterKeyFile(LockedUserState<UserState>* src) {
     /* Copy the master key file to the new user.  Unfortunately we don't have the src user's
      * password so we cannot generate a new file with a new salt.
      */
-    int in = TEMP_FAILURE_RETRY(open(src->getMasterKeyFileName(), O_RDONLY));
+    int in = TEMP_FAILURE_RETRY(open((*src)->getMasterKeyFileName().c_str(), O_RDONLY));
     if (in < 0) {
         return ResponseCode::SYSTEM_ERROR;
     }
@@ -113,8 +120,8 @@
     if (close(in) != 0) {
         return ResponseCode::SYSTEM_ERROR;
     }
-    int out =
-        TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
+    int out = TEMP_FAILURE_RETRY(open(mMasterKeyEntry.getKeyBlobPath().c_str(),
+                                      O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
     if (out < 0) {
         return ResponseCode::SYSTEM_ERROR;
     }
@@ -124,7 +131,7 @@
     }
     if (outLength != length) {
         ALOGW("blob not fully written %zu != %zu", outLength, length);
-        unlink(mMasterKeyFile);
+        unlink(mMasterKeyEntry.getKeyBlobPath().c_str());
         return ResponseCode::SYSTEM_ERROR;
     }
     return ResponseCode::NO_ERROR;
@@ -134,11 +141,15 @@
     uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
     generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
     Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
-    return masterKeyBlob.writeBlob(mMasterKeyFile, passwordKey, STATE_NO_ERROR, entropy);
+    auto lockedEntry = LockedKeyBlobEntry::get(mMasterKeyEntry);
+    return lockedEntry.writeBlobs(masterKeyBlob, {}, passwordKey, STATE_NO_ERROR, entropy);
 }
 
 ResponseCode UserState::readMasterKey(const android::String8& pw, Entropy* entropy) {
-    int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY));
+
+    auto lockedEntry = LockedKeyBlobEntry::get(mMasterKeyEntry);
+
+    int in = TEMP_FAILURE_RETRY(open(mMasterKeyEntry.getKeyBlobPath().c_str(), O_RDONLY));
     if (in < 0) {
         return ResponseCode::SYSTEM_ERROR;
     }
@@ -159,8 +170,10 @@
     }
     uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
     generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
-    Blob masterKeyBlob(rawBlob);
-    ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, passwordKey, STATE_NO_ERROR);
+    Blob masterKeyBlob, dummyBlob;
+    ResponseCode response;
+    std::tie(response, masterKeyBlob, dummyBlob) =
+        lockedEntry.readBlobs(passwordKey, STATE_NO_ERROR);
     if (response == ResponseCode::SYSTEM_ERROR) {
         return response;
     }
@@ -198,7 +211,7 @@
 }
 
 bool UserState::reset() {
-    DIR* dir = opendir(getUserDirName());
+    DIR* dir = opendir(mMasterKeyEntry.user_dir().c_str());
     if (!dir) {
         // If the directory doesn't exist then nothing to do.
         if (errno == ENOENT) {
@@ -254,3 +267,37 @@
 void UserState::setupMasterKeys() {
     setState(STATE_NO_ERROR);
 }
+
+LockedUserState<UserState> UserStateDB::getUserState(uid_t userId) {
+    std::unique_lock<std::mutex> lock(locked_state_mutex_);
+    decltype(mMasterKeys.begin()) it;
+    bool inserted;
+    std::tie(it, inserted) = mMasterKeys.emplace(userId, userId);
+    if (inserted) {
+        if (!it->second.initialize()) {
+            /* There's not much we can do if initialization fails. Trying to
+             * unlock the keystore for that user will fail as well, so any
+             * subsequent request for this user will just return SYSTEM_ERROR.
+             */
+            ALOGE("User initialization failed for %u; subsequent operations will fail", userId);
+        }
+    }
+    return get(std::move(lock), &it->second);
+}
+
+LockedUserState<UserState> UserStateDB::getUserStateByUid(uid_t uid) {
+    return getUserState(get_user_id(uid));
+}
+
+LockedUserState<const UserState> UserStateDB::getUserState(uid_t userId) const {
+    std::unique_lock<std::mutex> lock(locked_state_mutex_);
+    auto it = mMasterKeys.find(userId);
+    if (it == mMasterKeys.end()) return {};
+    return get(std::move(lock), &it->second);
+}
+
+LockedUserState<const UserState> UserStateDB::getUserStateByUid(uid_t uid) const {
+    return getUserState(get_user_id(uid));
+}
+
+}  // namespace keystore
diff --git a/keystore/user_state.h b/keystore/user_state.h
index c28f7b8..365941e 100644
--- a/keystore/user_state.h
+++ b/keystore/user_state.h
@@ -25,19 +25,32 @@
 
 #include <keystore/keystore.h>
 
+#include "blob.h"
 #include "entropy.h"
+#include "keystore_utils.h"
+
+#include <android-base/logging.h>
+#include <condition_variable>
+#include <keystore/keystore_concurrency.h>
+#include <mutex>
+#include <set>
+
+namespace keystore {
+
+class UserState;
+
+template <typename UserState> using LockedUserState = ProxyLock<UnlockProxyLockHelper<UserState>>;
 
 class UserState {
   public:
     explicit UserState(uid_t userId);
-    ~UserState();
 
     bool initialize();
 
     uid_t getUserId() const { return mUserId; }
-    const char* getUserDirName() const { return mUserDir; }
+    const std::string& getUserDirName() const { return mMasterKeyEntry.user_dir(); }
 
-    const char* getMasterKeyFileName() const { return mMasterKeyFile; }
+    std::string getMasterKeyFileName() const { return mMasterKeyEntry.getKeyBlobPath(); }
 
     void setState(State state);
     State getState() const { return mState; }
@@ -49,15 +62,18 @@
 
     ResponseCode initialize(const android::String8& pw, Entropy* entropy);
 
-    ResponseCode copyMasterKey(UserState* src);
-    ResponseCode copyMasterKeyFile(UserState* src);
+    ResponseCode copyMasterKey(LockedUserState<UserState>* src);
+    ResponseCode copyMasterKeyFile(LockedUserState<UserState>* src);
     ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy);
     ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy);
 
-    auto& getEncryptionKey() const { return mMasterKey; }
+    const uint8_t* getEncryptionKey() const { return &mMasterKey[0]; }
 
     bool reset();
 
+    bool operator<(const UserState& rhs) const;
+    bool operator<(uid_t userId) const;
+
   private:
     static const int MASTER_KEY_SIZE_BYTES = 16;
     static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
@@ -71,11 +87,9 @@
     bool generateMasterKey(Entropy* entropy);
     void setupMasterKeys();
 
+    KeyBlobEntry mMasterKeyEntry;
+
     uid_t mUserId;
-
-    char* mUserDir;
-    char* mMasterKeyFile;
-
     State mState;
     int8_t mRetry;
 
@@ -83,4 +97,36 @@
     uint8_t mSalt[SALT_SIZE];
 };
 
+bool operator<(uid_t userId, const UserState& rhs);
+
+class UserStateDB {
+  public:
+    LockedUserState<UserState> getUserState(uid_t userId);
+    LockedUserState<UserState> getUserStateByUid(uid_t uid);
+    LockedUserState<const UserState> getUserState(uid_t userId) const;
+    LockedUserState<const UserState> getUserStateByUid(uid_t uid) const;
+
+  private:
+    mutable std::set<const UserState*> locked_state_;
+    mutable std::mutex locked_state_mutex_;
+    mutable std::condition_variable locked_state_mutex_cond_var_;
+
+    template <typename UserState>
+    LockedUserState<UserState> get(std::unique_lock<std::mutex> lock, UserState* entry) const {
+        locked_state_mutex_cond_var_.wait(
+            lock, [&] { return locked_state_.find(entry) == locked_state_.end(); });
+        locked_state_.insert(entry);
+        return {entry, [&](UserState* entry) {
+                    std::unique_lock<std::mutex> lock(locked_state_mutex_);
+                    locked_state_.erase(entry);
+                    lock.unlock();
+                    locked_state_mutex_cond_var_.notify_all();
+                }};
+    }
+
+    std::map<uid_t, UserState> mMasterKeys;
+};
+
+}  //  namespace keystore
+
 #endif  // KEYSTORE_USER_STATE_H_
