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/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 dcf1acb..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));
@@ -431,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();
 }
 
@@ -453,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();
 }
 
@@ -474,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();
     }
@@ -494,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();
     }
@@ -518,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();
@@ -555,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();
 }
 
@@ -604,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();
 }
 
@@ -725,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();
 }
 
@@ -825,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();
     }
@@ -837,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();
 }
 
@@ -957,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();
 }
 
@@ -1014,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)) {
@@ -1033,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())) {
@@ -1251,132 +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));
+    dev->abort(token, [&](KeyStoreServiceReturnCode rc) { resultPromise.set_value(rc); });
+
+    resultFuture.wait();
+    *aidl_return = int32_t(resultFuture.get());
     return Status::ok();
 }
 
@@ -1403,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();
 }
@@ -1463,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();
 }
 
@@ -1533,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);
@@ -1549,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();
 }
@@ -1616,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,
@@ -1697,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);
 }
 
 /**
@@ -1838,182 +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};
-}
-
-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 7a48be7..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);
@@ -149,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.
      */
@@ -206,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,
@@ -250,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_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_
