Multithreaded Keystore

This patch transitions keystore a threading model with one dispatcher
thread and one worker thread per keymaster instance, i.e. fallback, TEE,
Strongbox (if available). Singleton objects, such as the user state
database, the enforcement policy, and grant database have been moved to
KeyStore and were made concurrency safe.
Other noteworthy changes in this patch:

* Cached key characteristics. The key characteristics file used to hold
  a limited set of parameters used generate or import the key. This
  patch introduces a new blob type that holds full characteristics as
  returned by generate, import, or getKeyCharacteristics, with the
  original parameters mixed into the software enforced list. When
  keystore encounters a lagacy characteristics file it will grab the
  characteristics from keymaster, merge them with the cached parameters,
  and update the cache file to the new format. If keystore encounters
  the new cache no call to keymaster will be made for retrieving the
  key characteristics.
* Changed semantic of list. The list call takes a prefix used for
  filtering key entries. By the old semantic, list would return a list
  of aliases stripped of the given prefix. By the new semantic list
  always returns a filtered list of full alias string. Callers may
  strip prefixes if they are so inclined.
* Entertain per keymaster instance operation maps. With the introduction
  of Strongbox keystore had to deal with multiple keymaster instances.
  But until now it would entertain a single operations map. Keystore
  also enforces the invariant that no more than 15 operation slots are
  used so there is always a free slot available for vold. With a single
  operation map, this means no more than 15 slots can ever be used
  although with TEE and Strongbox there are a total of 32 slots. With
  strongbox implementation that have significantly fewer slots we see
  another effect of the single operation map. If a slot needs to be
  freed on Stronbox but the oldest operations are on TEE, the latter
  will be unnecessarily pruned before a Strongbox slot is freed up.
  With this patch each keymaster instance has its own operation map and
  pruning is performed on a per keymaster instance basis.
* Introduce KeyBlobEntries which are independent from files. To allow
  concurrent access to the key blob data base, entries can be
  individually locked so that operations on entries become atomic.
  LockedKeyBlobEntries are move only objects that track ownership of an
  Entry on the stack or in functor object representing keymaster worker
  requests. Entries must only be locked by the dispatcher Thread. Worker
  threads can only be granted access to a LockedKeyBlobEntry by the
  dispatcher thread. This allows the dispatcher thread to execute a
  barrier that waits until all locks held by workers have been
  relinquished to perform blob database maintenance operations, e.g.,
  clearing a uid of all entries.
* Verification tokens are now acquired asynchronously. When a begin
  operation requires a verification token a request is submitted to the
  other keymaster worker while the begin call returns. When the
  operation commences with update or finish, we block until the
  verification token becomes available.

As of this patch the keystore IPC interface is still synchronous. That
is, the dispatcher thread dispatches a request to a worker and then
waits until the worker has finished. In a followup patch the IPC
interface shall be made asynchronous so that multiple requests may be in
flight.

Test: Ran full CTS test suite
      atest android.keystore.cts
Bug: 111443219
Bug: 110495056
Change-Id: I305e28d784295a0095a34810d83202f7423498bd
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();