diff --git a/keystore-engine/Android.bp b/keystore-engine/Android.bp
new file mode 100644
index 0000000..60f5940
--- /dev/null
+++ b/keystore-engine/Android.bp
@@ -0,0 +1,72 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "libkeystore-engine",
+
+    srcs: [
+        "android_engine.cpp",
+        "keystore_backend_binder.cpp",
+    ],
+
+    cflags: [
+        "-fvisibility=hidden",
+        "-Wall",
+        "-Werror",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libcrypto",
+        "libcutils",
+        "libhidlbase",
+        "libkeystore_aidl",
+        "libkeystore_binder",
+        "libkeystore_parcelables",
+        "liblog",
+        "libbase",
+        "libutils",
+    ],
+
+}
+
+// This builds a variant of libkeystore-engine that uses a HIDL HAL
+// owned by the WiFi user to perform signing operations.
+cc_library_shared {
+    name: "libkeystore-engine-wifi-hidl",
+
+    srcs: [
+        "android_engine.cpp",
+        "keystore_backend_hidl.cpp",
+    ],
+
+    cflags: [
+        "-fvisibility=hidden",
+        "-Wall",
+        "-Werror",
+        "-DBACKEND_WIFI_HIDL",
+    ],
+
+    shared_libs: [
+        "android.system.wifi.keystore@1.0",
+        "libcrypto",
+        "liblog",
+        "libhidlbase",
+        "libhidltransport",
+        "libcutils",
+        "libutils",
+    ],
+
+    vendor: true,
+}
diff --git a/keystore-engine/Android.mk b/keystore-engine/Android.mk
deleted file mode 100644
index c995dfc..0000000
--- a/keystore-engine/Android.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libkeystore-engine
-
-LOCAL_SRC_FILES := \
-	android_engine.cpp \
-	keystore_backend_binder.cpp
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -fvisibility=hidden -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES += \
-	libbinder \
-	libcrypto \
-	libcutils \
-	libhidlbase \
-	libkeystore_aidl \
-	libkeystore_binder \
-	liblog \
-	libutils
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-# This builds a variant of libkeystore-engine that uses a HIDL HAL
-# owned by the WiFi user to perform signing operations.
-LOCAL_MODULE := libkeystore-engine-wifi-hidl
-
-LOCAL_SRC_FILES := \
-	android_engine.cpp \
-	keystore_backend_hidl.cpp
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -fvisibility=hidden -Wall -Werror -DBACKEND_WIFI_HIDL
-
-LOCAL_SHARED_LIBRARIES += \
-	android.system.wifi.keystore@1.0 \
-	libcrypto \
-	liblog \
-	libhidlbase \
-	libhidltransport \
-	libcutils \
-	libutils
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
index bb0356b..856194d 100644
--- a/keystore-engine/android_engine.cpp
+++ b/keystore-engine/android_engine.cpp
@@ -28,7 +28,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 
 #include <openssl/bn.h>
 #include <openssl/ec.h>
@@ -59,7 +59,7 @@
                long /* argl */,
                void* /* argp */) {
     char *key_id = reinterpret_cast<char *>(*from_d);
-    if (key_id != NULL) {
+    if (key_id != nullptr) {
         *from_d = strdup(key_id);
     }
     return 1;
@@ -80,8 +80,7 @@
  * the argument on failure. This means we need to tell our scoped pointers when
  * we've transferred ownership, without triggering a warning by not using the
  * result of release(). */
-#define OWNERSHIP_TRANSFERRED(obj) \
-    typeof ((obj).release()) _dummy __attribute__((unused)) = (obj).release()
+#define OWNERSHIP_TRANSFERRED(obj) auto _dummy __attribute__((unused)) = (obj).release()
 
 const char* rsa_get_key_id(const RSA* rsa);
 
@@ -95,12 +94,12 @@
     ensure_keystore_engine();
 
     const char *key_id = rsa_get_key_id(rsa);
-    if (key_id == NULL) {
+    if (key_id == nullptr) {
         ALOGE("key had no key_id!");
         return 0;
     }
 
-    uint8_t* reply = NULL;
+    uint8_t* reply = nullptr;
     size_t reply_len;
     int32_t ret = g_keystore_backend->sign(key_id, in, len, &reply, &reply_len);
     if (ret < 0) {
@@ -109,7 +108,7 @@
     } else if (ret != 0) {
         ALOGW("Error during sign from keystore: %d", ret);
         return 0;
-    } else if (reply_len == 0 || reply == NULL) {
+    } else if (reply_len == 0 || reply == nullptr) {
         ALOGW("No valid signature returned");
         return 0;
     }
@@ -149,21 +148,21 @@
     ensure_keystore_engine();
 
     const char *key_id = ecdsa_get_key_id(ec_key);
-    if (key_id == NULL) {
+    if (key_id == nullptr) {
         ALOGE("key had no key_id!");
         return 0;
     }
 
     size_t ecdsa_size = ECDSA_size(ec_key);
 
-    uint8_t* reply = NULL;
+    uint8_t* reply = nullptr;
     size_t reply_len;
     int32_t ret = g_keystore_backend->sign(
             key_id, digest, digest_len, &reply, &reply_len);
     if (ret < 0) {
         ALOGW("There was an error during ecdsa_sign: could not connect");
         return 0;
-    } else if (reply_len == 0 || reply == NULL) {
+    } else if (reply_len == 0 || reply == nullptr) {
         ALOGW("No valid signature returned");
         return 0;
     } else if (reply_len > ecdsa_size) {
@@ -186,13 +185,13 @@
  public:
   KeystoreEngine()
       : rsa_index_(RSA_get_ex_new_index(0 /* argl */,
-                                        NULL /* argp */,
-                                        NULL /* new_func */,
+                                        nullptr /* argp */,
+                                        nullptr /* new_func */,
                                         key_id_dup,
                                         key_id_free)),
         ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */,
-                                              NULL /* argp */,
-                                              NULL /* new_func */,
+                                              nullptr /* argp */,
+                                              nullptr /* new_func */,
                                               key_id_dup,
                                               key_id_free)),
         engine_(ENGINE_new()) {
@@ -278,31 +277,31 @@
  * KeyStore and operate on the key named |key_id|. */
 static EVP_PKEY *wrap_rsa(const char *key_id, const RSA *public_rsa) {
     Unique_RSA rsa(RSA_new_method(g_keystore_engine->engine()));
-    if (rsa.get() == NULL) {
-        return NULL;
+    if (rsa.get() == nullptr) {
+        return nullptr;
     }
 
     char *key_id_copy = strdup(key_id);
-    if (key_id_copy == NULL) {
-        return NULL;
+    if (key_id_copy == nullptr) {
+        return nullptr;
     }
 
     if (!RSA_set_ex_data(rsa.get(), g_keystore_engine->rsa_ex_index(),
                          key_id_copy)) {
         free(key_id_copy);
-        return NULL;
+        return nullptr;
     }
 
     rsa->n = BN_dup(public_rsa->n);
     rsa->e = BN_dup(public_rsa->e);
-    if (rsa->n == NULL || rsa->e == NULL) {
-        return NULL;
+    if (rsa->n == nullptr || rsa->e == nullptr) {
+        return nullptr;
     }
 
     Unique_EVP_PKEY result(EVP_PKEY_new());
-    if (result.get() == NULL ||
+    if (result.get() == nullptr ||
         !EVP_PKEY_assign_RSA(result.get(), rsa.get())) {
-        return NULL;
+        return nullptr;
     }
     OWNERSHIP_TRANSFERRED(rsa);
 
@@ -314,30 +313,30 @@
  * KeyStore and operate on the key named |key_id|. */
 static EVP_PKEY *wrap_ecdsa(const char *key_id, const EC_KEY *public_ecdsa) {
     Unique_EC_KEY ec(EC_KEY_new_method(g_keystore_engine->engine()));
-    if (ec.get() == NULL) {
-        return NULL;
+    if (ec.get() == nullptr) {
+        return nullptr;
     }
 
     if (!EC_KEY_set_group(ec.get(), EC_KEY_get0_group(public_ecdsa)) ||
         !EC_KEY_set_public_key(ec.get(), EC_KEY_get0_public_key(public_ecdsa))) {
-        return NULL;
+        return nullptr;
     }
 
     char *key_id_copy = strdup(key_id);
-    if (key_id_copy == NULL) {
-        return NULL;
+    if (key_id_copy == nullptr) {
+        return nullptr;
     }
 
     if (!EC_KEY_set_ex_data(ec.get(), g_keystore_engine->ec_key_ex_index(),
                             key_id_copy)) {
         free(key_id_copy);
-        return NULL;
+        return nullptr;
     }
 
     Unique_EVP_PKEY result(EVP_PKEY_new());
-    if (result.get() == NULL ||
+    if (result.get() == nullptr ||
         !EVP_PKEY_assign_EC_KEY(result.get(), ec.get())) {
-        return NULL;
+        return nullptr;
     }
     OWNERSHIP_TRANSFERRED(ec);
 
@@ -359,22 +358,22 @@
 
     ensure_keystore_engine();
 
-    uint8_t *pubkey = NULL;
+    uint8_t *pubkey = nullptr;
     size_t pubkey_len;
     int32_t ret = g_keystore_backend->get_pubkey(key_id, &pubkey, &pubkey_len);
     if (ret < 0) {
         ALOGW("could not contact keystore");
-        return NULL;
-    } else if (ret != 0 || pubkey == NULL) {
+        return nullptr;
+    } else if (ret != 0 || pubkey == nullptr) {
         ALOGW("keystore reports error: %d", ret);
-        return NULL;
+        return nullptr;
     }
 
     const uint8_t *inp = pubkey;
-    Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &inp, pubkey_len));
-    if (pkey.get() == NULL) {
+    Unique_EVP_PKEY pkey(d2i_PUBKEY(nullptr, &inp, pubkey_len));
+    if (pkey.get() == nullptr) {
         ALOGW("Cannot convert pubkey");
-        return NULL;
+        return nullptr;
     }
 
     EVP_PKEY *result;
@@ -391,7 +390,7 @@
     }
     default:
         ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type));
-        result = NULL;
+        result = nullptr;
     }
 
     return result;
diff --git a/keystore-engine/keystore_backend_binder.cpp b/keystore-engine/keystore_backend_binder.cpp
index f9e7be0..590f005 100644
--- a/keystore-engine/keystore_backend_binder.cpp
+++ b/keystore-engine/keystore_backend_binder.cpp
@@ -22,19 +22,76 @@
 
 #include "keystore_backend_binder.h"
 
-#include <android/security/IKeystoreService.h>
+#include <android-base/logging.h>
+#include <android/security/keystore/IKeystoreService.h>
 #include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <keystore/KeyCharacteristics.h>
+#include <keystore/KeymasterArguments.h>
+#include <keystore/KeymasterBlob.h>
+#include <keystore/KeystoreResponse.h>
+#include <keystore/OperationResult.h>
+#include <keystore/keymaster_types.h>
 #include <keystore/keystore.h>
 #include <keystore/keystore_hidl_support.h>
+#include <keystore/keystore_promises.h>
+#include <keystore/keystore_return_types.h>
 
-using android::security::IKeystoreService;
+#include <future>
+#include <thread>
+
+using android::security::keystore::IKeystoreService;
 using namespace android;
-using keystore::blob2hidlVec;
 using keystore::hidl_vec;
 
+using android::hardware::keymaster::V4_0::Algorithm;
+using android::hardware::keymaster::V4_0::authorizationValue;
+using android::hardware::keymaster::V4_0::Digest;
+using android::hardware::keymaster::V4_0::KeyFormat;
+using android::hardware::keymaster::V4_0::KeyParameter;
+using android::hardware::keymaster::V4_0::KeyPurpose;
+using android::hardware::keymaster::V4_0::NullOr;
+using android::hardware::keymaster::V4_0::PaddingMode;
+using android::hardware::keymaster::V4_0::TAG_ALGORITHM;
+using android::hardware::keymaster::V4_0::TAG_DIGEST;
+using android::hardware::keymaster::V4_0::TAG_PADDING;
+using android::security::keymaster::ExportResult;
+using android::security::keymaster::KeyCharacteristics;
+using android::security::keymaster::KeymasterArguments;
+using android::security::keymaster::KeymasterBlob;
+using android::security::keymaster::OperationResult;
+
+using KSReturn = keystore::KeyStoreNativeReturnCode;
+
 namespace {
 const char keystore_service_name[] = "android.security.keystore";
-};
+constexpr int32_t UID_SELF = -1;
+
+using keystore::KeyCharacteristicsPromise;
+using keystore::KeystoreExportPromise;
+using keystore::KeystoreResponsePromise;
+using keystore::OperationResultPromise;
+
+}  // namespace
+
+#define AT __func__ << ":" << __LINE__ << " "
+
+static NullOr<const Algorithm&> getKeyAlgoritmFromKeyCharacteristics(
+    const ::android::security::keymaster::KeyCharacteristics& characteristics) {
+    for (const auto& param : characteristics.hardwareEnforced.getParameters()) {
+        auto algo = authorizationValue(TAG_ALGORITHM, param);
+        if (algo.isOk()) return algo;
+    }
+    for (const auto& param : characteristics.softwareEnforced.getParameters()) {
+        auto algo = authorizationValue(TAG_ALGORITHM, param);
+        if (algo.isOk()) return algo;
+    }
+    return {};
+}
+
+KeystoreBackendBinder::KeystoreBackendBinder() {
+    android::ProcessState::self()->startThreadPool();
+}
 
 int32_t KeystoreBackendBinder::sign(const char* key_id, const uint8_t* in, size_t len,
                                     uint8_t** reply, size_t* reply_len) {
@@ -42,21 +99,146 @@
     sp<IBinder> binder = sm->getService(String16(keystore_service_name));
     sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
 
-    if (service == NULL) {
-        ALOGE("could not contact keystore");
+    if (service == nullptr) {
+        LOG(ERROR) << AT << "could not contact keystore";
         return -1;
     }
 
-    auto inBlob = blob2hidlVec(in, len);
-    std::vector<uint8_t> reply_vec;
-    auto ret = service->sign(String16(key_id), inBlob, &reply_vec);
-    if (!ret.isOk()) {
+    String16 key_name16(key_id);
+    int32_t error_code;
+    android::sp<KeyCharacteristicsPromise> kc_promise(new KeyCharacteristicsPromise);
+    auto kc_future = kc_promise->get_future();
+    auto binder_result = service->getKeyCharacteristics(kc_promise, key_name16, KeymasterBlob(),
+                                                        KeymasterBlob(), UID_SELF, &error_code);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
+        return -1;
+    }
+    if (KSReturn(error_code).isOk()) {
+        LOG(ERROR) << AT << "getKeyCharacteristics failed: " << error_code;
         return -1;
     }
 
-    hidl_vec<uint8_t> reply_hidl(reply_vec);  // makes copy
-    *reply = reply_hidl.releaseData();
-    *reply_len = reply_vec.size();
+    auto [km_response, characteristics] = kc_future.get();
+
+    if (KSReturn(km_response.response_code()).isOk()) {
+        LOG(ERROR) << AT << "getKeyCharacteristics failed: " << km_response.response_code();
+        return -1;
+    }
+
+    auto algorithm = getKeyAlgoritmFromKeyCharacteristics(characteristics);
+    if (!algorithm.isOk()) {
+        LOG(ERROR) << AT << "could not get algorithm from key characteristics";
+        return -1;
+    }
+
+    hidl_vec<KeyParameter> params(3);
+    params[0] = Authorization(TAG_DIGEST, Digest::NONE);
+    params[1] = Authorization(TAG_PADDING, PaddingMode::NONE);
+    params[2] = Authorization(TAG_ALGORITHM, algorithm.value());
+
+    android::sp<android::IBinder> token(new android::BBinder);
+    sp<OperationResultPromise> promise(new OperationResultPromise());
+    auto future = promise->get_future();
+    binder_result = service->begin(promise, token, key_name16, (int)KeyPurpose::SIGN,
+                                   true /*pruneable*/, KeymasterArguments(params),
+                                   std::vector<uint8_t>() /* entropy */, UID_SELF, &error_code);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
+        return -1;
+    }
+
+    keystore::KeyStoreNativeReturnCode rc(error_code);
+    if (!rc.isOk()) {
+        LOG(ERROR) << AT << "Keystore begin returned: " << error_code;
+        return -1;
+    }
+    OperationResult result = future.get();
+
+    if (!result.resultCode.isOk()) {
+        LOG(ERROR) << AT << "begin failed: " << result.resultCode;
+        return -1;
+    }
+    auto handle = std::move(result.token);
+
+    do {
+        future = {};
+        promise = new OperationResultPromise();
+        future = promise->get_future();
+        binder_result = service->update(promise, handle, KeymasterArguments(params),
+                                        std::vector<uint8_t>(in, in + len), &error_code);
+        if (!binder_result.isOk()) {
+            LOG(ERROR) << AT << "communication error while calling keystore";
+            return -1;
+        }
+
+        rc = keystore::KeyStoreNativeReturnCode(error_code);
+        if (!rc.isOk()) {
+            LOG(ERROR) << AT << "Keystore update returned: " << error_code;
+            return -1;
+        }
+        result = future.get();
+
+        if (!result.resultCode.isOk()) {
+            LOG(ERROR) << AT << "update failed: " << result.resultCode;
+            return -1;
+        }
+
+        if (result.inputConsumed > len) {
+            LOG(ERROR) << AT << "update consumed more data than provided";
+            sp<KeystoreResponsePromise> abortPromise(new KeystoreResponsePromise);
+            auto abortFuture = abortPromise->get_future();
+            binder_result = service->abort(abortPromise, handle, &error_code);
+            if (!binder_result.isOk()) {
+                LOG(ERROR) << AT << "communication error while calling keystore";
+                return -1;
+            }
+            // This is mainly for logging since we already failed.
+            // But if abort returned OK we have to wait untill abort calls the callback
+            // hence the call to abortFuture.get().
+            if (!KSReturn(error_code).isOk()) {
+                LOG(ERROR) << AT << "abort failed: " << error_code;
+            } else if (!(rc = KSReturn(abortFuture.get().response_code())).isOk()) {
+                LOG(ERROR) << AT << "abort failed: " << rc;
+            }
+            return -1;
+        }
+        len -= result.inputConsumed;
+        in += result.inputConsumed;
+    } while (len > 0);
+
+    future = {};
+    promise = new OperationResultPromise();
+    future = promise->get_future();
+
+    binder_result = service->finish(promise, handle, KeymasterArguments(params),
+                                    std::vector<uint8_t>() /* signature */,
+                                    std::vector<uint8_t>() /* entropy */, &error_code);
+
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
+        return -1;
+    }
+
+    rc = keystore::KeyStoreNativeReturnCode(error_code);
+    if (!rc.isOk()) {
+        LOG(ERROR) << AT << "Keystore finish returned: " << error_code;
+        return -1;
+    }
+    result = future.get();
+
+    if (!result.resultCode.isOk()) {
+        LOG(ERROR) << AT << "finish failed: " << result.resultCode;
+        return -1;
+    }
+
+    hidl_vec<uint8_t> reply_hidl(result.data);
+    if (reply_len) {
+        *reply_len = reply_hidl.size();
+    }
+    if (reply) {
+        *reply = reply_hidl.releaseData();
+    }
     return 0;
 }
 
@@ -66,19 +248,39 @@
     sp<IBinder> binder = sm->getService(String16(keystore_service_name));
     sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
 
-    if (service == NULL) {
-        ALOGE("could not contact keystore");
+    if (service == nullptr) {
+        LOG(ERROR) << AT << "could not contact keystore";
         return -1;
     }
 
-    std::vector<uint8_t> pubkey_vec;
-    auto ret = service->get_pubkey(String16(key_id), &pubkey_vec);
-    if (!ret.isOk()) {
+    int32_t error_code;
+    android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise);
+    auto future = promise->get_future();
+    auto binder_result = service->exportKey(
+        promise, String16(key_id), static_cast<int32_t>(KeyFormat::X509),
+        KeymasterBlob() /* clientId */, KeymasterBlob() /* appData */, UID_SELF, &error_code);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
         return -1;
     }
 
-    hidl_vec<uint8_t> hidl_pubkey(pubkey_vec);  // makes copy
-    *pubkey = hidl_pubkey.releaseData();        // caller should clean up memory.
-    *pubkey_len = pubkey_vec.size();
+    KSReturn rc(error_code);
+    if (!rc.isOk()) {
+        LOG(ERROR) << AT << "exportKey failed: " << error_code;
+        return -1;
+    }
+
+    auto export_result = future.get();
+    if (!export_result.resultCode.isOk()) {
+        LOG(ERROR) << AT << "exportKey failed: " << export_result.resultCode;
+        return -1;
+    }
+
+    if (pubkey_len) {
+        *pubkey_len = export_result.exportData.size();
+    }
+    if (pubkey) {
+        *pubkey = export_result.exportData.releaseData();
+    }
     return 0;
 }
diff --git a/keystore-engine/keystore_backend_binder.h b/keystore-engine/keystore_backend_binder.h
index 1db90f7..4c828c5 100644
--- a/keystore-engine/keystore_backend_binder.h
+++ b/keystore-engine/keystore_backend_binder.h
@@ -27,7 +27,7 @@
 
 class KeystoreBackendBinder : public KeystoreBackend {
   public:
-    KeystoreBackendBinder() {}
+    KeystoreBackendBinder();
     virtual ~KeystoreBackendBinder() {}
     int32_t sign(const char *key_id, const uint8_t* in, size_t len,
                  uint8_t** reply, size_t* reply_len) override;
diff --git a/keystore-engine/keystore_backend_hidl.cpp b/keystore-engine/keystore_backend_hidl.cpp
index 9a84e67..30cf890 100644
--- a/keystore-engine/keystore_backend_hidl.cpp
+++ b/keystore-engine/keystore_backend_hidl.cpp
@@ -33,13 +33,13 @@
 int32_t KeystoreBackendHidl::sign(
         const char *key_id, const uint8_t* in, size_t len, uint8_t** reply,
         size_t* reply_len) {
-    if (key_id == NULL || in == NULL || reply == NULL || reply_len == NULL) {
+    if (key_id == nullptr || in == nullptr || reply == nullptr || reply_len == nullptr) {
         ALOGE("Null pointer argument passed");
         return -1;
     }
 
     sp<IKeystore> service = IKeystore::tryGetService();
-    if (service == NULL) {
+    if (service == nullptr) {
         ALOGE("could not contact keystore HAL");
         return -1;
     }
@@ -63,13 +63,13 @@
 
 int32_t KeystoreBackendHidl::get_pubkey(
         const char *key_id, uint8_t** pubkey, size_t* pubkey_len) {
-    if (key_id == NULL || pubkey == NULL || pubkey_len == NULL) {
+    if (key_id == nullptr || pubkey == nullptr || pubkey_len == nullptr) {
         ALOGE("Null pointer argument passed");
         return -1;
     }
 
     sp<IKeystore> service = IKeystore::tryGetService();
-    if (service == NULL) {
+    if (service == nullptr) {
         ALOGE("could not contact keystore HAL");
         return -1;
     }
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 9ce00c2..9bd363f 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -31,6 +31,7 @@
         "key_store_service.cpp",
         "keyblob_utils.cpp",
         "keymaster_enforcement.cpp",
+        "keymaster_worker.cpp",
         "keystore_attestation_id.cpp",
         "keystore_main.cpp",
         "keystore_utils.cpp",
@@ -49,6 +50,7 @@
         "libbase",
         "libbinder",
         "libcrypto",
+        "libcutils",
         "libhardware",
         "libhidlbase",
         "libhidltransport",
@@ -76,6 +78,13 @@
         pdk: {
             enabled: false,
         },
+	debuggable: {
+            cflags: [
+                // Allow VTS tests running as root to have
+                // additional permissions.
+                "-DGRANT_ROOT_ALL_PERMISSIONS",
+            ],
+        },
     },
 
     required: ["keystore_cli_v2"],
@@ -84,7 +93,6 @@
 cc_binary {
     name: "keystore_cli",
     defaults: ["keystore_defaults"],
-    tags: ["debug"],
 
     srcs: ["keystore_cli.cpp"],
     shared_libs: [
@@ -105,7 +113,6 @@
 cc_binary {
     name: "keystore_cli_v2",
     defaults: ["keystore_defaults"],
-    tags: ["debug"],
 
     cflags: [
         "-DKEYMASTER_NAME_TAGS",
@@ -137,10 +144,10 @@
         "KeyAttestationApplicationId.cpp",
         "KeyAttestationPackageInfo.cpp",
         "KeymasterArguments.cpp",
-        "KeystoreArguments.cpp",
+        "keystore_aidl_hidl_marshalling_utils.cpp",
+        "KeystoreResponse.cpp",
         "OperationResult.cpp",
         "Signature.cpp",
-        "keystore_aidl_hidl_marshalling_utils.cpp",
     ],
     shared_libs: [
         "android.hardware.keymaster@4.0",
@@ -230,16 +237,26 @@
     defaults: ["keystore_defaults"],
 
     srcs: [
+        ":IKeyAttestationApplicationIdProvider.aidl",
         "auth_token_table.cpp",
+        "blob.cpp",
+        "keystore_attestation_id.cpp",
+        "KeyAttestationApplicationId.cpp",
+        "KeyAttestationPackageInfo.cpp",
+        "Signature.cpp",
     ],
     cflags: [ "-O0", ],
     static_libs: ["libgtest_main"],
     shared_libs: [
         "android.hardware.keymaster@4.0",
+        "libbinder",
+        "libcrypto",
         "libhidlbase",
         "libhwbinder",
         "libkeymaster4support",
         "libutils",
+        "libkeystore_aidl",
+        "libkeystore_parcelables",
     ],
     export_shared_lib_headers: [
         "android.hardware.keymaster@4.0",
@@ -248,6 +265,9 @@
         "libkeymaster4support",
     ],
 
+    aidl: {
+        include_dirs: ["frameworks/base/core/java/"],
+    },
     export_include_dirs: ["include"],
 }
 
@@ -255,8 +275,14 @@
     name: "keystore_aidl",
     srcs: [
         "binder/android/security/IConfirmationPromptCallback.aidl",
-        "binder/android/security/IKeystoreService.aidl",
+        "binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl",
+        "binder/android/security/keystore/IKeystoreExportKeyCallback.aidl",
+        "binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl",
+        "binder/android/security/keystore/IKeystoreOperationResultCallback.aidl",
+        "binder/android/security/keystore/IKeystoreResponseCallback.aidl",
+        "binder/android/security/keystore/IKeystoreService.aidl",
     ],
+    path: "binder",
 }
 
 cc_library_shared {
@@ -285,5 +311,3 @@
         "libkeystore_parcelables",
     ],
 }
-
-subdirs = ["tests"]
diff --git a/keystore/KeyAttestationApplicationId.cpp b/keystore/KeyAttestationApplicationId.cpp
index 4bc939d..c62571f 100644
--- a/keystore/KeyAttestationApplicationId.cpp
+++ b/keystore/KeyAttestationApplicationId.cpp
@@ -31,6 +31,9 @@
     packageInfos_->push_back(std::move(package));
 }
 
+KeyAttestationApplicationId::KeyAttestationApplicationId(PackageInfoVector packages)
+    : packageInfos_(std::make_shared<PackageInfoVector>(std::move(packages))) {}
+
 status_t KeyAttestationApplicationId::writeToParcel(Parcel* parcel) const {
     return parcel->writeParcelableVector(packageInfos_);
 }
diff --git a/keystore/KeyStore.cpp b/keystore/KeyStore.cpp
index 428b51e..6e8a4b2 100644
--- a/keystore/KeyStore.cpp
+++ b/keystore/KeyStore.cpp
@@ -28,7 +28,7 @@
 
 #include <android-base/scopeguard.h>
 #include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
 #include <log/log_event_list.h>
 
 #include <private/android_logger.h>
@@ -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,24 @@
 
 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(const KeymasterDevices& kmDevices,
                    SecurityLevel minimalAllowedSecurityLevelForNewKeys)
-    : mKmDevices(kmDevices),
-      mAllowNewFallback(minimalAllowedSecurityLevelForNewKeys == SecurityLevel::SOFTWARE) {
+    : 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 +79,92 @@
 }
 
 ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
-    UserState* userState = getUserState(userId);
+    auto userState = mUserStateDB.getUserState(userId);
     return userState->initialize(pw);
 }
 
 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);
 }
 
 ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) {
-    UserState* userState = getUserState(userId);
+    auto userState = mUserStateDB.getUserState(userId);
     return userState->readMasterKey(pw);
 }
 
-/* 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) {
+
+    auto userState = mUserStateDB.getUserState(userId);
+    std::string userDirName = userState->getUserDirName();
+    auto encryptionKey = userState->getEncryptionKey();
+    auto state = userState->getState();
+    // userState is a proxy that holds a lock which may be required by a worker.
+    // LockedKeyBlobEntry::list has a fence that waits until all workers have finished which may
+    // not happen if a user state lock is held. The following line relinquishes the lock.
+    userState = {};
+
+    ResponseCode rc;
+    std::list<LockedKeyBlobEntry> matches;
+
+    // must not be called by a keymaster worker. List waits for workers to relinquish all access
+    // to blob entries
+    std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);
+    if (rc != ResponseCode::NO_ERROR) {
         return;
     }
-    for (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 +183,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,335 +206,138 @@
 }
 
 bool KeyStore::isEmpty(uid_t userId) const {
-    const UserState* userState = getUserState(userId);
-    if (userState == NULL) {
-        return true;
-    }
-
-    DIR* dir = opendir(userState->getUserDirName());
-    if (!dir) {
-        return true;
-    }
-
-    bool result = true;
-    struct dirent* file;
-    while ((file = readdir(dir)) != NULL) {
-        // We only care about files.
-        if (file->d_type != DT_REG) {
-            continue;
+    std::string userDirName;
+    {
+        // userState holds a lock which must be relinquished before list is called. This scope
+        // prevents deadlocks.
+        auto userState = mUserStateDB.getUserState(userId);
+        if (!userState) {
+            return true;
         }
-
-        // 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());
+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());
 }
 
-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)) != NULL) {
-        // 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 != NULL) {
-                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(NULL, &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(), NULL, 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
@@ -605,74 +352,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 NULL;
-}
-
-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 */
@@ -689,7 +396,6 @@
      * and write it.
      */
     if (updated) {
-        ALOGV("updated and writing file %s", filename);
         blob->setVersion(version);
     }
 
@@ -701,43 +407,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() == NULL) {
-        ALOGE("Problem instantiating BIO");
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL));
-    if (pkey.get() == NULL) {
-        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(), NULL);
-    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) {
@@ -771,14 +440,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;
             }
@@ -796,7 +465,7 @@
         }
 
         struct dirent* file;
-        while ((file = readdir(dir)) != NULL) {
+        while ((file = readdir(dir)) != nullptr) {
             // We only care about files.
             if (file->d_type != DT_REG) {
                 continue;
@@ -813,14 +482,14 @@
             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());
-            if (otherdir == NULL) {
+            DIR* otherdir = opendir(otherUser->getUserDirName().c_str());
+            if (otherdir == nullptr) {
                 ALOGW("couldn't open user directory for rename");
                 continue;
             }
@@ -838,16 +507,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 f0fe9d3..69a02ae 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> struct tuple_size<keystore::Devices<T, count>> {
+  public:
+    static constexpr size_t value = std::tuple_size<std::array<T, count>>::value;
+};
+}  // namespace std
+
+namespace keystore {
+
+using KeymasterWorkers = Devices<std::shared_ptr<KeymasterWorker>, 3>;
+using KeymasterDevices = Devices<sp<Keymaster>, 3>;
+
+class KeyStore : public ::android::IBinder::DeathRecipient {
   public:
     KeyStore(const KeymasterDevices& kmDevices,
              SecurityLevel minimalAllowedSecurityLevelForNewKeys);
     ~KeyStore();
 
-    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;
@@ -141,10 +149,14 @@
     static const android::String16 kRsaKeyType;
     static const android::String16 kEcKeyType;
 
-    KeymasterDevices mKmDevices;
+    KeymasterWorkers mKmDevices;
+
     bool mAllowNewFallback;
 
-    android::Vector<UserState*> mMasterKeys;
+    UserStateDB mUserStateDB;
+    AuthTokenTable mAuthTokenTable;
+    KeystoreKeymasterEnforcement mEnforcementPolicy;
+    sp<ConfirmationManager> mConfirmationManager;
 
     ::keystore::GrantStore mGrants;
 
@@ -155,15 +167,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/KeystoreArguments.cpp b/keystore/KeystoreArguments.cpp
deleted file mode 100644
index fe53c29..0000000
--- a/keystore/KeystoreArguments.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-**
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include "include/keystore/KeystoreArguments.h"
-#include "keystore_aidl_hidl_marshalling_utils.h"
-
-#include <binder/Parcel.h>
-
-namespace android {
-namespace security {
-
-using ::android::security::KeystoreArg;
-using ::android::security::KeystoreArguments;
-
-const ssize_t MAX_GENERATE_ARGS = 3;
-status_t KeystoreArguments::readFromParcel(const android::Parcel* in) {
-    ssize_t numArgs = in->readInt32();
-    if (numArgs > MAX_GENERATE_ARGS) {
-        return BAD_VALUE;
-    }
-    if (numArgs > 0) {
-        for (size_t i = 0; i < static_cast<size_t>(numArgs); i++) {
-            ssize_t inSize = in->readInt32();
-            if (inSize >= 0 && static_cast<size_t>(inSize) <= in->dataAvail()) {
-                sp<KeystoreArg> arg = new KeystoreArg(in->readInplace(inSize), inSize);
-                args.push_back(arg);
-            } else {
-                args.push_back(NULL);
-            }
-        }
-    }
-    return OK;
-};
-
-status_t KeystoreArguments::writeToParcel(android::Parcel* out) const {
-    out->writeInt32(args.size());
-    for (sp<KeystoreArg> item : args) {
-        size_t keyLength = item->size();
-        out->writeInt32(keyLength);
-        void* buf = out->writeInplace(keyLength);
-        memcpy(buf, item->data(), keyLength);
-    }
-    return OK;
-}
-
-}  // namespace security
-}  // namespace android
diff --git a/keystore/KeystoreResponse.cpp b/keystore/KeystoreResponse.cpp
new file mode 100644
index 0000000..c46973a
--- /dev/null
+++ b/keystore/KeystoreResponse.cpp
@@ -0,0 +1,43 @@
+/*
+**
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <binder/Parcel.h>
+#include <keystore/keymaster_types.h>
+#include <utility>
+#include <utils/String16.h>
+
+#include "include/keystore/KeystoreResponse.h"
+
+namespace android {
+namespace security {
+namespace keystore {
+
+status_t KeystoreResponse::readFromParcel(const Parcel* in) {
+    auto rc = in->readInt32(&response_code_);
+    if (rc != NO_ERROR) return rc;
+    return in->readString16(&error_msg_);
+}
+
+status_t KeystoreResponse::writeToParcel(Parcel* out) const {
+    auto rc = out->writeInt32(response_code_);
+    if (rc != NO_ERROR) return rc;
+    return out->writeString16(error_msg_);
+}
+
+}  // namespace keystore
+}  // namespace security
+}  // namespace android
diff --git a/keystore/OperationResult.cpp b/keystore/OperationResult.cpp
index 53c8d62..3ff8bc3 100644
--- a/keystore/OperationResult.cpp
+++ b/keystore/OperationResult.cpp
@@ -46,7 +46,7 @@
 }
 
 status_t OperationResult::writeToParcel(Parcel* out) const {
-    out->writeInt32(resultCode);
+    out->writeInt32(resultCode.getErrorCode());
     out->writeStrongBinder(token);
     out->writeInt64(handle);
     out->writeInt32(inputConsumed);
@@ -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/Signature.cpp b/keystore/Signature.cpp
index 1566df9..284f358 100644
--- a/keystore/Signature.cpp
+++ b/keystore/Signature.cpp
@@ -31,6 +31,8 @@
     return parcel->readByteVector(&sig_data_);
 }
 
+Signature::Signature(std::vector<uint8_t> signature_data) : sig_data_(std::move(signature_data)) {}
+
 }  // namespace pm
 }  // namespace content
 }  // namespace android
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
index 3c51c70..6bffa7c 100644
--- a/keystore/auth_token_table.cpp
+++ b/keystore/auth_token_table.cpp
@@ -23,7 +23,7 @@
 
 #include <algorithm>
 
-#include <cutils/log.h>
+#include <log/log.h>
 
 namespace keystore {
 
@@ -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) {
-    Entry* newest_match = NULL;
+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 db60003..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;
@@ -97,9 +104,9 @@
     class Entry {
       public:
         Entry(HardwareAuthToken&& token, time_t current_time);
-        Entry(Entry&& entry) { *this = std::move(entry); }
+        Entry(Entry&& entry) noexcept { *this = std::move(entry); }
 
-        void operator=(Entry&& rhs) {
+        void operator=(Entry&& rhs) noexcept {
             token_ = std::move(rhs.token_);
             time_received_ = rhs.time_received_;
             last_use_ = rhs.last_use_;
@@ -142,16 +149,21 @@
         bool operation_completed_;
     };
 
-    Error FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
-                                     HardwareAuthenticatorType auth_type, uint64_t op_handle,
-                                     const HardwareAuthToken** found);
-    Error FindTimedAuthorization(const std::vector<uint64_t>& sids,
-                                 HardwareAuthenticatorType auth_type,
-                                 const AuthorizationSet& key_info, const HardwareAuthToken** found);
+    std::tuple<Error, HardwareAuthToken>
+    FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
+                               HardwareAuthenticatorType auth_type, uint64_t op_handle);
+    std::tuple<Error, HardwareAuthToken> FindTimedAuthorization(const std::vector<uint64_t>& sids,
+                                                                HardwareAuthenticatorType auth_type,
+                                                                const AuthorizationSet& key_info);
     void ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids);
     void RemoveEntriesSupersededBy(const Entry& entry);
     bool IsSupersededBySomeEntry(const Entry& entry);
 
+    /**
+     * Guards the entries_ vector against concurrent modification. All public facing methods
+     * reading of modifying the vector must grab this mutex.
+     */
+    mutable std::mutex entries_mutex_;
     std::vector<Entry> entries_;
     size_t max_entries_;
     time_t last_off_body_;
diff --git a/keystore/authorization_set.cpp b/keystore/authorization_set.cpp
deleted file mode 100644
index 537fe3d..0000000
--- a/keystore/authorization_set.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <keystore/keymaster_types.h>
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits>
-#include <ostream>
-#include <istream>
-
-#include <new>
-
-namespace keystore {
-
-inline bool keyParamLess(const KeyParameter& a, const KeyParameter& b) {
-    if (a.tag != b.tag) return a.tag < b.tag;
-    int retval;
-    switch (typeFromTag(a.tag)) {
-    case TagType::INVALID:
-    case TagType::BOOL:
-        return false;
-    case TagType::ENUM:
-    case TagType::ENUM_REP:
-    case TagType::UINT:
-    case TagType::UINT_REP:
-        return a.f.integer < b.f.integer;
-    case TagType::ULONG:
-    case TagType::ULONG_REP:
-        return a.f.longInteger < b.f.longInteger;
-    case TagType::DATE:
-        return a.f.dateTime < b.f.dateTime;
-    case TagType::BIGNUM:
-    case TagType::BYTES:
-        // Handle the empty cases.
-        if (a.blob.size() == 0)
-            return b.blob.size() != 0;
-        if (b.blob.size() == 0) return false;
-
-        retval = memcmp(&a.blob[0], &b.blob[0], std::min(a.blob.size(), b.blob.size()));
-        // if one is the prefix of the other the longer wins
-        if (retval == 0) return a.blob.size() < b.blob.size();
-        // Otherwise a is less if a is less.
-        else return retval < 0;
-    }
-    return false;
-}
-
-inline bool keyParamEqual(const KeyParameter& a, const KeyParameter& b) {
-    if (a.tag != b.tag) return false;
-
-    switch (typeFromTag(a.tag)) {
-    case TagType::INVALID:
-    case TagType::BOOL:
-        return true;
-    case TagType::ENUM:
-    case TagType::ENUM_REP:
-    case TagType::UINT:
-    case TagType::UINT_REP:
-        return a.f.integer == b.f.integer;
-    case TagType::ULONG:
-    case TagType::ULONG_REP:
-        return a.f.longInteger == b.f.longInteger;
-    case TagType::DATE:
-        return a.f.dateTime == b.f.dateTime;
-    case TagType::BIGNUM:
-    case TagType::BYTES:
-        if (a.blob.size() != b.blob.size()) return false;
-        return a.blob.size() == 0 ||
-                memcmp(&a.blob[0], &b.blob[0], a.blob.size()) == 0;
-    }
-    return false;
-}
-
-void AuthorizationSet::Sort() {
-    std::sort(data_.begin(), data_.end(), keyParamLess);
-}
-
-void AuthorizationSet::Deduplicate() {
-    if (data_.empty()) return;
-
-    Sort();
-    std::vector<KeyParameter> result;
-
-    auto curr = data_.begin();
-    auto prev = curr++;
-    for (; curr != data_.end(); ++prev, ++curr) {
-        if (prev->tag == Tag::INVALID) continue;
-
-        if (!keyParamEqual(*prev, *curr)) {
-            result.emplace_back(std::move(*prev));
-        }
-    }
-    result.emplace_back(std::move(*prev));
-
-    std::swap(data_, result);
-}
-
-void AuthorizationSet::Union(const AuthorizationSet& other) {
-    data_.insert(data_.end(), other.data_.begin(), other.data_.end());
-    Deduplicate();
-}
-
-void AuthorizationSet::Subtract(const AuthorizationSet& other) {
-    Deduplicate();
-
-    auto i = other.begin();
-    while (i != other.end()) {
-        int pos = -1;
-        do {
-            pos = find(i->tag, pos);
-            if (pos != -1 && keyParamEqual(*i, data_[pos])) {
-                data_.erase(data_.begin() + pos);
-                break;
-            }
-        } while (pos != -1);
-        ++i;
-    }
-}
-
-int AuthorizationSet::find(Tag tag, int begin) const {
-    auto iter = data_.begin() + (1 + begin);
-
-    while (iter != data_.end() && iter->tag != tag) ++iter;
-
-    if (iter != data_.end()) return iter - data_.begin();
-    return -1;
-}
-
-bool AuthorizationSet::erase(int index) {
-    auto pos = data_.begin() + index;
-    if (pos != data_.end()) {
-        data_.erase(pos);
-        return true;
-    }
-    return false;
-}
-
-KeyParameter& AuthorizationSet::operator[](int at) {
-    return data_[at];
-}
-
-const KeyParameter& AuthorizationSet::operator[](int at) const {
-    return data_[at];
-}
-
-void AuthorizationSet::Clear() {
-    data_.clear();
-}
-
-size_t AuthorizationSet::GetTagCount(Tag tag) const {
-    size_t count = 0;
-    for (int pos = -1; (pos = find(tag, pos)) != -1;)
-        ++count;
-    return count;
-}
-
-NullOr<const KeyParameter&> AuthorizationSet::GetEntry(Tag tag) const {
-    int pos = find(tag);
-    if (pos == -1) return {};
-    return data_[pos];
-}
-
-/**
- * Persistent format is:
- * | 32 bit indirect_size         |
- * --------------------------------
- * | indirect_size bytes of data  | this is where the blob data is stored
- * --------------------------------
- * | 32 bit element_count         | number of entries
- * | 32 bit elements_size         | total bytes used by entries (entries have variable length)
- * --------------------------------
- * | elementes_size bytes of data | where the elements are stored
- */
-
-/**
- * Persistent format of blobs and bignums:
- * | 32 bit tag             |
- * | 32 bit blob_length     |
- * | 32 bit indirect_offset |
- */
-
-struct OutStreams {
-    std::ostream& indirect;
-    std::ostream& elements;
-};
-
-OutStreams& serializeParamValue(OutStreams& out, const hidl_vec<uint8_t>& blob) {
-    uint32_t buffer;
-
-    // write blob_length
-    auto blob_length = blob.size();
-    if (blob_length > std::numeric_limits<uint32_t>::max()) {
-        out.elements.setstate(std::ios_base::badbit);
-        return out;
-    }
-    buffer = blob_length;
-    out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
-
-    // write indirect_offset
-    auto offset = out.indirect.tellp();
-    if (offset < 0 || offset > std::numeric_limits<uint32_t>::max() ||
-            uint32_t(offset) + uint32_t(blob_length) < uint32_t(offset)) { // overflow check
-        out.elements.setstate(std::ios_base::badbit);
-        return out;
-    }
-    buffer = offset;
-    out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
-
-    // write blob to indirect stream
-    if(blob_length)
-        out.indirect.write(reinterpret_cast<const char*>(&blob[0]), blob_length);
-
-    return out;
-}
-
-template <typename T>
-OutStreams& serializeParamValue(OutStreams& out, const T& value) {
-    out.elements.write(reinterpret_cast<const char*>(&value), sizeof(T));
-    return out;
-}
-
-OutStreams& serialize(TAG_INVALID_t&&, OutStreams& out, const KeyParameter&) {
-    // skip invalid entries.
-    return out;
-}
-template <typename T>
-OutStreams& serialize(T ttag, OutStreams& out, const KeyParameter& param) {
-    out.elements.write(reinterpret_cast<const char*>(&param.tag), sizeof(int32_t));
-    return serializeParamValue(out, accessTagValue(ttag, param));
-}
-
-template <typename... T>
-struct choose_serializer;
-template <typename... Tags>
-struct choose_serializer<MetaList<Tags...>> {
-    static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
-        return choose_serializer<Tags...>::serialize(out, param);
-    }
-};
-template <>
-struct choose_serializer<> {
-    static OutStreams& serialize(OutStreams& out, const KeyParameter&) {
-        return out;
-    }
-};
-template <TagType tag_type, Tag tag, typename... Tail>
-struct choose_serializer<TypedTag<tag_type, tag>, Tail...> {
-    static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
-        if (param.tag == tag) {
-            return keystore::serialize(TypedTag<tag_type, tag>(), out, param);
-        } else {
-            return choose_serializer<Tail...>::serialize(out, param);
-        }
-    }
-};
-
-OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
-    return choose_serializer<all_tags_t>::serialize(out, param);
-}
-
-std::ostream& serialize(std::ostream& out, const std::vector<KeyParameter>& params) {
-    std::stringstream indirect;
-    std::stringstream elements;
-    OutStreams streams = { indirect, elements };
-    for (const auto& param: params) {
-        serialize(streams, param);
-    }
-    if (indirect.bad() || elements.bad()) {
-        out.setstate(std::ios_base::badbit);
-        return out;
-    }
-    auto pos = indirect.tellp();
-    if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
-        out.setstate(std::ios_base::badbit);
-        return out;
-    }
-    uint32_t indirect_size = pos;
-    pos = elements.tellp();
-    if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
-        out.setstate(std::ios_base::badbit);
-        return out;
-    }
-    uint32_t elements_size = pos;
-    uint32_t element_count = params.size();
-
-    out.write(reinterpret_cast<const char*>(&indirect_size), sizeof(uint32_t));
-
-    pos = out.tellp();
-    if (indirect_size)
-        out << indirect.rdbuf();
-    assert(out.tellp() - pos == indirect_size);
-
-    out.write(reinterpret_cast<const char*>(&element_count), sizeof(uint32_t));
-    out.write(reinterpret_cast<const char*>(&elements_size), sizeof(uint32_t));
-
-    pos = out.tellp();
-    if (elements_size)
-        out << elements.rdbuf();
-    assert(out.tellp() - pos == elements_size);
-
-    return out;
-}
-
-struct InStreams {
-    std::istream& indirect;
-    std::istream& elements;
-};
-
-InStreams& deserializeParamValue(InStreams& in, hidl_vec<uint8_t>* blob) {
-    uint32_t blob_length = 0;
-    uint32_t offset = 0;
-    in.elements.read(reinterpret_cast<char*>(&blob_length), sizeof(uint32_t));
-    blob->resize(blob_length);
-    in.elements.read(reinterpret_cast<char*>(&offset), sizeof(uint32_t));
-    in.indirect.seekg(offset);
-    in.indirect.read(reinterpret_cast<char*>(&(*blob)[0]), blob->size());
-    return in;
-}
-
-template <typename T>
-InStreams& deserializeParamValue(InStreams& in, T* value) {
-    in.elements.read(reinterpret_cast<char*>(value), sizeof(T));
-    return in;
-}
-
-InStreams& deserialize(TAG_INVALID_t&&, InStreams& in, KeyParameter*) {
-    // there should be no invalid KeyParamaters but if handle them as zero sized.
-    return in;
-}
-
-template <typename T>
-InStreams& deserialize(T&& ttag, InStreams& in, KeyParameter* param) {
-    return deserializeParamValue(in, &accessTagValue(ttag, *param));
-}
-
-template <typename... T>
-struct choose_deserializer;
-template <typename... Tags>
-struct choose_deserializer<MetaList<Tags...>> {
-    static InStreams& deserialize(InStreams& in, KeyParameter* param) {
-        return choose_deserializer<Tags...>::deserialize(in, param);
-    }
-};
-template <>
-struct choose_deserializer<> {
-    static InStreams& deserialize(InStreams& in, KeyParameter*) {
-        // encountered an unknown tag -> fail parsing
-        in.elements.setstate(std::ios_base::badbit);
-        return in;
-    }
-};
-template <TagType tag_type, Tag tag, typename... Tail>
-struct choose_deserializer<TypedTag<tag_type, tag>, Tail...> {
-    static InStreams& deserialize(InStreams& in, KeyParameter* param) {
-        if (param->tag == tag) {
-            return keystore::deserialize(TypedTag<tag_type, tag>(), in, param);
-        } else {
-            return choose_deserializer<Tail...>::deserialize(in, param);
-        }
-    }
-};
-
-InStreams& deserialize(InStreams& in, KeyParameter* param) {
-    in.elements.read(reinterpret_cast<char*>(&param->tag), sizeof(Tag));
-    return choose_deserializer<all_tags_t>::deserialize(in, param);
-}
-
-std::istream& deserialize(std::istream& in, std::vector<KeyParameter>* params) {
-    uint32_t indirect_size = 0;
-    in.read(reinterpret_cast<char*>(&indirect_size), sizeof(uint32_t));
-    std::string indirect_buffer(indirect_size, '\0');
-    if (indirect_buffer.size() != indirect_size) {
-        in.setstate(std::ios_base::badbit);
-        return in;
-    }
-    in.read(&indirect_buffer[0], indirect_buffer.size());
-
-    uint32_t element_count = 0;
-    in.read(reinterpret_cast<char*>(&element_count), sizeof(uint32_t));
-    uint32_t elements_size = 0;
-    in.read(reinterpret_cast<char*>(&elements_size), sizeof(uint32_t));
-
-    std::string elements_buffer(elements_size, '\0');
-    if(elements_buffer.size() != elements_size) {
-        in.setstate(std::ios_base::badbit);
-        return in;
-    }
-    in.read(&elements_buffer[0], elements_buffer.size());
-
-    if (in.bad()) return in;
-
-    // TODO write one-shot stream buffer to avoid copying here
-    std::stringstream indirect(indirect_buffer);
-    std::stringstream elements(elements_buffer);
-    InStreams streams = { indirect, elements };
-
-    params->resize(element_count);
-
-    for (uint32_t i = 0; i < element_count; ++i) {
-        deserialize(streams, &(*params)[i]);
-    }
-    return in;
-}
-void AuthorizationSet::Serialize(std::ostream* out) const {
-    serialize(*out, data_);
-}
-void AuthorizationSet::Deserialize(std::istream* in) {
-    deserialize(*in, &data_);
-}
-
-}  // namespace keystore
diff --git a/keystore/binder/android/security/IKeystoreService.aidl b/keystore/binder/android/security/IKeystoreService.aidl
deleted file mode 100644
index db55062..0000000
--- a/keystore/binder/android/security/IKeystoreService.aidl
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Copyright (c) 2015, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security;
-
-import android.security.keymaster.ExportResult;
-import android.security.keymaster.KeyCharacteristics;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterCertificateChain;
-import android.security.keymaster.KeymasterBlob;
-import android.security.keymaster.OperationResult;
-import android.security.KeystoreArguments;
-
-/**
- * This must be kept manually in sync with system/security/keystore until AIDL
- * can generate both Java and C++ bindings.
- *
- * @hide
- */
-interface IKeystoreService {
-    int getState(int userId);
-    byte[] get(String name, int uid);
-    int insert(String name, in byte[] item, int uid, int flags);
-    int del(String name, int uid);
-    int exist(String name, int uid);
-    String[] list(String namePrefix, int uid);
-    int reset();
-    int onUserPasswordChanged(int userId, String newPassword);
-    int lock(int userId);
-    int unlock(int userId, String userPassword);
-    int isEmpty(int userId);
-    int generate(String name, int uid, int keyType, int keySize, int flags,
-        in KeystoreArguments args);
-    int import_key(String name, in byte[] data, int uid, int flags);
-    byte[] sign(String name, in byte[] data);
-    int verify(String name, in byte[] data, in byte[] signature);
-    byte[] get_pubkey(String name);
-    String grant(String name, int granteeUid);
-    int ungrant(String name, int granteeUid);
-    long getmtime(String name, int uid);
-    int is_hardware_backed(String string);
-    int clear_uid(long uid);
-
-    // Keymaster 0.4 methods
-    int addRngEntropy(in byte[] data, int flags);
-    int generateKey(String alias, in KeymasterArguments arguments, in byte[] entropy, int uid,
-        int flags, out KeyCharacteristics characteristics);
-    int getKeyCharacteristics(String alias, in KeymasterBlob clientId, in KeymasterBlob appData,
-        int uid, out KeyCharacteristics characteristics);
-    int importKey(String alias, in KeymasterArguments arguments, int format,
-        in byte[] keyData, int uid, int flags, out KeyCharacteristics characteristics);
-    ExportResult exportKey(String alias, int format, in KeymasterBlob clientId,
-        in KeymasterBlob appData, int uid);
-    OperationResult begin(IBinder appToken, String alias, int purpose, boolean pruneable,
-        in KeymasterArguments params, in byte[] entropy, int uid);
-    OperationResult update(IBinder token, in KeymasterArguments params, in byte[] input);
-    OperationResult finish(IBinder token, in KeymasterArguments params, in byte[] signature,
-        in byte[] entropy);
-    int abort(IBinder handle);
-    boolean isOperationAuthorized(IBinder token);
-    int addAuthToken(in byte[] authToken);
-    int onUserAdded(int userId, int parentId);
-    int onUserRemoved(int userId);
-    int attestKey(String alias, in KeymasterArguments params, out KeymasterCertificateChain chain);
-    int attestDeviceIds(in KeymasterArguments params, out KeymasterCertificateChain chain);
-    int onDeviceOffBody();
-    int importWrappedKey(in String wrappedKeyAlias, in byte[] wrappedKey,
-        in String wrappingKeyAlias, in byte[] maskingKey, in KeymasterArguments arguments,
-        in long rootSid, in long fingerprintSid,
-        out KeyCharacteristics characteristics);
-    int presentConfirmationPrompt(IBinder listener, String promptText, in byte[] extraData,
-        in String locale, in int uiOptionsAsFlags);
-    int cancelConfirmationPrompt(IBinder listener);
-    boolean isConfirmationPromptSupported();
-    int onKeyguardVisibilityChanged(in boolean isShowing, in int userId);
-}
diff --git a/keystore/binder/android/security/KeystoreArguments.aidl b/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl
similarity index 60%
copy from keystore/binder/android/security/KeystoreArguments.aidl
copy to keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl
index dc8ed50..dca928d 100644
--- a/keystore/binder/android/security/KeystoreArguments.aidl
+++ b/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015, The Android Open Source Project
+ * Copyright (c) 2018, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,14 @@
  * limitations under the License.
  */
 
-package android.security;
+package android.security.keystore;
 
-/* @hide */
-parcelable KeystoreArguments cpp_header "keystore/KeystoreArguments.h";
+import android.security.keystore.KeystoreResponse;
+import android.security.keymaster.KeymasterCertificateChain;
+
+/**
+ * @hide
+ */
+oneway interface IKeystoreCertificateChainCallback {
+    void onFinished(in KeystoreResponse response, in KeymasterCertificateChain chain);
+}
\ No newline at end of file
diff --git a/keystore/binder/android/security/KeystoreArguments.aidl b/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
similarity index 65%
copy from keystore/binder/android/security/KeystoreArguments.aidl
copy to keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
index dc8ed50..e42e927 100644
--- a/keystore/binder/android/security/KeystoreArguments.aidl
+++ b/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015, The Android Open Source Project
+ * Copyright (c) 2018, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,14 @@
  * limitations under the License.
  */
 
-package android.security;
+package android.security.keystore;
 
-/* @hide */
-parcelable KeystoreArguments cpp_header "keystore/KeystoreArguments.h";
+import android.security.keystore.KeystoreResponse;
+import android.security.keymaster.ExportResult;
+
+/**
+ * @hide
+ */
+oneway interface IKeystoreExportKeyCallback {
+	void onFinished(in ExportResult result);
+}
\ No newline at end of file
diff --git a/keystore/binder/android/security/KeystoreArguments.aidl b/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
similarity index 61%
copy from keystore/binder/android/security/KeystoreArguments.aidl
copy to keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
index dc8ed50..e1f0ffe 100644
--- a/keystore/binder/android/security/KeystoreArguments.aidl
+++ b/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015, The Android Open Source Project
+ * Copyright (c) 2018, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,14 @@
  * limitations under the License.
  */
 
-package android.security;
+package android.security.keystore;
 
-/* @hide */
-parcelable KeystoreArguments cpp_header "keystore/KeystoreArguments.h";
+import android.security.keystore.KeystoreResponse;
+import android.security.keymaster.KeyCharacteristics;
+
+/**
+ * @hide
+ */
+oneway interface IKeystoreKeyCharacteristicsCallback {
+	void onFinished(in KeystoreResponse response, in KeyCharacteristics charactersistics);
+}
\ No newline at end of file
diff --git a/keystore/binder/android/security/KeystoreArguments.aidl b/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
similarity index 64%
copy from keystore/binder/android/security/KeystoreArguments.aidl
copy to keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
index dc8ed50..0a51511 100644
--- a/keystore/binder/android/security/KeystoreArguments.aidl
+++ b/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015, The Android Open Source Project
+ * Copyright (c) 2018, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,14 @@
  * limitations under the License.
  */
 
-package android.security;
+package android.security.keystore;
 
-/* @hide */
-parcelable KeystoreArguments cpp_header "keystore/KeystoreArguments.h";
+import android.security.keystore.KeystoreResponse;
+import android.security.keymaster.OperationResult;
+
+/**
+ * @hide
+ */
+oneway interface IKeystoreOperationResultCallback {
+    void onFinished(in OperationResult result);
+}
\ No newline at end of file
diff --git a/keystore/binder/android/security/KeystoreArguments.aidl b/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl
similarity index 68%
copy from keystore/binder/android/security/KeystoreArguments.aidl
copy to keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl
index dc8ed50..912e605 100644
--- a/keystore/binder/android/security/KeystoreArguments.aidl
+++ b/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015, The Android Open Source Project
+ * Copyright (c) 2018, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,13 @@
  * limitations under the License.
  */
 
-package android.security;
+package android.security.keystore;
 
-/* @hide */
-parcelable KeystoreArguments cpp_header "keystore/KeystoreArguments.h";
+import android.security.keystore.KeystoreResponse;
+
+/**
+ * @hide
+ */
+oneway interface IKeystoreResponseCallback {
+    void onFinished(in KeystoreResponse response);
+}
\ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreService.aidl b/keystore/binder/android/security/keystore/IKeystoreService.aidl
new file mode 100644
index 0000000..348964f
--- /dev/null
+++ b/keystore/binder/android/security/keystore/IKeystoreService.aidl
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.security.keymaster.KeymasterArguments;
+import android.security.keymaster.KeymasterBlob;
+import android.security.keymaster.OperationResult;
+import android.security.keystore.IKeystoreResponseCallback;
+import android.security.keystore.IKeystoreKeyCharacteristicsCallback;
+import android.security.keystore.IKeystoreExportKeyCallback;
+import android.security.keystore.IKeystoreOperationResultCallback;
+import android.security.keystore.IKeystoreCertificateChainCallback;
+
+/**
+ * @hide
+ */
+interface IKeystoreService {
+    int getState(int userId);
+    byte[] get(String name, int uid);
+    int insert(String name, in byte[] item, int uid, int flags);
+    int del(String name, int uid);
+    int exist(String name, int uid);
+    String[] list(String namePrefix, int uid);
+    int reset();
+    int onUserPasswordChanged(int userId, String newPassword);
+    int lock(int userId);
+    int unlock(int userId, String userPassword);
+    int isEmpty(int userId);
+    String grant(String name, int granteeUid);
+    int ungrant(String name, int granteeUid);
+    long getmtime(String name, int uid);
+    int is_hardware_backed(String string);
+    int clear_uid(long uid);
+
+    int addRngEntropy(IKeystoreResponseCallback cb, in byte[] data, int flags);
+    int generateKey(IKeystoreKeyCharacteristicsCallback cb, String alias, in KeymasterArguments arguments, in byte[] entropy, int uid,
+        int flags);
+    int getKeyCharacteristics (IKeystoreKeyCharacteristicsCallback cb, String alias, in KeymasterBlob clientId, in KeymasterBlob appData,
+        int uid);
+    int importKey(IKeystoreKeyCharacteristicsCallback cb, String alias, in KeymasterArguments arguments, int format,
+        in byte[] keyData, int uid, int flags);
+    int exportKey(IKeystoreExportKeyCallback cb, String alias, int format, in KeymasterBlob clientId,
+        in KeymasterBlob appData, int uid);
+    int begin(in IKeystoreOperationResultCallback cb, IBinder appToken, String alias, int purpose, boolean pruneable,
+        in KeymasterArguments params, in byte[] entropy, int uid);
+    int update(in IKeystoreOperationResultCallback cb, IBinder token, in KeymasterArguments params, in byte[] input);
+    int finish(in IKeystoreOperationResultCallback cb, IBinder token, in KeymasterArguments params, in byte[] signature,
+        in byte[] entropy);
+    int abort(in IKeystoreResponseCallback cb, IBinder token);
+    int addAuthToken(in byte[] authToken);
+    int onUserAdded(int userId, int parentId);
+    int onUserRemoved(int userId);
+    int attestKey(in IKeystoreCertificateChainCallback cb, String alias, in KeymasterArguments params);
+    int attestDeviceIds(in IKeystoreCertificateChainCallback cb, in KeymasterArguments params);
+    int onDeviceOffBody();
+    int importWrappedKey(in IKeystoreKeyCharacteristicsCallback cb, String wrappedKeyAlias, in byte[] wrappedKey,
+        in String wrappingKeyAlias, in byte[] maskingKey, in KeymasterArguments arguments,
+        in long rootSid, in long fingerprintSid);
+    int presentConfirmationPrompt(IBinder listener, String promptText, in byte[] extraData,
+        in String locale, in int uiOptionsAsFlags);
+    int cancelConfirmationPrompt(IBinder listener);
+    boolean isConfirmationPromptSupported();
+    int onKeyguardVisibilityChanged(in boolean isShowing, in int userId);
+    int listUidsOfAuthBoundKeys(out @utf8InCpp List<String> uids);
+}
diff --git a/keystore/binder/android/security/KeystoreArguments.aidl b/keystore/binder/android/security/keystore/KeystoreResponse.aidl
similarity index 70%
rename from keystore/binder/android/security/KeystoreArguments.aidl
rename to keystore/binder/android/security/keystore/KeystoreResponse.aidl
index dc8ed50..128b456 100644
--- a/keystore/binder/android/security/KeystoreArguments.aidl
+++ b/keystore/binder/android/security/keystore/KeystoreResponse.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2015, The Android Open Source Project
+/*
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security;
+package android.security.keystore;
 
 /* @hide */
-parcelable KeystoreArguments cpp_header "keystore/KeystoreArguments.h";
+parcelable KeystoreResponse cpp_header "keystore/KeystoreResponse.h";
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index c3956f0..f9485a4 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -19,15 +19,24 @@
 #include <arpa/inet.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <openssl/rand.h>
 #include <string.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 
 #include "blob.h"
 
 #include "keystore_utils.h"
 
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+
+#include <istream>
+#include <ostream>
+#include <streambuf>
+#include <string>
+
+#include <android-base/logging.h>
+
 namespace {
 
 constexpr size_t kGcmIvSizeBytes = 96 / 8;
@@ -148,11 +157,60 @@
     return ResponseCode::NO_ERROR;
 }
 
+class ArrayStreamBuffer : public std::streambuf {
+  public:
+    template <typename T, size_t size> explicit ArrayStreamBuffer(const T (&data)[size]) {
+        static_assert(sizeof(T) == 1, "Array element size too large");
+        std::streambuf::char_type* d = const_cast<std::streambuf::char_type*>(
+            reinterpret_cast<const std::streambuf::char_type*>(&data[0]));
+        setg(d, d, d + size);
+        setp(d, d + size);
+    }
+
+  protected:
+    pos_type seekoff(off_type off, std::ios_base::seekdir dir,
+                     std::ios_base::openmode which = std::ios_base::in |
+                                                     std::ios_base::out) override {
+        bool in = which & std::ios_base::in;
+        bool out = which & std::ios_base::out;
+        if ((!in && !out) || (in && out && dir == std::ios_base::cur)) return -1;
+        std::streambuf::char_type* newPosPtr;
+        switch (dir) {
+        case std::ios_base::beg:
+            newPosPtr = pbase();
+            break;
+        case std::ios_base::cur:
+            // if dir == cur then in xor out due to
+            // if ((!in && !out) || (in && out && dir == std::ios_base::cur)) return -1; above
+            if (in)
+                newPosPtr = gptr();
+            else
+                newPosPtr = pptr();
+            break;
+        case std::ios_base::end:
+            // in and out bounds are the same and cannot change, so we can take either range
+            // regardless of the value of "which"
+            newPosPtr = epptr();
+            break;
+        }
+        newPosPtr += off;
+        if (newPosPtr < pbase() || newPosPtr > epptr()) return -1;
+        if (in) {
+            gbump(newPosPtr - gptr());
+        }
+        if (out) {
+            pbump(newPosPtr - pptr());
+        }
+        return newPosPtr - pbase();
+    }
+};
+
 }  // namespace
 
 Blob::Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength,
            BlobType type) {
-    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");
@@ -161,44 +219,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) {
@@ -206,85 +296,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 std::vector<uint8_t>& aes_key,
-                             State state) {
+static ResponseCode writeBlob(const std::string& filename, Blob blob, blobv3* rawBlob,
+                              const std::vector<uint8_t>& aes_key, State state) {
     ALOGV("writing blob %s", filename.c_str());
 
-    const size_t dataLength = 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 (!RAND_bytes(mBlob.initialization_vector, kGcmIvSizeBytes)) {
+        memset(rawBlob->initialization_vector, 0, AES_BLOCK_SIZE);
+        if (!RAND_bytes(rawBlob->initialization_vector, kGcmIvSizeBytes)) {
             ALOGW("Could not read random data for: %s", filename.c_str());
             return ResponseCode::SYSTEM_ERROR;
         }
 
-        auto rc = AES_gcm_encrypt(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;
 
-    const char* tmpFileName = ".tmp";
     int out =
-        TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
+        TEMP_FAILURE_RETRY(open(filename.c_str(), O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
     if (out < 0) {
-        ALOGW("could not open 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 std::vector<uint8_t>& aes_key,
+                                            State state) const {
+    if (entry_ == nullptr) {
+        return ResponseCode::SYSTEM_ERROR;
+    }
+    ResponseCode rc;
+    if (keyBlob) {
+        blobv3* rawBlob = keyBlob.mBlob.get();
+        rc = writeBlob(entry_->getKeyBlobPath(), std::move(keyBlob), rawBlob, aes_key, state);
+        if (rc != ResponseCode::NO_ERROR) {
+            return rc;
+        }
+    }
+
+    if (characteristicsBlob) {
+        blobv3* rawBlob = characteristicsBlob.mBlob.get();
+        rc = writeBlob(entry_->getCharacteristicsBlobPath(), std::move(characteristicsBlob),
+                       rawBlob, aes_key, state);
+    }
+    return rc;
+}
+
 ResponseCode Blob::readBlob(const std::string& filename, const std::vector<uint8_t>& aes_key,
                             State state) {
+    ResponseCode rc;
     ALOGV("reading blob %s", filename.c_str());
+    std::unique_ptr<blobv3> rawBlob = std::make_unique<blobv3>();
+
     const int in = TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY));
     if (in < 0) {
         return (errno == ENOENT) ? ResponseCode::KEY_NOT_FOUND : ResponseCode::SYSTEM_ERROR;
     }
 
     // fileLength may be less than sizeof(mBlob)
-    const size_t fileLength = readFully(in, (uint8_t*)&mBlob, sizeof(mBlob));
+    const size_t fileLength = readFully(in, (uint8_t*)rawBlob.get(), sizeof(blobv3));
     if (close(in) != 0) {
         return ResponseCode::SYSTEM_ERROR;
     }
@@ -293,67 +404,344 @@
         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.data(), 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 std::vector<uint8_t>& aes_key, State state) const {
+    std::tuple<ResponseCode, Blob, Blob> result;
+    auto& [rc, keyBlob, characteristicsBlob] = result;
+    if (entry_ == nullptr) return rc = ResponseCode::SYSTEM_ERROR, result;
+
+    rc = keyBlob.readBlob(entry_->getKeyBlobPath(), aes_key, state);
+    if (rc != ResponseCode::NO_ERROR && rc != ResponseCode::UNINITIALIZED) {
+        return result;
+    }
+
+    if (entry_->hasCharacteristicsBlob()) {
+        characteristicsBlob.readBlob(entry_->getCharacteristicsBlobPath(), aes_key, state);
+    }
+    return result;
+}
+
+ResponseCode LockedKeyBlobEntry::deleteBlobs() const {
+    if (entry_ == nullptr) return ResponseCode::NO_ERROR;
+
+    // always try to delete both
+    ResponseCode rc1 = (unlink(entry_->getKeyBlobPath().c_str()) && errno != ENOENT)
+                           ? ResponseCode::SYSTEM_ERROR
+                           : ResponseCode::NO_ERROR;
+    if (rc1 != ResponseCode::NO_ERROR) {
+        ALOGW("Failed to delete key blob file \"%s\"", entry_->getKeyBlobPath().c_str());
+    }
+    ResponseCode rc2 = (unlink(entry_->getCharacteristicsBlobPath().c_str()) && errno != ENOENT)
+                           ? ResponseCode::SYSTEM_ERROR
+                           : ResponseCode::NO_ERROR;
+    if (rc2 != ResponseCode::NO_ERROR) {
+        ALOGW("Failed to delete key characteristics file \"%s\"",
+              entry_->getCharacteristicsBlobPath().c_str());
+    }
+    // then report the first error that occured
+    if (rc1 != ResponseCode::NO_ERROR) return rc1;
+    return rc2;
+}
+
 keystore::SecurityLevel Blob::getSecurityLevel() const {
-    return keystore::flagsToSecurityLevel(mBlob.flags);
+    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. */
+
+std::string encodeKeyName(const std::string& keyName) {
+    std::string encodedName;
+    encodedName.reserve(keyName.size() * 2);
+    auto in = keyName.begin();
+    while (in != keyName.end()) {
+        // Input character needs to be encoded.
+        if (*in < '0' || *in > '~') {
+            // Encode the two most-significant bits of the input char in the first
+            // output character, by counting up from 43 ('+').
+            encodedName.append(1, '+' + (uint8_t(*in) >> 6));
+            // Encode the six least-significant bits of the input char in the second
+            // output character, by counting up from 48 ('0').
+            // This is safe because the maximum value is 112, which is the
+            // character 'p'.
+            encodedName.append(1, '0' + (*in & 0x3F));
+        } else {
+            // No need to encode input char - append as-is.
+            encodedName.append(1, *in);
+        }
+        ++in;
+    }
+    return encodedName;
+}
+
+std::string decodeKeyName(const std::string& encodedName) {
+    std::string decodedName;
+    decodedName.reserve(encodedName.size());
+    auto in = encodedName.begin();
+    bool multichar = false;
+    char c;
+    while (in != encodedName.end()) {
+        if (multichar) {
+            // Second part of a multi-character encoding. Turn off the multichar
+            // flag and set the six least-significant bits of c to the value originally
+            // encoded by counting up from '0'.
+            multichar = false;
+            decodedName.append(1, c | (uint8_t(*in) - '0'));
+        } else if (*in >= '+' && *in <= '.') {
+            // First part of a multi-character encoding. Set the multichar flag
+            // and set the two most-significant bits of c to be the two bits originally
+            // encoded by counting up from '+'.
+            multichar = true;
+            c = (*in - '+') << 6;
+        } else {
+            // Regular character, append as-is.
+            decodedName.append(1, *in);
+        }
+        ++in;
+    }
+    // mulitchars at the end get truncated
+    return decodedName;
+}
+
+std::string KeyBlobEntry::getKeyBlobBaseName() const {
+    std::stringstream s;
+    if (masterkey_) {
+        s << alias_;
+    } else {
+        s << uid_ << "_" << encodeKeyName(alias_);
+    }
+    return s.str();
+}
+
+std::string KeyBlobEntry::getKeyBlobPath() const {
+    std::stringstream s;
+    if (masterkey_) {
+        s << user_dir_ << "/" << alias_;
+    } else {
+        s << user_dir_ << "/" << uid_ << "_" << encodeKeyName(alias_);
+    }
+    return s.str();
+}
+
+std::string KeyBlobEntry::getCharacteristicsBlobBaseName() const {
+    std::stringstream s;
+    if (!masterkey_) s << "." << uid_ << "_chr_" << encodeKeyName(alias_);
+    return s.str();
+}
+
+std::string KeyBlobEntry::getCharacteristicsBlobPath() const {
+    std::stringstream s;
+    if (!masterkey_)
+        s << user_dir_ << "/"
+          << "." << uid_ << "_chr_" << encodeKeyName(alias_);
+    return s.str();
+}
+
+bool KeyBlobEntry::hasKeyBlob() const {
+    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 dc70709..ce488ec 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>
 #include <vector>
 
 constexpr size_t kValueSize = 32768;
@@ -82,26 +88,45 @@
     TYPE_KEY_PAIR = 3,
     TYPE_KEYMASTER_10 = 4,
     TYPE_KEY_CHARACTERISTICS = 5,
+    TYPE_KEY_CHARACTERISTICS_CACHE = 6,
     TYPE_MASTER_KEY_AES256 = 7,
 } BlobType;
 
+class LockedKeyBlobEntry;
+
+/**
+ * The Blob represents the content of a KeyBlobEntry.
+ *
+ * BEWARE: It is only save to call any member function of a Blob b if bool(b) yields true.
+ *         Exceptions are putKeyCharacteristics(), the assignment operators and operator bool.
+ */
 class Blob {
+    friend LockedKeyBlobEntry;
+
   public:
     Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength,
          BlobType type);
     explicit Blob(blobv3 b);
     Blob();
+    Blob(const Blob& rhs);
+    Blob(Blob&& rhs);
 
-    ~Blob() { mBlob = {}; }
+    ~Blob() {
+        if (mBlob) *mBlob = {};
+    }
 
-    const uint8_t* getValue() const { return mBlob.value; }
+    Blob& operator=(const Blob& rhs);
+    Blob& operator=(Blob&& rhs);
+    explicit 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);
@@ -112,23 +137,148 @@
     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 std::vector<uint8_t>& aes_key,
-                           State state);
-    ResponseCode readBlob(const std::string& filename, const std::vector<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 std::vector<uint8_t>& aes_key,
+                          State state);
 };
 
+/**
+ * A KeyBlobEntry represents a full qualified key blob as known by Keystore. The key blob
+ * is given by the uid of the owning app and the alias used by the app to refer to this key.
+ * The user_dir_ is technically implied by the uid, but computation of the user directory is
+ * done in the user state database. Which is why we also cache it here.
+ *
+ * The KeyBlobEntry knows the location of the key blob files (which may include a characteristics
+ * cache file) but does not allow read or write access to the content. It also does not imply
+ * the existence of the files.
+ *
+ * KeyBlobEntry abstracts, to some extent, from the the file system based storage of key blobs.
+ * An evolution of KeyBlobEntry may be used for key blob storage based on a back end other than
+ * file system, e.g., SQL database or other.
+ *
+ * For access to the key blob content the programmer has to acquire a LockedKeyBlobEntry (see
+ * below).
+ */
+class KeyBlobEntry {
+  private:
+    std::string alias_;
+    std::string user_dir_;
+    uid_t uid_;
+    bool masterkey_;
+
+  public:
+    KeyBlobEntry(std::string alias, std::string user_dir, uid_t uid, bool masterkey = false)
+        : alias_(std::move(alias)), user_dir_(std::move(user_dir)), uid_(uid),
+          masterkey_(masterkey) {}
+
+    std::string getKeyBlobBaseName() const;
+    std::string getKeyBlobPath() const;
+
+    std::string getCharacteristicsBlobBaseName() const;
+    std::string getCharacteristicsBlobPath() const;
+
+    bool hasKeyBlob() const;
+    bool hasCharacteristicsBlob() const;
+
+    bool operator<(const KeyBlobEntry& rhs) const {
+        return std::tie(uid_, alias_, user_dir_) < std::tie(rhs.uid_, rhs.alias_, rhs.user_dir_);
+    }
+    bool operator==(const KeyBlobEntry& rhs) const {
+        return std::tie(uid_, alias_, user_dir_) == std::tie(rhs.uid_, rhs.alias_, rhs.user_dir_);
+    }
+    bool operator!=(const KeyBlobEntry& rhs) const { return !(*this == rhs); }
+
+    inline const std::string& alias() const { return alias_; }
+    inline const std::string& user_dir() const { return user_dir_; }
+    inline uid_t uid() const { return uid_; }
+};
+
+/**
+ * The LockedKeyBlobEntry is a proxy object to KeyBlobEntry that expresses exclusive ownership
+ * of a KeyBlobEntry. LockedKeyBlobEntries can be acquired by calling
+ * LockedKeyBlobEntry::get() or LockedKeyBlobEntry::list().
+ *
+ * LockedKeyBlobEntries are movable but not copyable. By convention they can only
+ * be taken by the dispatcher thread of keystore, but not by any keymaster worker thread.
+ * The dispatcher thread may transfer ownership of a locked entry to a keymaster worker thread.
+ *
+ * Locked entries are tracked on the stack or as members of movable functor objects passed to the
+ * keymaster worker request queues. Locks are relinquished as the locked entry gets destroyed, e.g.,
+ * when it goes out of scope or when the owning request functor gets destroyed.
+ *
+ * LockedKeyBlobEntry::list(), which must only be called by the dispatcher, blocks until all
+ * LockedKeyBlobEntries have been destroyed. Thereby list acts as a fence to make sure it gets a
+ * consistent view of the key blob database. Under the assumption that keymaster worker requests
+ * cannot run or block indefinitely and cannot grab new locked entries, progress is guaranteed.
+ * It then grabs locked entries in accordance with the given filter rule.
+ *
+ * LockedKeyBlobEntry allow access to the proxied KeyBlobEntry interface through the operator->.
+ * They add additional functionality to access and modify the key blob's content on disk.
+ * LockedKeyBlobEntry ensures atomic operations on the persistently stored key blobs on a per
+ * entry granularity.
+ */
+class LockedKeyBlobEntry {
+  private:
+    static std::set<KeyBlobEntry> locked_blobs_;
+    static std::mutex locked_blobs_mutex_;
+    static std::condition_variable locked_blobs_mutex_cond_var_;
+
+    const KeyBlobEntry* entry_;
+    // NOLINTNEXTLINE(google-explicit-constructor)
+    LockedKeyBlobEntry(const KeyBlobEntry& entry) : entry_(&entry) {}
+
+    static void put(const KeyBlobEntry& entry);
+    LockedKeyBlobEntry(const LockedKeyBlobEntry&) = delete;
+    LockedKeyBlobEntry& operator=(const LockedKeyBlobEntry&) = delete;
+
+  public:
+    LockedKeyBlobEntry() : entry_(nullptr){};
+    ~LockedKeyBlobEntry();
+    LockedKeyBlobEntry(LockedKeyBlobEntry&& rhs) : entry_(rhs.entry_) { rhs.entry_ = nullptr; }
+    LockedKeyBlobEntry& operator=(LockedKeyBlobEntry&& rhs) {
+        // as dummy goes out of scope it relinquishes the lock on this
+        LockedKeyBlobEntry dummy(std::move(*this));
+        entry_ = rhs.entry_;
+        rhs.entry_ = nullptr;
+        return *this;
+    }
+    static LockedKeyBlobEntry get(KeyBlobEntry entry);
+    static std::tuple<ResponseCode, std::list<LockedKeyBlobEntry>>
+    list(const std::string& user_dir,
+         std::function<bool(uid_t, const std::string&)> filter =
+             [](uid_t, const std::string&) -> bool { return true; });
+
+    ResponseCode writeBlobs(Blob keyBlob, Blob characteristicsBlob,
+                            const std::vector<uint8_t>& aes_key, State state) const;
+    std::tuple<ResponseCode, Blob, Blob> readBlobs(const std::vector<uint8_t>& aes_key,
+                                                   State state) const;
+    ResponseCode deleteBlobs() const;
+
+    inline explicit operator bool() const { return entry_ != nullptr; }
+    inline const KeyBlobEntry& operator*() const { return *entry_; }
+    inline const KeyBlobEntry* operator->() const { return entry_; }
+};
+
+// Visible for testing
+std::string encodeKeyName(const std::string& keyName);
+std::string decodeKeyName(const std::string& encodedName);
+
 #endif  // KEYSTORE_BLOB_H_
diff --git a/keystore/confirmation_manager.cpp b/keystore/confirmation_manager.cpp
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..1baf32c 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,13 @@
  */
 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_; }
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  operator const uint64_t&() const { return grant_no_; }
 };
 
 /**
@@ -56,10 +64,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 +75,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/KeyAttestationApplicationId.h b/keystore/include/keystore/KeyAttestationApplicationId.h
index c612929..861c2e1 100644
--- a/keystore/include/keystore/KeyAttestationApplicationId.h
+++ b/keystore/include/keystore/KeyAttestationApplicationId.h
@@ -30,8 +30,11 @@
   public:
     typedef SharedNullableIterator<const KeyAttestationPackageInfo, std::vector>
         ConstKeyAttestationPackageInfoIterator;
+    typedef std::vector<std::unique_ptr<KeyAttestationPackageInfo>> PackageInfoVector;
     KeyAttestationApplicationId();
-    KeyAttestationApplicationId(std::unique_ptr<KeyAttestationPackageInfo> package);
+    // Following c'tors are for initializing instances containing test data.
+    explicit KeyAttestationApplicationId(std::unique_ptr<KeyAttestationPackageInfo> package);
+    explicit KeyAttestationApplicationId(PackageInfoVector packages);
 
     status_t writeToParcel(Parcel*) const override;
     status_t readFromParcel(const Parcel* parcel) override;
diff --git a/keystore/include/keystore/KeyCharacteristics.h b/keystore/include/keystore/KeyCharacteristics.h
index 7fc89c6..9c90b8a 100644
--- a/keystore/include/keystore/KeyCharacteristics.h
+++ b/keystore/include/keystore/KeyCharacteristics.h
@@ -27,7 +27,11 @@
 // Parcelable version of keystore::KeyCharacteristics
 struct KeyCharacteristics : public ::android::Parcelable {
     KeyCharacteristics(){};
-    explicit KeyCharacteristics(const keystore::KeyCharacteristics& other) {
+    explicit 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..3d22f5f 100644
--- a/keystore/include/keystore/KeymasterArguments.h
+++ b/keystore/include/keystore/KeymasterArguments.h
@@ -26,15 +26,19 @@
 // struct for serializing/deserializing a list of KeyParameters
 struct KeymasterArguments : public Parcelable {
     KeymasterArguments(){};
-    explicit KeymasterArguments(const hardware::hidl_vec<keystore::KeyParameter>& other);
+    // NOLINTNEXTLINE(google-explicit-constructor)
+    KeymasterArguments(hardware::hidl_vec<::keystore::KeyParameter>&& other);
+    explicit KeymasterArguments(const hardware::hidl_vec<::keystore::KeyParameter>& other);
 
     status_t readFromParcel(const Parcel* in) override;
     status_t writeToParcel(Parcel* out) const override;
 
-    const inline hardware::hidl_vec<keystore::KeyParameter>& getParameters() const { return data_; }
+    const inline hardware::hidl_vec<::keystore::KeyParameter>& getParameters() const {
+        return data_;
+    }
 
   private:
-    hardware::hidl_vec<keystore::KeyParameter> data_;
+    hardware::hidl_vec<::keystore::KeyParameter> data_;
 };
 
 }  // namespace keymaster
diff --git a/keystore/include/keystore/KeymasterCertificateChain.h b/keystore/include/keystore/KeymasterCertificateChain.h
index 132862c..f251d08 100644
--- a/keystore/include/keystore/KeymasterCertificateChain.h
+++ b/keystore/include/keystore/KeymasterCertificateChain.h
@@ -16,6 +16,7 @@
 #define KEYSTORE_INCLUDE_KEYSTORE_KEYMASTERCERTIFICATECHAIN_H_
 
 #include <binder/Parcelable.h>
+#include <keystore/keymaster_types.h>
 
 namespace android {
 namespace security {
diff --git a/keystore/include/keystore/KeystoreArg.h b/keystore/include/keystore/KeystoreArg.h
deleted file mode 100644
index a5e68f2..0000000
--- a/keystore/include/keystore/KeystoreArg.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARG_H
-#define KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARG_H
-
-#include <utils/RefBase.h>
-
-namespace android {
-namespace security {
-
-// Simple pair of generic pointer and length of corresponding data structure.
-class KeystoreArg : public RefBase {
-  public:
-    KeystoreArg(const void* data, size_t len) : mData(data), mSize(len) {}
-    ~KeystoreArg() {}
-
-    const void* data() const { return mData; }
-    size_t size() const { return mSize; }
-
-  private:
-    const void* mData;  // provider of the data must handle memory clean-up.
-    size_t mSize;
-};
-
-}  // namespace security
-}  // namespace android
-
-#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARG_H
diff --git a/keystore/include/keystore/KeystoreArguments.h b/keystore/include/keystore/KeystoreArguments.h
deleted file mode 100644
index c0a8b0a..0000000
--- a/keystore/include/keystore/KeystoreArguments.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARGUMENTS_H_
-#define KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARGUMENTS_H_
-
-#include <binder/Parcelable.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-
-#include "KeystoreArg.h"
-#include "keystore_return_types.h"
-
-namespace android {
-namespace security {
-
-// Parcelable KeystoreArguments.java which simply holds byte[][].
-struct KeystoreArguments : public ::android::Parcelable, public RefBase {
-    status_t readFromParcel(const Parcel* in) override;
-    status_t writeToParcel(Parcel* out) const override;
-
-    const Vector<sp<KeystoreArg>>& getArguments() const { return args; }
-
-  private:
-    Vector<sp<KeystoreArg>> args;
-};
-
-}  // namespace security
-}  // namespace android
-
-#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARGUMENTS_H_
diff --git a/keystore/include/keystore/KeystoreResponse.h b/keystore/include/keystore/KeystoreResponse.h
new file mode 100644
index 0000000..20f7274
--- /dev/null
+++ b/keystore/include/keystore/KeystoreResponse.h
@@ -0,0 +1,63 @@
+// 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_RESPONSE_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_RESPONSE_H_
+
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+#include <utils/String8.h>
+
+#include "keystore_return_types.h"
+
+namespace android {
+namespace security {
+namespace keystore {
+
+// struct for holding response code and optionally an error message for keystore
+// AIDL callbacks
+struct KeystoreResponse : public ::android::Parcelable {
+  public:
+    KeystoreResponse() = default;
+    explicit KeystoreResponse(const int response_code, const String16& error_msg)
+        : response_code_(response_code), error_msg_(std::make_unique<String16>(error_msg)) {}
+    explicit KeystoreResponse(const int response_code)
+        : response_code_(response_code), error_msg_() {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
+    KeystoreResponse(const ::keystore::KeyStoreServiceReturnCode& rc)
+        : response_code_(rc.getErrorCode()), error_msg_() {}
+    KeystoreResponse(const KeystoreResponse& other)
+        : response_code_(other.response_code_), error_msg_() {
+        if (other.error_msg_) {
+            error_msg_ = std::make_unique<String16>(*other.error_msg_);
+        }
+    }
+    KeystoreResponse(KeystoreResponse&& other) = default;
+
+    status_t readFromParcel(const Parcel* in) override;
+    status_t writeToParcel(Parcel* out) const override;
+
+    int response_code() const { return response_code_; }
+    const String16* error_msg() const { return error_msg_.get(); }
+
+  private:
+    int response_code_;
+    std::unique_ptr<String16> error_msg_;
+};
+
+}  // namespace keystore
+}  // namespace security
+}  // namespace android
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_RESPONSE_H_
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/Signature.h b/keystore/include/keystore/Signature.h
index 3c996bb..f39acec 100644
--- a/keystore/include/keystore/Signature.h
+++ b/keystore/include/keystore/Signature.h
@@ -25,6 +25,10 @@
 
 class Signature : public Parcelable {
   public:
+    Signature() = default;
+    // Intended for initializing instances containing test data.
+    explicit Signature(std::vector<uint8_t> signature_data);
+
     status_t writeToParcel(Parcel*) const override;
     status_t readFromParcel(const Parcel* parcel) override;
 
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_client_impl.h b/keystore/include/keystore/keystore_client_impl.h
index 9edd082..0bcef98 100644
--- a/keystore/include/keystore/keystore_client_impl.h
+++ b/keystore/include/keystore/keystore_client_impl.h
@@ -17,11 +17,12 @@
 
 #include "keystore_client.h"
 
+#include <future>
 #include <map>
 #include <string>
 #include <vector>
 
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
 #include <binder/IBinder.h>
 #include <binder/IServiceManager.h>
 #include <utils/StrongPointer.h>
@@ -109,7 +110,7 @@
 
     android::sp<android::IServiceManager> service_manager_;
     android::sp<android::IBinder> keystore_binder_;
-    android::sp<android::security::IKeystoreService> keystore_;
+    android::sp<android::security::keystore::IKeystoreService> keystore_;
     uint64_t next_virtual_handle_ = 1;
     std::map<uint64_t, android::sp<android::IBinder>> active_operations_;
 
diff --git a/keystore/include/keystore/keystore_concurrency.h b/keystore/include/keystore/keystore_concurrency.h
new file mode 100644
index 0000000..039ca31
--- /dev/null
+++ b/keystore/include/keystore/keystore_concurrency.h
@@ -0,0 +1,114 @@
+/*
+**
+** 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_() {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
+    template <typename... Args> ProxyLock(Args&&... args) : impl_{std::forward<Args>(args)...} {}
+    explicit ProxyLock(Implementation&& impl) : impl_(std::move(impl)) {}
+    explicit 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/include/keystore/keystore_promises.h b/keystore/include/keystore/keystore_promises.h
new file mode 100644
index 0000000..3d45016
--- /dev/null
+++ b/keystore/include/keystore/keystore_promises.h
@@ -0,0 +1,72 @@
+/*
+**
+** 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_PROMISES_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_PROMISES_H_
+
+#include <android/security/keystore/BnKeystoreCertificateChainCallback.h>
+#include <android/security/keystore/BnKeystoreExportKeyCallback.h>
+#include <android/security/keystore/BnKeystoreKeyCharacteristicsCallback.h>
+#include <android/security/keystore/BnKeystoreOperationResultCallback.h>
+#include <android/security/keystore/BnKeystoreResponseCallback.h>
+#include <future>
+
+namespace keystore {
+
+template <typename BnInterface, typename Result>
+class CallbackPromise : public BnInterface, public std::promise<Result> {
+  public:
+    ::android::binder::Status onFinished(const Result& result) override {
+        this->set_value(result);
+        return ::android::binder::Status::ok();
+    }
+};
+
+template <typename BnInterface, typename... Results>
+class CallbackPromise<BnInterface, std::tuple<Results...>>
+    : public BnInterface, public std::promise<std::tuple<Results...>> {
+  public:
+    ::android::binder::Status onFinished(const Results&... results) override {
+        this->set_value({results...});
+        return ::android::binder::Status::ok();
+    }
+};
+
+using OperationResultPromise =
+    CallbackPromise<::android::security::keystore::BnKeystoreOperationResultCallback,
+                    ::android::security::keymaster::OperationResult>;
+
+using KeystoreResponsePromise =
+    CallbackPromise<::android::security::keystore::BnKeystoreResponseCallback,
+                    ::android::security::keystore::KeystoreResponse>;
+
+using KeyCharacteristicsPromise =
+    CallbackPromise<::android::security::keystore::BnKeystoreKeyCharacteristicsCallback,
+                    std::tuple<::android::security::keystore::KeystoreResponse,
+                               ::android::security::keymaster::KeyCharacteristics>>;
+using KeystoreExportPromise =
+    CallbackPromise<::android::security::keystore::BnKeystoreExportKeyCallback,
+                    ::android::security::keymaster::ExportResult>;
+
+using KeyCertChainPromise =
+    CallbackPromise<::android::security::keystore::BnKeystoreCertificateChainCallback,
+                    std::tuple<::android::security::keystore::KeystoreResponse,
+                               ::android::security::keymaster::KeymasterCertificateChain>>;
+
+}  // namespace keystore
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_PROMISES_H_
diff --git a/keystore/include/keystore/keystore_return_types.h b/keystore/include/keystore/keystore_return_types.h
index fa4a224..f8cf1cc 100644
--- a/keystore/include/keystore/keystore_return_types.h
+++ b/keystore/include/keystore/keystore_return_types.h
@@ -41,10 +41,13 @@
 class KeyStoreServiceReturnCode {
   public:
     KeyStoreServiceReturnCode() : errorCode_(0) {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
     KeyStoreServiceReturnCode(const ErrorCode& errorCode) : errorCode_(int32_t(errorCode)) {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
     KeyStoreServiceReturnCode(const ResponseCode& errorCode) : errorCode_(int32_t(errorCode)) {}
     KeyStoreServiceReturnCode(const KeyStoreServiceReturnCode& errorCode)
         : errorCode_(errorCode.errorCode_) {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
     KeyStoreServiceReturnCode(const KeyStoreNativeReturnCode& errorCode);
     explicit inline KeyStoreServiceReturnCode(const int32_t& errorCode) : errorCode_(errorCode) {}
     inline KeyStoreServiceReturnCode& operator=(const ErrorCode& errorCode) {
@@ -64,7 +67,7 @@
                errorCode_ == static_cast<int32_t>(ErrorCode::OK);
     }
 
-    inline operator int32_t() const {
+    inline int32_t getErrorCode() const {
         if (!errorCode_) return static_cast<int32_t>(ResponseCode::NO_ERROR /* 1 */);
         return errorCode_;
     }
@@ -99,7 +102,7 @@
 }
 
 inline std::ostream& operator<<(std::ostream& out, const KeyStoreServiceReturnCode& error) {
-    return out << int32_t(error);
+    return out << error.getErrorCode();
 }
 
 /**
@@ -115,11 +118,14 @@
 class KeyStoreNativeReturnCode {
   public:
     KeyStoreNativeReturnCode() : errorCode_(0) {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
     KeyStoreNativeReturnCode(const ErrorCode& errorCode) : errorCode_(int32_t(errorCode)) {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
     KeyStoreNativeReturnCode(const ResponseCode& errorCode) : errorCode_(int32_t(errorCode)) {}
     KeyStoreNativeReturnCode(const KeyStoreNativeReturnCode& errorCode)
         : errorCode_(errorCode.errorCode_) {}
     explicit inline KeyStoreNativeReturnCode(const int32_t& errorCode) : errorCode_(errorCode) {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
     KeyStoreNativeReturnCode(const KeyStoreServiceReturnCode& errorcode);
     inline KeyStoreNativeReturnCode& operator=(const ErrorCode& errorCode) {
         errorCode_ = int32_t(errorCode);
@@ -137,7 +143,7 @@
         return errorCode_ == static_cast<int32_t>(ResponseCode::NO_ERROR) ||
                errorCode_ == static_cast<int32_t>(ErrorCode::OK);
     }
-    inline operator int32_t() const {
+    inline int32_t getErrorCode() const {
         if (errorCode_ == static_cast<int32_t>(ResponseCode::NO_ERROR) /* 1 */) {
             return static_cast<int32_t>(ErrorCode::OK) /* 0 */;
         }
@@ -175,13 +181,13 @@
 
 inline KeyStoreNativeReturnCode::KeyStoreNativeReturnCode(
     const KeyStoreServiceReturnCode& errorCode)
-    : errorCode_(int32_t(errorCode)) {}
+    : errorCode_(errorCode.getErrorCode()) {}
 inline KeyStoreServiceReturnCode::KeyStoreServiceReturnCode(
     const KeyStoreNativeReturnCode& errorCode)
-    : errorCode_(int32_t(errorCode)) {}
+    : errorCode_(errorCode.getErrorCode()) {}
 
 inline std::ostream& operator<<(std::ostream& out, const KeyStoreNativeReturnCode& error) {
-    return out << int32_t(error);
+    return out << error.getErrorCode();
 }
 
 }  // namespace keystore
diff --git a/keystore/include/keystore/utils.h b/keystore/include/keystore/utils.h
index f95ae71..544dd21 100644
--- a/keystore/include/keystore/utils.h
+++ b/keystore/include/keystore/utils.h
@@ -29,12 +29,16 @@
     typedef std::shared_ptr<CollectionType> CollectionPtr;
 
     SharedNullableIterator() {}
-    SharedNullableIterator(const std::shared_ptr<CollectionType>& coll) : coll_(coll) { init(); }
-    SharedNullableIterator(std::shared_ptr<CollectionType>&& coll) : coll_(coll) { init(); }
+    explicit SharedNullableIterator(const std::shared_ptr<CollectionType>& coll) : coll_(coll) {
+        init();
+    }
+    explicit SharedNullableIterator(std::shared_ptr<CollectionType>&& coll) : coll_(coll) {
+        init();
+    }
 
     SharedNullableIterator(const SharedNullableIterator& other)
         : coll_(other.coll_), cur_(other.cur_) {}
-    SharedNullableIterator(SharedNullableIterator&& other)
+    SharedNullableIterator(SharedNullableIterator&& other) noexcept
         : coll_(std::move(other.coll_)), cur_(std::move(other.cur_)) {}
 
     SharedNullableIterator& operator++() {
@@ -56,7 +60,7 @@
     bool operator!=(const SharedNullableIterator& other) const { return !(*this == other); }
 
     SharedNullableIterator& operator=(const SharedNullableIterator&) = default;
-    SharedNullableIterator& operator=(SharedNullableIterator&&) = default;
+    SharedNullableIterator& operator=(SharedNullableIterator&&) noexcept = default;
 
   private:
     inline bool is_end() const { return !coll_ || cur_ == coll_->end(); }
diff --git a/keystore/key_proto_handler.cpp b/keystore/key_proto_handler.cpp
index 3bf8c06..a106213 100644
--- a/keystore/key_proto_handler.cpp
+++ b/keystore/key_proto_handler.cpp
@@ -22,6 +22,7 @@
 #include <keymasterV4_0/Keymaster.h>
 #include <keystore/keymaster_types.h>
 #include <utils/String16.h>
+#include <utils/StrongPointer.h>
 
 #include "key_config.pb.h"
 
@@ -74,7 +75,7 @@
                                      bool wasCreationSuccessful) {
     KeyConfig keyConfig;
     checkEnforcedCharacteristics(keyParams, &keyConfig);
-    auto dropbox = std::make_unique<android::os::DropBoxManager>();
+    android::sp<android::os::DropBoxManager> dropbox(new android::os::DropBoxManager());
     keyConfig.set_was_creation_successful(wasCreationSuccessful);
 
     size_t size = keyConfig.ByteSize();
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 81189ae..a7fcd38 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -17,12 +17,12 @@
 #define LOG_TAG "keystore"
 
 #include "key_store_service.h"
-#include "include/keystore/KeystoreArg.h"
 
 #include <fcntl.h>
 #include <sys/stat.h>
 
 #include <algorithm>
+#include <atomic>
 #include <sstream>
 
 #include <android-base/scopeguard.h>
@@ -30,11 +30,13 @@
 #include <binder/IPCThreadState.h>
 #include <binder/IPermissionController.h>
 #include <binder/IServiceManager.h>
+#include <cutils/multiuser.h>
 #include <log/log_event_list.h>
 
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
+#include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
 #include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
 
 #include "defaults.h"
@@ -43,6 +45,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>
 
@@ -53,15 +56,17 @@
 namespace {
 
 using ::android::binder::Status;
-using android::security::KeystoreArg;
 using android::security::keymaster::ExportResult;
 using android::security::keymaster::KeymasterArguments;
 using android::security::keymaster::KeymasterBlob;
 using android::security::keymaster::KeymasterCertificateChain;
+using android::security::keymaster::operationFailed;
 using android::security::keymaster::OperationResult;
 using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
+using ::android::security::keystore::IKeystoreOperationResultCallback;
+using ::android::security::keystore::IKeystoreResponseCallback;
+using ::android::security::keystore::KeystoreResponse;
 
-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;
@@ -73,18 +78,17 @@
 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; });
+    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);
-}
+#define AIDL_RETURN(rc) (*_aidl_return = KeyStoreServiceReturnCode(rc).getErrorCode(), Status::ok())
 
 std::pair<KeyStoreServiceReturnCode, bool> hadFactoryResetSinceIdRotation() {
     struct stat sbuf;
     if (stat(kTimestampFilePath, &sbuf) == 0) {
-        double diff_secs = difftime(time(NULL), sbuf.st_ctime);
+        double diff_secs = difftime(time(nullptr), sbuf.st_ctime);
         return {ResponseCode::NO_ERROR, diff_secs < kIdRotationPeriod};
     }
 
@@ -107,7 +111,7 @@
     return {ResponseCode::NO_ERROR, true};
 }
 
-constexpr size_t KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE = 1024;
+using ::android::security::KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE;
 
 KeyStoreServiceReturnCode updateParamsForAttestation(uid_t callingUid, AuthorizationSet* params) {
     KeyStoreServiceReturnCode responseCode;
@@ -125,11 +129,14 @@
     std::vector<uint8_t>& asn1_attestation_id = asn1_attestation_id_result;
 
     /*
-     * The attestation application ID cannot be longer than
-     * KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE, so we truncate if too long.
+     * The attestation application ID must not be longer than
+     * KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE, error out if gather_attestation_application_id
+     * returned such an invalid vector.
      */
     if (asn1_attestation_id.size() > KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE) {
-        asn1_attestation_id.resize(KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE);
+        ALOGE("BUG: Gathered Attestation Application ID is too big (%d)",
+              static_cast<int32_t>(asn1_attestation_id.size()));
+        return ErrorCode::CANNOT_ATTEST_IDS;
     }
 
     params->push_back(TAG_ATTESTATION_APPLICATION_ID, asn1_attestation_id);
@@ -139,15 +146,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);
@@ -166,10 +164,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.
@@ -187,18 +189,23 @@
     KeyStoreServiceReturnCode result =
         checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
     if (!result.isOk()) {
-        *aidl_return = static_cast<int32_t>(result);
+        *aidl_return = result.getErrorCode();
         return Status::ok();
     }
 
     String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_GENERIC));
+    auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), targetUid);
 
-    Blob keyBlob(&item[0], item.size(), NULL, 0, ::TYPE_GENERIC);
+    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();
 }
 
@@ -210,26 +217,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();
 }
 
@@ -240,13 +236,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)) {
@@ -254,19 +251,100 @@
             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;
+    auto userDirName = mKeyStore->getUserStateDB().getUserStateByUid(targetUid)->getUserDirName();
+
+    std::tie(rc, internal_matches) =
+        LockedKeyBlobEntry::list(userDirName, [&](uid_t uid, const std::string& alias) {
+            std::mismatch(stdPrefix.begin(), stdPrefix.end(), alias.begin(), alias.end());
+            return uid == static_cast<uid_t>(targetUid) &&
+                   std::mismatch(stdPrefix.begin(), stdPrefix.end(), alias.begin(), alias.end())
+                           .first == stdPrefix.end();
+        });
+
+    if (rc != ResponseCode::NO_ERROR) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(rc));
     }
-    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();
 }
 
+/*
+ * This method will return the uids of all auth bound keys for the calling user.
+ * This is intended to be used for alerting the user about which apps will be affected
+ * if the password/pin is removed. Only allowed to be called by system.
+ * The output is bound by the initial size of uidsOut to be compatible with Java.
+ */
+Status KeyStoreService::listUidsOfAuthBoundKeys(std::vector<std::string>* uidsOut,
+                                                int32_t* aidl_return) {
+    const int32_t callingUid = IPCThreadState::self()->getCallingUid();
+    const int32_t userId = get_user_id(callingUid);
+    const int32_t appId = get_app_id(callingUid);
+    if (appId != AID_SYSTEM) {
+        ALOGE("Permission listUidsOfAuthBoundKeys denied for aid %d", appId);
+        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+        return Status::ok();
+    }
+
+    const String8 prefix8("");
+    auto userState = mKeyStore->getUserStateDB().getUserState(userId);
+    const std::string userDirName = userState->getUserDirName();
+    auto encryptionKey = userState->getEncryptionKey();
+    auto state = userState->getState();
+    // unlock the user state
+    userState = {};
+
+    ResponseCode rc;
+    std::list<LockedKeyBlobEntry> internal_matches;
+    std::tie(rc, internal_matches) =
+        LockedKeyBlobEntry::list(userDirName, [&](uid_t, const std::string&) {
+            // Need to filter on auth bound state, so just return true.
+            return true;
+        });
+    if (rc != ResponseCode::NO_ERROR) {
+        ALOGE("Error listing blob entries for user %d", userId);
+        return Status::fromServiceSpecificError(static_cast<int32_t>(rc));
+    }
+
+    for (LockedKeyBlobEntry& entry : internal_matches) {
+        // Need to store uids as a list of strings because integer list output
+        // parameters is not supported in aidl-cpp.
+        std::string entryUid = std::to_string(entry->uid());
+        if (std::find(uidsOut->begin(), uidsOut->end(), entryUid) != uidsOut->end()) {
+            // uid already in list, skip
+            continue;
+        }
+
+        auto [rc, blob, charBlob] = entry.readBlobs(encryptionKey, state);
+        if (rc != ResponseCode::NO_ERROR && rc != ResponseCode::LOCKED) {
+            ALOGE("Error reading blob for key %s", entry->alias().c_str());
+            continue;
+        }
+
+        if (blob && blob.isEncrypted()) {
+            uidsOut->push_back(entryUid);
+        } else if (charBlob) {
+            auto [success, hwEnforced, swEnforced] = charBlob.getKeyCharacteristics();
+            if (!success) {
+                ALOGE("Error reading blob characteristics for key %s", entry->alias().c_str());
+                continue;
+            }
+            if (hwEnforced.Contains(TAG_USER_SECURE_ID) ||
+                swEnforced.Contains(TAG_USER_SECURE_ID)) {
+                uidsOut->push_back(entryUid);
+            }
+        }
+    }
+    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+    return Status::ok();
+}
+
 Status KeyStoreService::reset(int32_t* aidl_return) {
     if (!checkBinderPermission(P_RESET)) {
         *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
@@ -289,7 +367,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);
@@ -370,7 +448,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();
@@ -399,7 +477,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));
@@ -416,188 +494,6 @@
     return Status::ok();
 }
 
-Status KeyStoreService::generate(const String16& name, int32_t targetUid, int32_t keyType,
-                                 int32_t keySize, int32_t flags,
-                                 const ::android::security::KeystoreArguments& keystoreArgs,
-                                 int32_t* aidl_return) {
-    const Vector<sp<KeystoreArg>>* args = &(keystoreArgs.getArguments());
-    targetUid = getEffectiveUid(targetUid);
-    KeyStoreServiceReturnCode result =
-        checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (!result.isOk()) {
-        *aidl_return = static_cast<int32_t>(result);
-        return Status::ok();
-    }
-
-    keystore::AuthorizationSet params;
-    add_legacy_key_authorizations(keyType, &params);
-
-    switch (keyType) {
-    case EVP_PKEY_EC: {
-        params.push_back(TAG_ALGORITHM, Algorithm::EC);
-        if (keySize == -1) {
-            keySize = EC_DEFAULT_KEY_SIZE;
-        } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
-            ALOGI("invalid key size %d", keySize);
-            *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-            return Status::ok();
-        }
-        params.push_back(TAG_KEY_SIZE, keySize);
-        break;
-    }
-    case EVP_PKEY_RSA: {
-        params.push_back(TAG_ALGORITHM, Algorithm::RSA);
-        if (keySize == -1) {
-            keySize = RSA_DEFAULT_KEY_SIZE;
-        } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
-            ALOGI("invalid key size %d", keySize);
-            *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-            return Status::ok();
-        }
-        params.push_back(TAG_KEY_SIZE, keySize);
-        unsigned long exponent = RSA_DEFAULT_EXPONENT;
-        if (args->size() > 1) {
-            ALOGI("invalid number of arguments: %zu", args->size());
-            *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-            return Status::ok();
-        } else if (args->size() == 1) {
-            const sp<KeystoreArg>& expArg = args->itemAt(0);
-            if (expArg != NULL) {
-                Unique_BIGNUM pubExpBn(BN_bin2bn(
-                    reinterpret_cast<const unsigned char*>(expArg->data()), expArg->size(), NULL));
-                if (pubExpBn.get() == NULL) {
-                    ALOGI("Could not convert public exponent to BN");
-                    *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-                    return Status::ok();
-                }
-                exponent = BN_get_word(pubExpBn.get());
-                if (exponent == 0xFFFFFFFFL) {
-                    ALOGW("cannot represent public exponent as a long value");
-                    *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-                    return Status::ok();
-                }
-            } else {
-                ALOGW("public exponent not read");
-                *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-                return Status::ok();
-            }
-        }
-        params.push_back(TAG_RSA_PUBLIC_EXPONENT, exponent);
-        break;
-    }
-    default: {
-        ALOGW("Unsupported key type %d", keyType);
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-    }
-
-    int32_t aidl_result;
-    android::security::keymaster::KeyCharacteristics unused_characteristics;
-    auto rc = generateKey(name, KeymasterArguments(params.hidl_data()), ::std::vector<uint8_t>(),
-                          targetUid, flags, &unused_characteristics, &aidl_result);
-    if (!KeyStoreServiceReturnCode(aidl_result).isOk()) {
-        ALOGW("generate failed: %d", int32_t(aidl_result));
-    }
-    *aidl_return = aidl_result;
-    return Status::ok();
-}
-
-Status KeyStoreService::import_key(const String16& name, const ::std::vector<uint8_t>& data,
-                                   int targetUid, int32_t flags, int32_t* aidl_return) {
-
-    const uint8_t* ptr = &data[0];
-
-    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, data.size()));
-    if (!pkcs8.get()) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-    Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
-    if (!pkey.get()) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-    int type = EVP_PKEY_type(pkey->type);
-    AuthorizationSet params;
-    add_legacy_key_authorizations(type, &params);
-    switch (type) {
-    case EVP_PKEY_RSA:
-        params.push_back(TAG_ALGORITHM, Algorithm::RSA);
-        break;
-    case EVP_PKEY_EC:
-        params.push_back(TAG_ALGORITHM, Algorithm::EC);
-        break;
-    default:
-        ALOGW("Unsupported key type %d", type);
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-
-    int import_result;
-    auto rc = importKey(name, KeymasterArguments(params.hidl_data()),
-                        static_cast<int32_t>(KeyFormat::PKCS8), data, targetUid, flags,
-                        /*outCharacteristics*/ NULL, &import_result);
-
-    if (!KeyStoreServiceReturnCode(import_result).isOk()) {
-        ALOGW("importKey failed: %d", int32_t(import_result));
-    }
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return Status::ok();
-}
-
-Status KeyStoreService::sign(const String16& name, const ::std::vector<uint8_t>& data,
-                             ::std::vector<uint8_t>* out) {
-    if (!checkBinderPermission(P_SIGN)) {
-        return Status::fromServiceSpecificError(
-            static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
-    }
-    hidl_vec<uint8_t> legacy_out;
-    KeyStoreServiceReturnCode res =
-        doLegacySignVerify(name, data, &legacy_out, hidl_vec<uint8_t>(), KeyPurpose::SIGN);
-    if (!res.isOk()) {
-        return Status::fromServiceSpecificError((res));
-    }
-    *out = legacy_out;
-    return Status::ok();
-}
-
-Status KeyStoreService::verify(const String16& name, const ::std::vector<uint8_t>& data,
-                               const ::std::vector<uint8_t>& signature, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_VERIFY)) {
-        return Status::fromServiceSpecificError(
-            static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
-    }
-    *aidl_return = static_cast<int32_t>(
-        doLegacySignVerify(name, data, nullptr, signature, KeyPurpose::VERIFY));
-    return Status::ok();
-}
-
-/*
- * TODO: The abstraction between things stored in hardware and regular blobs
- * of data stored on the filesystem should be moved down to keystore itself.
- * Unfortunately the Java code that calls this has naming conventions that it
- * knows about. Ideally keystore shouldn't be used to store random blobs of
- * data.
- *
- * Until that happens, it's necessary to have a separate "get_pubkey" and
- * "del_key" since the Java code doesn't really communicate what it's
- * intentions are.
- */
-Status KeyStoreService::get_pubkey(const String16& name, ::std::vector<uint8_t>* pubKey) {
-    android::security::keymaster::ExportResult result;
-    KeymasterBlob clientId;
-    KeymasterBlob appData;
-    exportKey(name, static_cast<int32_t>(KeyFormat::X509), clientId, appData, UID_SELF, &result);
-    if (!result.resultCode.isOk()) {
-        ALOGW("export failed: %d", int32_t(result.resultCode));
-        return Status::fromServiceSpecificError(static_cast<int32_t>(result.resultCode));
-    }
-
-    if (pubKey) *pubKey = std::move(result.exportData);
-    return Status::ok();
-}
-
 Status KeyStoreService::grant(const String16& name, int32_t granteeUid,
                               ::android::String16* aidl_return) {
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -609,15 +505,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();
 }
 
@@ -626,22 +520,18 @@
     KeyStoreServiceReturnCode result =
         checkBinderPermissionAndKeystoreState(P_GRANT, /*targetUid=*/-1, /*checkUnlocked=*/false);
     if (!result.isOk()) {
-        *aidl_return = static_cast<int32_t>(result);
+        *aidl_return = result.getErrorCode();
         return Status::ok();
     }
 
     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();
 }
 
@@ -652,18 +542,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();
     }
@@ -672,7 +564,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();
     }
@@ -686,885 +578,363 @@
     return Status::ok();
 }
 
-Status KeyStoreService::clear_uid(int64_t targetUid64, int32_t* aidl_return) {
+Status KeyStoreService::clear_uid(int64_t targetUid64, int32_t* _aidl_return) {
     uid_t targetUid = getEffectiveUid(targetUid64);
     if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
+        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
     }
     ALOGI("clear_uid %" PRId64, targetUid64);
 
     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);
-        return Status::ok();
+    ResponseCode rc;
+    std::list<LockedKeyBlobEntry> entries;
+    auto userDirName = mKeyStore->getUserStateDB().getUserStateByUid(targetUid)->getUserDirName();
+
+    // list has a fence making sure no workers are modifying blob files before iterating the
+    // data base. All returned entries are locked.
+    std::tie(rc, entries) = LockedKeyBlobEntry::list(
+        userDirName, [&](uid_t uid, const std::string&) -> bool { return uid == targetUid; });
+
+    if (rc != ResponseCode::NO_ERROR) {
+        return AIDL_RETURN(rc);
     }
 
-    for (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();
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
-Status KeyStoreService::addRngEntropy(const ::std::vector<uint8_t>& entropy, int32_t flags,
-                                      int32_t* aidl_return) {
+Status KeyStoreService::addRngEntropy(
+    const ::android::sp<::android::security::keystore::IKeystoreResponseCallback>& cb,
+    const ::std::vector<uint8_t>& entropy, int32_t flags, int32_t* _aidl_return) {
     auto device = mKeyStore->getDevice(flagsToSecurityLevel(flags));
     if (!device) {
-        *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 AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
     }
-    return Status::ok();
+
+    device->addRngEntropy(entropy, [cb](Return<ErrorCode> rc) {
+        cb->onFinished(KeyStoreServiceReturnCode(KS_HANDLE_HIDL_ERROR(rc)));
+    });
+
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
-Status
-KeyStoreService::generateKey(const String16& name, const KeymasterArguments& params,
-                             const ::std::vector<uint8_t>& entropy, int uid, int flags,
-                             android::security::keymaster::KeyCharacteristics* outCharacteristics,
-                             int32_t* aidl_return) {
+Status KeyStoreService::generateKey(
+    const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
+    const String16& name, const KeymasterArguments& params, const ::std::vector<uint8_t>& entropy,
+    int uid, int flags, int32_t* _aidl_return) {
     // TODO(jbires): remove this getCallingUid call upon implementation of b/25646100
     uid_t originalUid = IPCThreadState::self()->getCallingUid();
     uid = getEffectiveUid(uid);
     auto logOnScopeExit = android::base::make_scope_guard([&] {
         if (__android_log_security()) {
             android_log_event_list(SEC_TAG_AUTH_KEY_GENERATED)
-                << int32_t(*aidl_return == static_cast<int32_t>(ResponseCode::NO_ERROR))
+                << int32_t(*_aidl_return == static_cast<int32_t>(ResponseCode::NO_ERROR))
                 << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
         }
     });
     KeyStoreServiceReturnCode rc =
         checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
     if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
+        return AIDL_RETURN(rc);
     }
     if ((flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION) && get_app_id(uid) != AID_SYSTEM) {
         ALOGE("Non-system uid %d cannot set FLAG_CRITICAL_TO_DEVICE_ENCRYPTION", uid);
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
+        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
     }
 
     if (containsTag(params.getParameters(), Tag::INCLUDE_UNIQUE_ID)) {
         // TODO(jbires): remove uid checking upon implementation of b/25646100
         if (!checkBinderPermission(P_GEN_UNIQUE_ID) ||
             originalUid != IPCThreadState::self()->getCallingUid()) {
-            *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-            return Status::ok();
+            return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
         }
     }
 
     SecurityLevel securityLevel = flagsToSecurityLevel(flags);
     auto dev = mKeyStore->getDevice(securityLevel);
     if (!dev) {
-        *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();
+        return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
     }
 
-    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(), NULL, 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 = mActiveUserId;
-        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);
-        return Status::ok();
+    auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), uid);
+    if (!lockedEntry) {
+        return AIDL_RETURN(ResponseCode::KEY_ALREADY_EXISTS);
     }
-    auto kc_buf = kc_stream.str();
-    Blob charBlob(reinterpret_cast<const uint8_t*>(kc_buf.data()), kc_buf.size(), NULL, 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)));
-    return Status::ok();
+    logOnScopeExit.Disable();
+
+    dev->generateKey(
+        std::move(lockedEntry), params.getParameters(), entropy, flags,
+        [cb, uid, name](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+            if (__android_log_security()) {
+                android_log_event_list(SEC_TAG_AUTH_KEY_GENERATED)
+                    << rc.isOk() << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
+            }
+            cb->onFinished(rc,
+                           android::security::keymaster::KeyCharacteristics(keyCharacteristics));
+        });
+
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
 Status KeyStoreService::getKeyCharacteristics(
+    const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
     const String16& name, const ::android::security::keymaster::KeymasterBlob& clientId,
     const ::android::security::keymaster::KeymasterBlob& appData, int32_t uid,
-    ::android::security::keymaster::KeyCharacteristics* outCharacteristics, int32_t* aidl_return) {
-    if (!outCharacteristics) {
-        *aidl_return =
-            static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::UNEXPECTED_NULL_POINTER));
-        return Status::ok();
-    }
+    int32_t* _aidl_return) {
 
     uid_t targetUid = getEffectiveUid(uid);
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     if (!is_granted_to(callingUid, targetUid)) {
         ALOGW("uid %d not permitted to act for uid %d in getKeyCharacteristics", callingUid,
               targetUid);
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
+        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
     }
 
-    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()) {
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
+    std::tie(rc, keyBlob, charBlob, lockedEntry) =
+        mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
+
+    if (rc != ResponseCode::NO_ERROR) {
+        return AIDL_RETURN(rc);
     }
 
-    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);
-        return Status::ok();
+    if (!dev) {
+        return AIDL_RETURN(ResponseCode::SYSTEM_ERROR);
     }
 
-    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.
+    dev->getKeyCharacteristics(
+        std::move(lockedEntry), clientId.getData(), appData.getData(), std::move(keyBlob),
+        std::move(charBlob),
+        [cb](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+            cb->onFinished(rc,
+                           android::security::keymaster::KeyCharacteristics(keyCharacteristics));
+        });
 
-        auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
-
-        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));
-    return Status::ok();
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
-Status
-KeyStoreService::importKey(const String16& name, const KeymasterArguments& params, int32_t format,
-                           const ::std::vector<uint8_t>& keyData, int uid, int flags,
-                           ::android::security::keymaster::KeyCharacteristics* outCharacteristics,
-                           int32_t* aidl_return) {
-
+Status KeyStoreService::importKey(
+    const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
+    const String16& name, const KeymasterArguments& params, int32_t format,
+    const ::std::vector<uint8_t>& keyData, int uid, int flags, int32_t* _aidl_return) {
     uid = getEffectiveUid(uid);
     auto logOnScopeExit = android::base::make_scope_guard([&] {
         if (__android_log_security()) {
             android_log_event_list(SEC_TAG_KEY_IMPORTED)
-                << int32_t(*aidl_return == static_cast<int32_t>(ResponseCode::NO_ERROR))
+                << int32_t(*_aidl_return == static_cast<int32_t>(ResponseCode::NO_ERROR))
                 << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
         }
     });
     KeyStoreServiceReturnCode rc =
         checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
     if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
+        LOG(ERROR) << "permissission denied";
+        return AIDL_RETURN(rc);
     }
     if ((flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION) && get_app_id(uid) != AID_SYSTEM) {
         ALOGE("Non-system uid %d cannot set FLAG_CRITICAL_TO_DEVICE_ENCRYPTION", uid);
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
+        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
     }
 
     SecurityLevel securityLevel = flagsToSecurityLevel(flags);
     auto dev = mKeyStore->getDevice(securityLevel);
     if (!dev) {
-        *aidl_return = static_cast<int32_t>(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
-        return Status::ok();
+        LOG(ERROR) << "importKey - cound not get keymaster device";
+        return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
     }
 
     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(), NULL, 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);
-        return Status::ok();
+    auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), uid);
+    if (!lockedEntry) {
+        LOG(ERROR) << "importKey - key: " << name8.string() << " " << int(uid)
+                   << " already exists.";
+        return AIDL_RETURN(ResponseCode::KEY_ALREADY_EXISTS);
     }
-    // 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();
+
+    dev->importKey(
+        std::move(lockedEntry), params.getParameters(), KeyFormat(format), keyData, flags,
+        [cb, uid, name](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+            if (__android_log_security()) {
+                android_log_event_list(SEC_TAG_KEY_IMPORTED)
+                    << rc.isOk() << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
             }
-        }
+            cb->onFinished(rc,
+                           android::security::keymaster::KeyCharacteristics(keyCharacteristics));
+        });
 
-        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 */);
-    }
-
-    // Write the characteristics:
-    String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
-
-    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 = mActiveUserId;
-        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(), NULL, 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)));
-
-    return Status::ok();
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
-Status KeyStoreService::exportKey(const String16& name, int32_t format,
-                                  const ::android::security::keymaster::KeymasterBlob& clientId,
-                                  const ::android::security::keymaster::KeymasterBlob& appData,
-                                  int32_t uid, ExportResult* result) {
+Status KeyStoreService::exportKey(
+    const ::android::sp<::android::security::keystore::IKeystoreExportKeyCallback>& cb,
+    const String16& name, int32_t format,
+    const ::android::security::keymaster::KeymasterBlob& clientId,
+    const ::android::security::keymaster::KeymasterBlob& appData, int32_t uid,
+    int32_t* _aidl_return) {
 
     uid_t targetUid = getEffectiveUid(uid);
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     if (!is_granted_to(callingUid, targetUid)) {
         ALOGW("uid %d not permitted to act for uid %d in exportKey", callingUid, targetUid);
-        result->resultCode = ResponseCode::PERMISSION_DENIED;
-        return Status::ok();
+        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
     }
 
-    Blob keyBlob;
     String8 name8(name);
 
-    result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
-    if (!result->resultCode.isOk()) {
-        return Status::ok();
+    KeyStoreServiceReturnCode rc;
+    Blob keyBlob;
+    Blob charBlob;
+    LockedKeyBlobEntry lockedEntry;
+
+    std::tie(rc, keyBlob, charBlob, lockedEntry) =
+        mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
+    if (!rc.isOk()) {
+        return AIDL_RETURN(rc);
     }
 
-    auto key = blob2hidlVec(keyBlob);
     auto dev = mKeyStore->getDevice(keyBlob);
 
-    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),
+                   [cb](ExportResult exportResult) { cb->onFinished(exportResult); });
 
-    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();
-        }
-    }
-    return Status::ok();
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
-Status KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name, int32_t purpose,
+Status KeyStoreService::begin(const sp<IKeystoreOperationResultCallback>& cb,
+                              const sp<IBinder>& appToken, const String16& name, int32_t purpose,
                               bool pruneable, const KeymasterArguments& params,
                               const ::std::vector<uint8_t>& entropy, int32_t uid,
-                              OperationResult* result) {
-    auto keyPurpose = static_cast<KeyPurpose>(purpose);
-
+                              int32_t* _aidl_return) {
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     uid_t targetUid = getEffectiveUid(uid);
     if (!is_granted_to(callingUid, targetUid)) {
         ALOGW("uid %d not permitted to act for uid %d in begin", callingUid, targetUid);
-        result->resultCode = ResponseCode::PERMISSION_DENIED;
-        return Status::ok();
+        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
     }
     if (!pruneable && get_app_id(callingUid) != AID_SYSTEM) {
         ALOGE("Non-system uid %d trying to start non-pruneable operation", callingUid);
-        result->resultCode = ResponseCode::PERMISSION_DENIED;
-        return Status::ok();
+        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
     }
     if (!checkAllowedOperationParams(params.getParameters())) {
-        result->resultCode = ErrorCode::INVALID_ARGUMENT;
-        return Status::ok();
+        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
     }
 
-    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 AIDL_RETURN(ErrorCode::KEY_USER_NOT_AUTHENTICATED);
+    }
+    if (rc != ResponseCode::NO_ERROR) return AIDL_RETURN(rc);
+
     auto dev = mKeyStore->getDevice(keyBlob);
     AuthorizationSet opParams = params.getParameters();
-    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();
-    }
+    dev->begin(std::move(lockedEntry), appToken, std::move(keyBlob), std::move(charBlob), pruneable,
+               static_cast<KeyPurpose>(purpose), std::move(opParams), entropy,
+               [this, cb, dev](OperationResult result_) {
+                   if (result_.resultCode.isOk() ||
+                       result_.resultCode == ResponseCode::OP_AUTH_NEEDED) {
+                       addOperationDevice(result_.token, dev);
+                   }
+                   cb->onFinished(result_);
+               });
 
-    // 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");
-    }
-
-    // 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.
-    return Status::ok();
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
-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) {
+Status KeyStoreService::update(const ::android::sp<IKeystoreOperationResultCallback>& cb,
+                               const ::android::sp<::android::IBinder>& token,
+                               const ::android::security::keymaster::KeymasterArguments& params,
+                               const ::std::vector<uint8_t>& input, int32_t* _aidl_return) {
     if (!checkAllowedOperationParams(params.getParameters())) {
-        result->resultCode = ErrorCode::INVALID_ARGUMENT;
-        return Status::ok();
+        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
     }
 
-    auto getOpResult = mOperationMap.getOperation(token);
-    if (!getOpResult.isOk()) {
-        result->resultCode = ErrorCode::INVALID_OPERATION_HANDLE;
-        return Status::ok();
+    auto dev = getOperationDevice(token);
+    if (!dev) {
+        return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
     }
-    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(), input, [this, cb, token](OperationResult result_) {
+        if (!result_.resultCode.isOk()) {
+            removeOperationDevice(token);
         }
-    };
+        cb->onFinished(result_);
+    });
 
-    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);
-    }
-
-    return Status::ok();
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
-Status KeyStoreService::finish(const sp<IBinder>& token, const KeymasterArguments& params,
+Status KeyStoreService::finish(const ::android::sp<IKeystoreOperationResultCallback>& cb,
+                               const ::android::sp<::android::IBinder>& token,
+                               const ::android::security::keymaster::KeymasterArguments& params,
                                const ::std::vector<uint8_t>& 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());
+                               const ::std::vector<uint8_t>& entropy, int32_t* _aidl_return) {
     if (!checkAllowedOperationParams(params.getParameters())) {
-        result->resultCode = ErrorCode::INVALID_ARGUMENT;
-        return Status::ok();
+        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
     }
 
-    HardwareAuthToken authToken;
-    std::tie(result->resultCode, authToken) = getOperationAuthTokenIfNeeded(token);
-    if (!result->resultCode.isOk()) return Status::ok();
-
-    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) {
+        return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
     }
 
-    // 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,
+                [this, cb, token](OperationResult result_) {
+                    if (!result_.resultCode.isOk()) {
+                        removeOperationDevice(token);
+                    }
+                    cb->onFinished(result_);
+                });
 
-    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);
-    return Status::ok();
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
-Status KeyStoreService::abort(const sp<IBinder>& token, int32_t* aidl_return) {
-    auto getOpResult = mOperationMap.removeOperation(token, false /* wasOpSuccessful */);
-    if (!getOpResult.isOk()) {
-        *aidl_return = static_cast<int32_t>(ErrorCode::INVALID_OPERATION_HANDLE);
-        return Status::ok();
+Status KeyStoreService::abort(const ::android::sp<IKeystoreResponseCallback>& cb,
+                              const ::android::sp<::android::IBinder>& token,
+                              int32_t* _aidl_return) {
+    auto dev = getOperationDevice(token);
+    if (!dev) {
+        return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
     }
-    auto op = std::move(getOpResult.value());
-    mAuthTokenTable.MarkCompleted(op.handle);
 
-    ErrorCode error_code = KS_HANDLE_HIDL_ERROR(op.device->abort(op.handle));
-    *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(error_code));
-    return Status::ok();
-}
+    dev->abort(token, [cb](KeyStoreServiceReturnCode rc) { cb->onFinished(rc); });
 
-Status KeyStoreService::isOperationAuthorized(const sp<IBinder>& token, bool* aidl_return) {
-    AuthorizationSet ignored;
-    KeyStoreServiceReturnCode rc;
-    std::tie(rc, std::ignore) = getOperationAuthTokenIfNeeded(token);
-    *aidl_return = rc.isOk();
-    return Status::ok();
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
 Status KeyStoreService::addAuthToken(const ::std::vector<uint8_t>& authTokenAsVector,
@@ -1579,24 +949,25 @@
         return Status::ok();
     }
     if (authTokenAsVector.size() != sizeof(hw_auth_token_t)) {
-        *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
+        *aidl_return = KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT).getErrorCode();
         return Status::ok();
     }
 
     hw_auth_token_t authToken;
     memcpy(reinterpret_cast<void*>(&authToken), authTokenAsVector.data(), sizeof(hw_auth_token_t));
     if (authToken.version != 0) {
-        *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
+        *aidl_return = KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT).getErrorCode();
         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();
 }
 
 int isDeviceIdAttestationRequested(const KeymasterArguments& params) {
-    const hardware::hidl_vec<KeyParameter> paramsVec = params.getParameters();
+    const hardware::hidl_vec<KeyParameter>& paramsVec = params.getParameters();
     int result = 0;
     for (size_t i = 0; i < paramsVec.size(); ++i) {
         switch (paramsVec[i].tag) {
@@ -1619,13 +990,12 @@
     return result;
 }
 
-Status KeyStoreService::attestKey(const String16& name, const KeymasterArguments& params,
-                                  ::android::security::keymaster::KeymasterCertificateChain* chain,
-                                  int32_t* aidl_return) {
+Status KeyStoreService::attestKey(
+    const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
+    const String16& name, const KeymasterArguments& params, int32_t* _aidl_return) {
     // check null output if method signature is updated and return ErrorCode::OUTPUT_PARAMETER_NULL
     if (!checkAllowedOperationParams(params.getParameters())) {
-        *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
-        return Status::ok();
+        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
     }
 
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -1639,96 +1009,86 @@
     // unique device ID.
     if ((needsIdAttestation && !isSomeUserSystemUid) ||
         (needsUniqueIdAttestation && !isPrimaryUserSystemUid)) {
-        *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
-        return Status::ok();
+        return AIDL_RETURN(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
     }
 
     AuthorizationSet mutableParams = params.getParameters();
     KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
     if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
+        return AIDL_RETURN(rc);
     }
 
-    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()) {
-            return;
-        }
-        if (chain) {
-            *chain = KeymasterCertificateChain(certChain);
-        }
-    };
+    std::tie(rc, keyBlob, charBlob, lockedEntry) =
+        mKeyStore->getKeyForName(name8, callingUid, TYPE_KEYMASTER_10);
 
-    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);
-    return Status::ok();
+    auto hidlKey = blob2hidlVec(keyBlob);
+    dev->attestKey(
+        std::move(hidlKey), mutableParams.hidl_data(),
+        [cb](Return<void> rc, std::tuple<ErrorCode, hidl_vec<hidl_vec<uint8_t>>>&& hidlResult) {
+            auto& [ret, certChain] = hidlResult;
+            if (!rc.isOk()) {
+                cb->onFinished(KeyStoreServiceReturnCode(ResponseCode::SYSTEM_ERROR), {});
+            } else if (ret != ErrorCode::OK) {
+                cb->onFinished(KeyStoreServiceReturnCode(ret), {});
+            } else {
+                cb->onFinished(KeyStoreServiceReturnCode(ret),
+                               KeymasterCertificateChain(std::move(certChain)));
+            }
+        });
+
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
-Status
-KeyStoreService::attestDeviceIds(const KeymasterArguments& params,
-                                 ::android::security::keymaster::KeymasterCertificateChain* chain,
-                                 int32_t* aidl_return) {
+// My IDE defines "CAPTURE_MOVE(x) x" because it does not understand generalized lambda captures.
+// It should never be redefined by a build system though.
+#ifndef CAPTURE_MOVE
+#define CAPTURE_MOVE(x) x = std::move(x)
+#endif
+
+Status KeyStoreService::attestDeviceIds(
+    const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
+    const KeymasterArguments& params, int32_t* _aidl_return) {
     // check null output if method signature is updated and return ErrorCode::OUTPUT_PARAMETER_NULL
 
     if (!checkAllowedOperationParams(params.getParameters())) {
-        *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
-        return Status::ok();
+        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
     }
 
     if (!isDeviceIdAttestationRequested(params)) {
         // There is an attestKey() method for attesting keys without device ID attestation.
-        *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
-        return Status::ok();
+        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
     }
 
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
-    if (binder == 0) {
-        *aidl_return =
-            static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::CANNOT_ATTEST_IDS));
-        return Status::ok();
+    if (binder == nullptr) {
+        return AIDL_RETURN(ErrorCode::CANNOT_ATTEST_IDS);
     }
     if (!interface_cast<IPermissionController>(binder)->checkPermission(
             String16("android.permission.READ_PRIVILEGED_PHONE_STATE"),
             IPCThreadState::self()->getCallingPid(), callingUid)) {
-        *aidl_return =
-            static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::CANNOT_ATTEST_IDS));
-        return Status::ok();
+        return AIDL_RETURN(ErrorCode::CANNOT_ATTEST_IDS);
     }
 
     AuthorizationSet mutableParams = params.getParameters();
     KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
     if (!rc.isOk()) {
-        *aidl_return = static_cast<int32_t>(rc);
-        return Status::ok();
+        return AIDL_RETURN(rc);
     }
 
     // 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();
+        return AIDL_RETURN(ResponseCode::SYSTEM_ERROR);
     }
 
-    KeyStoreServiceReturnCode error;
-    ::std::vector<uint8_t> hidlKey;
 
     AuthorizationSet keyCharacteristics;
     keyCharacteristics.push_back(TAG_PURPOSE, KeyPurpose::VERIFY);
@@ -1736,66 +1096,66 @@
     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(),
+        [cb, dev, CAPTURE_MOVE(mutableParams)](
+            Return<void> rc,
+            std::tuple<ErrorCode, ::std::vector<uint8_t>, KeyCharacteristics>&& hidlResult) {
+            auto& [ret, hidlKeyBlob_, dummyCharacteristics] = hidlResult;
+            auto hidlKeyBlob = std::move(hidlKeyBlob_);
+            if (!rc.isOk()) {
+                cb->onFinished(KeyStoreServiceReturnCode(ResponseCode::SYSTEM_ERROR), {});
+                return;
+            }
+            if (ret != ErrorCode::OK) {
+                cb->onFinished(KeyStoreServiceReturnCode(ret), {});
+                return;
+            }
+            dev->attestKey(
+                hidlKeyBlob, mutableParams.hidl_data(),
+                [cb, dev,
+                 hidlKeyBlob](Return<void> rc,
+                              std::tuple<ErrorCode, hidl_vec<hidl_vec<uint8_t>>>&& hidlResult) {
+                    auto& [ret, certChain] = hidlResult;
+                    // schedule temp key for deletion
+                    dev->deleteKey(std::move(hidlKeyBlob), [](Return<ErrorCode> rc) {
+                        // log error but don't return an error
+                        KS_HANDLE_HIDL_ERROR(rc);
+                    });
+                    if (!rc.isOk()) {
+                        cb->onFinished(KeyStoreServiceReturnCode(ResponseCode::SYSTEM_ERROR), {});
+                        return;
+                    }
+                    if (ret == ErrorCode::OK) {
+                        cb->onFinished(
+                            KeyStoreServiceReturnCode(ret),
+                            ::android::security::keymaster::KeymasterCertificateChain(certChain));
+                    } else {
+                        cb->onFinished(KeyStoreServiceReturnCode(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);
-    return Status::ok();
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
 Status KeyStoreService::onDeviceOffBody(int32_t* aidl_return) {
     // TODO(tuckeris): add permission check.  This should be callable from ClockworkHome only.
-    mAuthTokenTable.onDeviceOffBody();
+    mKeyStore->getAuthTokenTable().onDeviceOffBody();
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
     return Status::ok();
 }
 
-#define AIDL_RETURN(rc)                                                                            \
-    (*_aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(rc)), Status::ok())
-
 Status KeyStoreService::importWrappedKey(
+    const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
     const ::android::String16& wrappedKeyAlias, const ::std::vector<uint8_t>& wrappedKey,
     const ::android::String16& wrappingKeyAlias, const ::std::vector<uint8_t>& maskingKey,
     const KeymasterArguments& params, int64_t rootSid, int64_t fingerprintSid,
-    ::android::security::keymaster::KeyCharacteristics* outCharacteristics, int32_t* _aidl_return) {
+    int32_t* _aidl_return) {
 
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
 
@@ -1803,80 +1163,41 @@
         return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
     }
 
-    Blob wrappingKeyBlob;
     String8 wrappingKeyName8(wrappingKeyAlias);
-    KeyStoreServiceReturnCode rc =
-        mKeyStore->getKeyForName(&wrappingKeyBlob, wrappingKeyName8, callingUid, TYPE_KEYMASTER_10);
+
+    KeyStoreServiceReturnCode rc;
+    Blob wrappingKeyBlob;
+    Blob wrappingCharBlob;
+    LockedKeyBlobEntry wrappingLockedEntry;
+
+    std::tie(rc, wrappingKeyBlob, wrappingCharBlob, wrappingLockedEntry) =
+        mKeyStore->getKeyForName(wrappingKeyName8, callingUid, TYPE_KEYMASTER_10);
     if (!rc.isOk()) {
         return AIDL_RETURN(rc);
     }
 
+    String8 wrappedKeyName8(wrappedKeyAlias);
+    auto wrappedLockedEntry =
+        mKeyStore->getLockedBlobEntryIfNotExists(wrappedKeyName8.string(), callingUid);
+    if (!wrappedLockedEntry) {
+        return AIDL_RETURN(ResponseCode::KEY_ALREADY_EXISTS);
+    }
+
     SecurityLevel securityLevel = wrappingKeyBlob.getSecurityLevel();
     auto dev = mKeyStore->getDevice(securityLevel);
     if (!dev) {
         return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
     }
 
-    auto hidlWrappingKey = blob2hidlVec(wrappingKeyBlob);
-    String8 wrappedKeyAlias8(wrappedKeyAlias);
+    dev->importWrappedKey(
+        std::move(wrappingLockedEntry), std::move(wrappedLockedEntry), wrappedKey, maskingKey,
+        params.getParameters(), std::move(wrappingKeyBlob), std::move(wrappingCharBlob), rootSid,
+        fingerprintSid, [cb](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+            cb->onFinished(rc,
+                           ::android::security::keymaster::KeyCharacteristics(keyCharacteristics));
+        });
 
-    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(wrappedKeyAlias8, callingUid, ::TYPE_KEYMASTER_10));
-
-        Blob ksBlob(&keyBlob[0], keyBlob.size(), NULL, 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(), NULL, 0,
-                  ::TYPE_KEY_CHARACTERISTICS);
-    charBlob.setSecurityLevel(securityLevel);
-
-    return AIDL_RETURN(mKeyStore->put(cFilename.string(), &charBlob, get_user_id(callingUid)));
+    return AIDL_RETURN(ResponseCode::NO_ERROR);
 }
 
 Status KeyStoreService::presentConfirmationPrompt(const sp<IBinder>& listener,
@@ -1884,35 +1205,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);
 }
 
 /**
@@ -2025,296 +1328,9 @@
     return true;
 }
 
-ErrorCode KeyStoreService::getOperationCharacteristics(const hidl_vec<uint8_t>& key,
-                                                       sp<Keymaster>* dev,
-                                                       const AuthorizationSet& params,
-                                                       KeyCharacteristics* out) {
-    ::std::vector<uint8_t> clientId;
-    ::std::vector<uint8_t> appData;
-    for (auto param : params) {
-        if (param.tag == Tag::APPLICATION_ID) {
-            clientId = authorizationValue(TAG_APPLICATION_ID, param).value();
-        } else if (param.tag == Tag::APPLICATION_DATA) {
-            appData = authorizationValue(TAG_APPLICATION_DATA, param).value();
-        }
-    }
-    ErrorCode error = ErrorCode::OK;
-
-    auto hidlCb = [&](ErrorCode ret, const KeyCharacteristics& keyCharacteristics) {
-        error = ret;
-        if (error != ErrorCode::OK) {
-            return;
-        }
-        if (out) *out = keyCharacteristics;
-    };
-
-    ErrorCode rc =
-        KS_HANDLE_HIDL_ERROR((*dev)->getKeyCharacteristics(key, clientId, appData, hidlCb));
-    if (rc != ErrorCode::OK) {
-        return rc;
-    }
-    return error;
-}
-
-/**
- * Get the auth token for this operation from the auth token table.
- *
- * Returns ResponseCode::NO_ERROR if the auth token was set or none was required.
- *         ::OP_AUTH_NEEDED if it is a per op authorization, no
- *         authorization token exists for that operation and
- *         failOnTokenMissing is false.
- *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth
- *         token for the operation
- */
-std::pair<KeyStoreServiceReturnCode, HardwareAuthToken>
-KeyStoreService::getAuthToken(const KeyCharacteristics& characteristics, uint64_t handle,
-                              KeyPurpose purpose, bool failOnTokenMissing) {
-
-    AuthorizationSet allCharacteristics(characteristics.softwareEnforced);
-    allCharacteristics.append(characteristics.hardwareEnforced.begin(),
-                              characteristics.hardwareEnforced.end());
-
-    const HardwareAuthToken* authToken = nullptr;
-    AuthTokenTable::Error err = mAuthTokenTable.FindAuthorization(
-        allCharacteristics, static_cast<KeyPurpose>(purpose), handle, &authToken);
-
-    KeyStoreServiceReturnCode rc;
-
-    switch (err) {
-    case AuthTokenTable::OK:
-    case AuthTokenTable::AUTH_NOT_REQUIRED:
-        rc = ResponseCode::NO_ERROR;
-        break;
-
-    case AuthTokenTable::AUTH_TOKEN_NOT_FOUND:
-    case AuthTokenTable::AUTH_TOKEN_EXPIRED:
-    case AuthTokenTable::AUTH_TOKEN_WRONG_SID:
-        ALOGE("getAuthToken failed: %d", err);  // STOPSHIP: debug only, to be removed
-        rc = ErrorCode::KEY_USER_NOT_AUTHENTICATED;
-        break;
-
-    case AuthTokenTable::OP_HANDLE_REQUIRED:
-        rc = failOnTokenMissing ? KeyStoreServiceReturnCode(ErrorCode::KEY_USER_NOT_AUTHENTICATED)
-                                : KeyStoreServiceReturnCode(ResponseCode::OP_AUTH_NEEDED);
-        break;
-
-    default:
-        ALOGE("Unexpected FindAuthorization return value %d", err);
-        rc = ErrorCode::INVALID_ARGUMENT;
-    }
-
-    return {rc, authToken ? std::move(*authToken) : HardwareAuthToken()};
-}
-
-/**
- * Add the auth token for the operation to the param list if the operation
- * requires authorization. Uses the cached result in the OperationMap if available
- * otherwise gets the token from the AuthTokenTable and caches the result.
- *
- * Returns ResponseCode::NO_ERROR if the auth token was added or not needed.
- *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not
- *         authenticated.
- *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid
- *         operation token.
- */
-std::pair<KeyStoreServiceReturnCode, const HardwareAuthToken&>
-KeyStoreService::getOperationAuthTokenIfNeeded(const sp<IBinder>& token) {
-    static HardwareAuthToken emptyToken = {};
-
-    auto getOpResult = mOperationMap.getOperation(token);
-    if (!getOpResult.isOk()) return {ErrorCode::INVALID_OPERATION_HANDLE, emptyToken};
-    const auto& op = getOpResult.value();
-
-    if (!op.hasAuthToken()) {
-        KeyStoreServiceReturnCode rc;
-        HardwareAuthToken found;
-        std::tie(rc, found) = getAuthToken(op.characteristics, op.handle, op.purpose);
-        if (!rc.isOk()) return {rc, emptyToken};
-        mOperationMap.setOperationAuthToken(token, std::move(found));
-    }
-
-    return {ResponseCode::NO_ERROR, op.authToken};
-}
-
-/**
- * Translate a result value to a legacy return value. All keystore errors are
- * preserved and keymaster errors become SYSTEM_ERRORs
- */
-KeyStoreServiceReturnCode KeyStoreService::translateResultToLegacyResult(int32_t result) {
-    if (result > 0) return static_cast<ResponseCode>(result);
-    return ResponseCode::SYSTEM_ERROR;
-}
-
-static NullOr<const Algorithm&> getKeyAlgoritmFromKeyCharacteristics(
-    const ::android::security::keymaster::KeyCharacteristics& characteristics) {
-    for (const auto& param : characteristics.hardwareEnforced.getParameters()) {
-        auto algo = authorizationValue(TAG_ALGORITHM, param);
-        if (algo.isOk()) return algo;
-    }
-    for (const auto& param : characteristics.softwareEnforced.getParameters()) {
-        auto algo = authorizationValue(TAG_ALGORITHM, param);
-        if (algo.isOk()) return algo;
-    }
-    return {};
-}
-
-void KeyStoreService::addLegacyBeginParams(const String16& name, AuthorizationSet* params) {
-    // All legacy keys are DIGEST_NONE/PAD_NONE.
-    params->push_back(TAG_DIGEST, Digest::NONE);
-    params->push_back(TAG_PADDING, PaddingMode::NONE);
-
-    // Look up the algorithm of the key.
-    ::android::security::keymaster::KeyCharacteristics characteristics;
-    int32_t result;
-    auto rc = getKeyCharacteristics(name, ::android::security::keymaster::KeymasterBlob(),
-                                    ::android::security::keymaster::KeymasterBlob(), UID_SELF,
-                                    &characteristics, &result);
-    if (!rc.isOk()) {
-        ALOGE("Failed to get key characteristics");
-        return;
-    }
-    auto algorithm = getKeyAlgoritmFromKeyCharacteristics(characteristics);
-    if (!algorithm.isOk()) {
-        ALOGE("getKeyCharacteristics did not include KM_TAG_ALGORITHM");
-        return;
-    }
-    params->push_back(TAG_ALGORITHM, algorithm.value());
-}
-
-KeyStoreServiceReturnCode KeyStoreService::doLegacySignVerify(const String16& name,
-                                                              const hidl_vec<uint8_t>& data,
-                                                              hidl_vec<uint8_t>* out,
-                                                              const hidl_vec<uint8_t>& signature,
-                                                              KeyPurpose purpose) {
-
-    std::basic_stringstream<uint8_t> outBuffer;
-    OperationResult result;
-    AuthorizationSet inArgs;
-    addLegacyBeginParams(name, &inArgs);
-    sp<IBinder> appToken(new BBinder);
-    sp<IBinder> token;
-
-    begin(appToken, name, static_cast<int32_t>(purpose), true,
-          KeymasterArguments(inArgs.hidl_data()), ::std::vector<uint8_t>(), UID_SELF, &result);
-    if (!result.resultCode.isOk()) {
-        if (result.resultCode == ResponseCode::KEY_NOT_FOUND) {
-            ALOGW("Key not found");
-        } else {
-            ALOGW("Error in begin: %d", int32_t(result.resultCode));
-        }
-        return translateResultToLegacyResult(result.resultCode);
-    }
-    inArgs.Clear();
-    token = result.token;
-    size_t consumed = 0;
-    size_t lastConsumed = 0;
-    hidl_vec<uint8_t> data_view;
-    do {
-        data_view.setToExternal(const_cast<uint8_t*>(&data[consumed]), data.size() - consumed);
-        update(token, KeymasterArguments(inArgs.hidl_data()), data_view, &result);
-        if (result.resultCode != ResponseCode::NO_ERROR) {
-            ALOGW("Error in update: %d", int32_t(result.resultCode));
-            return translateResultToLegacyResult(result.resultCode);
-        }
-        if (out) {
-            outBuffer.write(&result.data[0], result.data.size());
-        }
-        lastConsumed = result.inputConsumed;
-        consumed += lastConsumed;
-    } while (consumed < data.size() && lastConsumed > 0);
-
-    if (consumed != data.size()) {
-        ALOGW("Not all data consumed. Consumed %zu of %zu", consumed, data.size());
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    finish(token, KeymasterArguments(inArgs.hidl_data()), signature, ::std::vector<uint8_t>(),
-           &result);
-    if (result.resultCode != ResponseCode::NO_ERROR) {
-        ALOGW("Error in finish: %d", int32_t(result.resultCode));
-        return translateResultToLegacyResult(result.resultCode);
-    }
-    if (out) {
-        outBuffer.write(&result.data[0], result.data.size());
-    }
-
-    if (out) {
-        auto buf = outBuffer.str();
-        out->resize(buf.size());
-        memcpy(&(*out)[0], buf.data(), out->size());
-    }
-
-    return ResponseCode::NO_ERROR;
-}
-
-KeyStoreServiceReturnCode KeyStoreService::upgradeKeyBlob(const String16& name, uid_t uid,
-                                                          const AuthorizationSet& params,
-                                                          Blob* blob) {
-    // Read the blob rather than assuming the caller provided the right name/uid/blob triplet.
-    String8 name8(name);
-    KeyStoreServiceReturnCode responseCode =
-        mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
-    if (responseCode != ResponseCode::NO_ERROR) {
-        return responseCode;
-    }
-    ALOGI("upgradeKeyBlob %s %d", name8.string(), uid);
-
-    auto hidlKey = blob2hidlVec(*blob);
-    auto dev = mKeyStore->getDevice(*blob);
-
-    KeyStoreServiceReturnCode error;
-    auto hidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& upgradedKeyBlob) {
-        error = ret;
-        if (!error.isOk()) {
-            if (error == ErrorCode::INVALID_KEY_BLOB) {
-                log_key_integrity_violation(name8, uid);
-            }
-            return;
-        }
-
-        auto filename = mKeyStore->getBlobFileNameIfExists(name8, uid, ::TYPE_KEYMASTER_10);
-        if (!filename.isOk()) {
-            ALOGI("trying to upgrade a non existing blob");
-            return;
-        }
-        error = mKeyStore->del(filename.value().string(), ::TYPE_ANY, get_user_id(uid));
-        if (!error.isOk()) {
-            ALOGI("upgradeKeyBlob keystore->del failed %d", (int)error);
-            return;
-        }
-
-        Blob newBlob(&upgradedKeyBlob[0], upgradedKeyBlob.size(), nullptr /* info */,
-                     0 /* infoLength */, ::TYPE_KEYMASTER_10);
-        newBlob.setSecurityLevel(blob->getSecurityLevel());
-        newBlob.setEncrypted(blob->isEncrypted());
-        newBlob.setSuperEncrypted(blob->isSuperEncrypted());
-        newBlob.setCriticalToDeviceEncryption(blob->isCriticalToDeviceEncryption());
-
-        error = mKeyStore->put(filename.value().string(), &newBlob, get_user_id(uid));
-        if (!error.isOk()) {
-            ALOGI("upgradeKeyBlob keystore->put failed %d", (int)error);
-            return;
-        }
-
-        // Re-read blob for caller.  We can't use newBlob because writing it modified it.
-        error = mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
-    };
-
-    KeyStoreServiceReturnCode rc =
-        KS_HANDLE_HIDL_ERROR(dev->upgradeKey(hidlKey, params.hidl_data(), hidlCb));
-    if (!rc.isOk()) {
-        return rc;
-    }
-
-    return error;
-}
-
 Status KeyStoreService::onKeyguardVisibilityChanged(bool isShowing, int32_t userId,
                                                     int32_t* aidl_return) {
-    enforcement_policy.set_device_locked(isShowing, userId);
-    if (!isShowing) {
-        mActiveUserId = 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 0056342..2171213 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -17,7 +17,7 @@
 #ifndef KEYSTORE_KEYSTORE_SERVICE_H_
 #define KEYSTORE_KEYSTORE_SERVICE_H_
 
-#include <android/security/BnKeystoreService.h>
+#include <android/security/keystore/BnKeystoreService.h>
 
 #include "auth_token_table.h"
 #include "confirmation_manager.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::keystore::BnKeystoreService {
   public:
-    explicit KeyStoreService(KeyStore* keyStore)
-        : mKeyStore(keyStore), mOperationMap(this),
-          mConfirmationManager(new ConfirmationManager(this)), mActiveUserId(0) {}
+    explicit KeyStoreService(sp<KeyStore> keyStore) : mKeyStore(keyStore) {}
     virtual ~KeyStoreService() = default;
 
     void binderDied(const android::wp<android::IBinder>& who);
@@ -56,6 +61,9 @@
                                     int32_t* _aidl_return) override;
     ::android::binder::Status list(const ::android::String16& namePrefix, int32_t uid,
                                    ::std::vector<::android::String16>* _aidl_return) override;
+    ::android::binder::Status listUidsOfAuthBoundKeys(std::vector<::std::string>* uids,
+                                                      int32_t* _aidl_return) override;
+
     ::android::binder::Status reset(int32_t* _aidl_return) override;
     ::android::binder::Status onUserPasswordChanged(int32_t userId,
                                                     const ::android::String16& newPassword,
@@ -64,33 +72,6 @@
     ::android::binder::Status unlock(int32_t userId, const ::android::String16& userPassword,
                                      int32_t* _aidl_return) override;
     ::android::binder::Status isEmpty(int32_t userId, int32_t* _aidl_return) override;
-    ::android::binder::Status generate(const ::android::String16& name, int32_t uid,
-                                       int32_t keyType, int32_t keySize, int32_t flags,
-                                       const ::android::security::KeystoreArguments& args,
-                                       int32_t* _aidl_return) override;
-    ::android::binder::Status import_key(const ::android::String16& name,
-                                         const ::std::vector<uint8_t>& data, int32_t uid,
-                                         int32_t flags, int32_t* _aidl_return) override;
-    ::android::binder::Status sign(const ::android::String16& name,
-                                   const ::std::vector<uint8_t>& data,
-                                   ::std::vector<uint8_t>* _aidl_return) override;
-    ::android::binder::Status verify(const ::android::String16& name,
-                                     const ::std::vector<uint8_t>& data,
-                                     const ::std::vector<uint8_t>& signature,
-                                     int32_t* _aidl_return) override;
-    /*
-     * TODO: The abstraction between things stored in hardware and regular blobs
-     * of data stored on the filesystem should be moved down to keystore itself.
-     * Unfortunately the Java code that calls this has naming conventions that it
-     * knows about. Ideally keystore shouldn't be used to store random blobs of
-     * data.
-     *
-     * Until that happens, it's necessary to have a separate "get_pubkey" and
-     * "del_key" since the Java code doesn't really communicate what it's
-     * intentions are.
-     */
-    ::android::binder::Status get_pubkey(const ::android::String16& name,
-                                         ::std::vector<uint8_t>* _aidl_return) override;
     ::android::binder::Status grant(const ::android::String16& name, int32_t granteeUid,
                                     ::android::String16* _aidl_return) override;
     ::android::binder::Status ungrant(const ::android::String16& name, int32_t granteeUid,
@@ -100,73 +81,76 @@
     ::android::binder::Status is_hardware_backed(const ::android::String16& string,
                                                  int32_t* _aidl_return) override;
     ::android::binder::Status clear_uid(int64_t uid, int32_t* _aidl_return) override;
-    ::android::binder::Status addRngEntropy(const ::std::vector<uint8_t>& data, int32_t flags,
-                                            int32_t* _aidl_return) override;
     ::android::binder::Status
-    generateKey(const ::android::String16& alias,
-                const ::android::security::keymaster::KeymasterArguments& arguments,
-                const ::std::vector<uint8_t>& entropy, int32_t uid, int32_t flags,
-                ::android::security::keymaster::KeyCharacteristics* characteristics,
-                int32_t* _aidl_return) override;
+    addRngEntropy(const ::android::sp<::android::security::keystore::IKeystoreResponseCallback>& cb,
+                  const ::std::vector<uint8_t>& data, int32_t flags,
+                  int32_t* _aidl_return) override;
+    ::android::binder::Status generateKey(
+        const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
+        const ::android::String16& alias,
+        const ::android::security::keymaster::KeymasterArguments& arguments,
+        const ::std::vector<uint8_t>& entropy, int32_t uid, int32_t flags,
+        int32_t* _aidl_return) override;
+    ::android::binder::Status getKeyCharacteristics(
+        const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
+        const ::android::String16& alias,
+        const ::android::security::keymaster::KeymasterBlob& clientId,
+        const ::android::security::keymaster::KeymasterBlob& appId, int32_t uid,
+        int32_t* _aidl_return) override;
+    ::android::binder::Status importKey(
+        const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
+        const ::android::String16& alias,
+        const ::android::security::keymaster::KeymasterArguments& arguments, int32_t format,
+        const ::std::vector<uint8_t>& keyData, int32_t uid, int32_t flags,
+        int32_t* _aidl_return) override;
     ::android::binder::Status
-    getKeyCharacteristics(const ::android::String16& alias,
-                          const ::android::security::keymaster::KeymasterBlob& clientId,
-                          const ::android::security::keymaster::KeymasterBlob& appId, int32_t uid,
-                          ::android::security::keymaster::KeyCharacteristics* characteristics,
-                          int32_t* _aidl_return) override;
-    ::android::binder::Status
-    importKey(const ::android::String16& alias,
-              const ::android::security::keymaster::KeymasterArguments& arguments, int32_t format,
-              const ::std::vector<uint8_t>& keyData, int32_t uid, int32_t flags,
-              ::android::security::keymaster::KeyCharacteristics* characteristics,
-              int32_t* _aidl_return) override;
-    ::android::binder::Status
-    exportKey(const ::android::String16& alias, int32_t format,
+    exportKey(const ::android::sp<::android::security::keystore::IKeystoreExportKeyCallback>& cb,
+              const ::android::String16& alias, int32_t format,
               const ::android::security::keymaster::KeymasterBlob& clientId,
               const ::android::security::keymaster::KeymasterBlob& appId, int32_t uid,
-              ::android::security::keymaster::ExportResult* _aidl_return) override;
+              int32_t* _aidl_return) override;
     ::android::binder::Status
-    begin(const ::android::sp<::android::IBinder>& appToken, const ::android::String16& alias,
+    begin(const ::android::sp<::android::security::keystore::IKeystoreOperationResultCallback>& cb,
+          const ::android::sp<::android::IBinder>& appToken, const ::android::String16& alias,
           int32_t purpose, bool pruneable,
           const ::android::security::keymaster::KeymasterArguments& params,
-          const ::std::vector<uint8_t>& entropy, int32_t uid,
-          ::android::security::keymaster::OperationResult* _aidl_return) override;
+          const ::std::vector<uint8_t>& entropy, int32_t uid, int32_t* _aidl_return) override;
     ::android::binder::Status
-    update(const ::android::sp<::android::IBinder>& token,
+    update(const ::android::sp<::android::security::keystore::IKeystoreOperationResultCallback>& cb,
+           const ::android::sp<::android::IBinder>& token,
            const ::android::security::keymaster::KeymasterArguments& params,
-           const ::std::vector<uint8_t>& input,
-           ::android::security::keymaster::OperationResult* _aidl_return) override;
+           const ::std::vector<uint8_t>& input, int32_t* _aidl_return) override;
     ::android::binder::Status
-    finish(const ::android::sp<::android::IBinder>& token,
+    finish(const ::android::sp<::android::security::keystore::IKeystoreOperationResultCallback>& cb,
+           const ::android::sp<::android::IBinder>& token,
            const ::android::security::keymaster::KeymasterArguments& params,
            const ::std::vector<uint8_t>& signature, const ::std::vector<uint8_t>& entropy,
-           ::android::security::keymaster::OperationResult* _aidl_return) override;
-    ::android::binder::Status abort(const ::android::sp<::android::IBinder>& handle,
-                                    int32_t* _aidl_return) override;
-    ::android::binder::Status isOperationAuthorized(const ::android::sp<::android::IBinder>& token,
-                                                    bool* _aidl_return) override;
+           int32_t* _aidl_return) override;
+    ::android::binder::Status
+    abort(const ::android::sp<::android::security::keystore::IKeystoreResponseCallback>& cb,
+          const ::android::sp<::android::IBinder>& token, int32_t* _aidl_return) override;
     ::android::binder::Status addAuthToken(const ::std::vector<uint8_t>& authToken,
                                            int32_t* _aidl_return) override;
     ::android::binder::Status onUserAdded(int32_t userId, int32_t parentId,
                                           int32_t* _aidl_return) override;
     ::android::binder::Status onUserRemoved(int32_t userId, int32_t* _aidl_return) override;
-    ::android::binder::Status
-    attestKey(const ::android::String16& alias,
-              const ::android::security::keymaster::KeymasterArguments& params,
-              ::android::security::keymaster::KeymasterCertificateChain* chain,
-              int32_t* _aidl_return) override;
-    ::android::binder::Status
-    attestDeviceIds(const ::android::security::keymaster::KeymasterArguments& params,
-                    ::android::security::keymaster::KeymasterCertificateChain* chain,
-                    int32_t* _aidl_return) override;
+    ::android::binder::Status attestKey(
+        const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
+        const ::android::String16& alias,
+        const ::android::security::keymaster::KeymasterArguments& params,
+        int32_t* _aidl_return) override;
+    ::android::binder::Status attestDeviceIds(
+        const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
+        const ::android::security::keymaster::KeymasterArguments& params,
+        int32_t* _aidl_return) override;
     ::android::binder::Status onDeviceOffBody(int32_t* _aidl_return) override;
 
     ::android::binder::Status importWrappedKey(
+        const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
         const ::android::String16& wrappedKeyAlias, const ::std::vector<uint8_t>& wrappedKey,
         const ::android::String16& wrappingKeyAlias, const ::std::vector<uint8_t>& maskingKey,
         const ::android::security::keymaster::KeymasterArguments& params, int64_t rootSid,
-        int64_t fingerprintSid, ::android::security::keymaster::KeyCharacteristics* characteristics,
-        int32_t* _aidl_return) override;
+        int64_t fingerprintSid, int32_t* _aidl_return) override;
 
     ::android::binder::Status presentConfirmationPrompt(
         const ::android::sp<::android::IBinder>& listener, const ::android::String16& promptText,
@@ -178,17 +162,12 @@
     ::android::binder::Status isConfirmationPromptSupported(bool* _aidl_return) override;
 
     ::android::binder::Status onKeyguardVisibilityChanged(bool isShowing, int32_t userId,
-                                                          int32_t* _aidl_return);
+                                                          int32_t* _aidl_return) override;
 
   private:
     static const int32_t UID_SELF = -1;
 
     /**
-     * Prune the oldest pruneable operation.
-     */
-    bool pruneOperation();
-
-    /**
      * Get the effective target uid for a binder operation that takes an
      * optional uid as the target.
      */
@@ -235,41 +214,6 @@
      */
     bool checkAllowedOperationParams(const hidl_vec<KeyParameter>& params);
 
-    ErrorCode getOperationCharacteristics(const hidl_vec<uint8_t>& key, sp<Keymaster>* dev,
-                                          const AuthorizationSet& params, KeyCharacteristics* out);
-
-    /**
-     * Get the auth token for this operation from the auth token table.
-     *
-     * Returns NO_ERROR if the auth token was found or none was required.  If not needed, the
-     *             token will be empty (which keymaster interprets as no auth token).
-     *         OP_AUTH_NEEDED if it is a per op authorization, no authorization token exists for
-     *             that operation and  failOnTokenMissing is false.
-     *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth token for the operation
-     */
-    std::pair<KeyStoreServiceReturnCode, HardwareAuthToken>
-    getAuthToken(const KeyCharacteristics& characteristics, uint64_t handle, KeyPurpose purpose,
-                 bool failOnTokenMissing = true);
-
-    /**
-     * Get the auth token for the operation if the operation requires authorization. Uses the cached
-     * result in the OperationMap if available otherwise gets the token from the AuthTokenTable and
-     * caches the result.
-     *
-     * Returns NO_ERROR if the auth token was found or not needed.  If not needed, the token will
-     *             be empty (which keymaster interprets as no auth token).
-     *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not authenticated.
-     *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid operation token.
-     */
-    std::pair<KeyStoreServiceReturnCode, const HardwareAuthToken&>
-    getOperationAuthTokenIfNeeded(const sp<android::IBinder>& token);
-
-    /**
-     * Translate a result value to a legacy return value. All keystore errors are
-     * preserved and keymaster errors become SYSTEM_ERRORs
-     */
-    KeyStoreServiceReturnCode translateResultToLegacyResult(int32_t result);
-
     void addLegacyBeginParams(const android::String16& name, AuthorizationSet* params);
 
     KeyStoreServiceReturnCode doLegacySignVerify(const android::String16& name,
@@ -279,28 +223,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;
-    int32_t mActiveUserId;
+    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/keyblob_utils.cpp b/keystore/keyblob_utils.cpp
index 3616822..6c2fac9 100644
--- a/keystore/keyblob_utils.cpp
+++ b/keystore/keyblob_utils.cpp
@@ -48,7 +48,7 @@
 
 uint8_t* add_softkey_header(uint8_t* key_blob, size_t key_blob_length) {
     if (key_blob_length < sizeof(SOFT_KEY_MAGIC)) {
-        return NULL;
+        return nullptr;
     }
 
     memcpy(key_blob, SOFT_KEY_MAGIC, sizeof(SOFT_KEY_MAGIC));
diff --git a/keystore/keymaster_enforcement.cpp b/keystore/keymaster_enforcement.cpp
index 5a6e591..a17cd94 100644
--- a/keystore/keymaster_enforcement.cpp
+++ b/keystore/keymaster_enforcement.cpp
@@ -25,57 +25,15 @@
 
 #include <openssl/evp.h>
 
-#include <cutils/log.h>
 #include <hardware/hw_auth_token.h>
+#include <log/log.h>
+
 #include <list>
 
 #include <keystore/keystore_hidl_support.h>
 
 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() &&
@@ -106,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,
@@ -389,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;
         }
@@ -427,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;
 }
 
@@ -544,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;
@@ -553,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;
@@ -578,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;
@@ -587,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..d2175b8
--- /dev/null
+++ b/keystore/keymaster_worker.cpp
@@ -0,0 +1,1086 @@
+/*
+**
+** 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::~Worker() {
+    std::unique_lock<std::mutex> lock(pending_requests_mutex_);
+    pending_requests_cond_var_.wait(lock, [this] { return pending_requests_.empty(); });
+}
+void Worker::addRequest(WorkerTask request) {
+    std::unique_lock<std::mutex> lock(pending_requests_mutex_);
+    bool start_thread = pending_requests_.empty();
+    pending_requests_.push(std::move(request));
+    lock.unlock();
+    if (start_thread) {
+        auto worker = std::thread([this] {
+            std::unique_lock<std::mutex> lock(pending_requests_mutex_);
+            running_ = true;
+            while (!pending_requests_.empty()) {
+                auto request = std::move(pending_requests_.front());
+                lock.unlock();
+                request();
+                lock.lock();
+                pending_requests_.pop();
+                pending_requests_cond_var_.notify_all();
+            }
+        });
+        worker.detach();
+    }
+}
+
+KeymasterWorker::KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore)
+    : keymasterDevice_(std::move(keymasterDevice)), operationMap_(keyStore), keyStore_(keyStore) {
+    // make sure that hal version is cached.
+    if (keymasterDevice_) keymasterDevice_->halVersion();
+}
+
+std::tuple<KeyStoreServiceReturnCode, Blob>
+KeymasterWorker::upgradeKeyBlob(const LockedKeyBlobEntry& lockedEntry,
+                                const AuthorizationSet& params) {
+    LOG(INFO) << "upgradeKeyBlob " << lockedEntry->alias() << " " << (uint32_t)lockedEntry->uid();
+
+    std::tuple<KeyStoreServiceReturnCode, Blob> result;
+
+    auto userState = keyStore_->getUserStateDB().getUserStateByUid(lockedEntry->uid());
+
+    Blob& blob = std::get<1>(result);
+    KeyStoreServiceReturnCode& error = std::get<0>(result);
+
+    Blob charBlob;
+    ResponseCode rc;
+
+    std::tie(rc, blob, charBlob) =
+        lockedEntry.readBlobs(userState->getEncryptionKey(), userState->getState());
+
+    userState = {};
+
+    if (rc != ResponseCode::NO_ERROR) {
+        return error = rc, result;
+    }
+
+    auto hidlKey = blob2hidlVec(blob);
+    auto& dev = keymasterDevice_;
+
+    auto hidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& upgradedKeyBlob) {
+        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", error.getErrorCode());
+            return;
+        }
+
+        Blob newBlob(&upgradedKeyBlob[0], upgradedKeyBlob.size(), nullptr /* info */,
+                     0 /* infoLength */, ::TYPE_KEYMASTER_10);
+        newBlob.setSecurityLevel(blob.getSecurityLevel());
+        newBlob.setEncrypted(blob.isEncrypted());
+        newBlob.setSuperEncrypted(blob.isSuperEncrypted());
+        newBlob.setCriticalToDeviceEncryption(blob.isCriticalToDeviceEncryption());
+
+        error = keyStore_->put(lockedEntry, newBlob, charBlob);
+        if (!error.isOk()) {
+            ALOGI("upgradeKeyBlob keystore->put failed %d", error.getErrorCode());
+            return;
+        }
+        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(), rc.getErrorCode());
+        return false;
+    }
+    return true;
+}
+
+// My IDE defines "CAPTURE_MOVE(x) x" because it does not understand generalized lambda captures.
+// It should never be redefined by a build system though.
+#ifndef CAPTURE_MOVE
+#define CAPTURE_MOVE(x) x = std::move(x)
+#endif
+
+void KeymasterWorker::begin(LockedKeyBlobEntry lockedEntry, sp<IBinder> appToken, Blob keyBlob,
+                            Blob charBlob, bool pruneable, KeyPurpose purpose,
+                            AuthorizationSet opParams, hidl_vec<uint8_t> entropy,
+                            worker_begin_cb worker_cb) {
+
+    Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), CAPTURE_MOVE(appToken),
+                        CAPTURE_MOVE(keyBlob), CAPTURE_MOVE(charBlob), pruneable, purpose,
+                        CAPTURE_MOVE(opParams), CAPTURE_MOVE(entropy),
+                        CAPTURE_MOVE(worker_cb)]() mutable {
+        // Concurrently executed
+
+        auto& dev = keymasterDevice_;
+
+        KeyCharacteristics characteristics;
+
+        {
+            hidl_vec<uint8_t> clientId;
+            hidl_vec<uint8_t> appData;
+            for (const auto& param : opParams) {
+                if (param.tag == Tag::APPLICATION_ID) {
+                    clientId = authorizationValue(TAG_APPLICATION_ID, param).value();
+                } else if (param.tag == Tag::APPLICATION_DATA) {
+                    appData = authorizationValue(TAG_APPLICATION_DATA, param).value();
+                }
+            }
+            KeyStoreServiceReturnCode error;
+            std::tie(error, characteristics, keyBlob, charBlob) = createKeyCharacteristicsCache(
+                lockedEntry, clientId, appData, std::move(keyBlob), std::move(charBlob));
+            if (!error.isOk()) {
+                worker_cb(operationFailed(error));
+                return;
+            }
+        }
+
+        KeyStoreServiceReturnCode rc, authRc;
+        HardwareAuthToken authToken;
+        std::tie(authRc, authToken) = getAuthToken(characteristics, 0 /* no challenge */, purpose,
+                                                   /*failOnTokenMissing*/ false);
+
+        // If per-operation auth is needed we need to begin the operation and
+        // the client will need to authorize that operation before calling
+        // update. Any other auth issues stop here.
+        if (!authRc.isOk() && authRc != ResponseCode::OP_AUTH_NEEDED) {
+            return worker_cb(operationFailed(authRc));
+        }
+
+        // Add entropy to the device first.
+        if (entropy.size()) {
+            rc = KS_HANDLE_HIDL_ERROR(dev->addRngEntropy(entropy));
+            if (!rc.isOk()) {
+                return worker_cb(operationFailed(rc));
+            }
+        }
+
+        // Create a keyid for this key.
+        auto keyid = KeymasterEnforcement::CreateKeyId(blob2hidlVec(keyBlob));
+        if (!keyid) {
+            ALOGE("Failed to create a key ID for authorization checking.");
+            return worker_cb(operationFailed(ErrorCode::UNKNOWN_ERROR));
+        }
+
+        // Check that all key authorization policy requirements are met.
+        AuthorizationSet key_auths = characteristics.hardwareEnforced;
+        key_auths.append(characteristics.softwareEnforced.begin(),
+                         characteristics.softwareEnforced.end());
+
+        rc = keyStore_->getEnforcementPolicy().AuthorizeOperation(
+            purpose, *keyid, key_auths, opParams, authToken, 0 /* op_handle */,
+            true /* is_begin_operation */);
+        if (!rc.isOk()) {
+            return worker_cb(operationFailed(rc));
+        }
+
+        // If there are more than kMaxOperations, abort the oldest operation that was started as
+        // pruneable.
+        while (operationMap_.getOperationCount() >= kMaxOperations) {
+            ALOGD("Reached or exceeded concurrent operations limit");
+            if (!pruneOperation()) {
+                break;
+            }
+        }
+
+        android::security::keymaster::OperationResult result;
+
+        auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
+                          uint64_t operationHandle) {
+            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, blob2hidlVec(keyBlob),
+                                                 opParams.hidl_data(), authToken, hidlCb));
+            if (!rc.isOk()) {
+                LOG(ERROR) << "Got error " << rc << " from begin()";
+                return worker_cb(operationFailed(ResponseCode::SYSTEM_ERROR));
+            }
+
+            if (result.resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
+                std::tie(rc, keyBlob) = upgradeKeyBlob(lockedEntry, opParams);
+                if (!rc.isOk()) {
+                    return worker_cb(operationFailed(rc));
+                }
+
+                rc = KS_HANDLE_HIDL_ERROR(dev->begin(purpose, blob2hidlVec(keyBlob),
+                                                     opParams.hidl_data(), authToken, hidlCb));
+                if (!rc.isOk()) {
+                    LOG(ERROR) << "Got error " << rc << " from begin()";
+                    return worker_cb(operationFailed(ResponseCode::SYSTEM_ERROR));
+                }
+            }
+            // If there are too many operations abort the oldest operation that was
+            // started as pruneable and try again.
+        } while (result.resultCode == ErrorCode::TOO_MANY_OPERATIONS && pruneOperation());
+
+        rc = result.resultCode;
+        if (!rc.isOk()) {
+            return worker_cb(operationFailed(rc));
+        }
+
+        // Note: The operation map takes possession of the contents of "characteristics".
+        // It is safe to use characteristics after the following line but it will be empty.
+        sp<IBinder> operationToken =
+            operationMap_.addOperation(result.handle, *keyid, purpose, dev, appToken,
+                                       std::move(characteristics), opParams.hidl_data(), pruneable);
+        assert(characteristics.hardwareEnforced.size() == 0);
+        assert(characteristics.softwareEnforced.size() == 0);
+        result.token = operationToken;
+
+        auto operation = operationMap_.getOperation(operationToken);
+        if (!operation) {
+            return worker_cb(operationFailed(ResponseCode::SYSTEM_ERROR));
+        }
+
+        if (authRc.isOk() && authToken.mac.size() &&
+            dev->halVersion().securityLevel == SecurityLevel::STRONGBOX) {
+            operation->authTokenFuture = operation->authTokenPromise.get_future();
+            std::weak_ptr<Operation> weak_operation = operation;
+
+            auto verifyTokenCB = [weak_operation](KeyStoreServiceReturnCode rc,
+                                                  HardwareAuthToken authToken,
+                                                  VerificationToken verificationToken) {
+                auto operation = weak_operation.lock();
+                if (!operation) {
+                    // operation aborted, nothing to do
+                    return;
+                }
+                if (rc.isOk()) {
+                    operation->authToken = std::move(authToken);
+                    operation->verificationToken = std::move(verificationToken);
+                }
+                operation->authTokenPromise.set_value(rc);
+            };
+            auto teeKmDevice = keyStore_->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
+            teeKmDevice->verifyAuthorization(result.handle, {}, std::move(authToken),
+                                             std::move(verifyTokenCB));
+        }
+
+        // Return the authentication lookup result. If this is a per operation
+        // auth'd key then the resultCode will be ::OP_AUTH_NEEDED and the
+        // application should get an auth token using the handle before the
+        // first call to update, which will fail if keystore hasn't received the
+        // auth token.
+        if (result.resultCode.isOk()) {
+            result.resultCode = authRc;
+        }
+        return worker_cb(result);
+    });
+}
+
+KeyStoreServiceReturnCode
+KeymasterWorker::getOperationAuthTokenIfNeeded(std::shared_ptr<Operation> op) {
+    if (!op) return ErrorCode::INVALID_OPERATION_HANDLE;
+
+    if (op->authTokenFuture.valid()) {
+        LOG(INFO) << "Waiting for verification token";
+        op->authTokenFuture.wait();
+        auto rc = op->authTokenFuture.get();
+        if (!rc.isOk()) {
+            return rc;
+        }
+        op->authTokenFuture = {};
+    } else if (!op->hasAuthToken()) {
+        KeyStoreServiceReturnCode rc;
+        HardwareAuthToken found;
+        std::tie(rc, found) = getAuthToken(op->characteristics, op->handle, op->purpose);
+        if (!rc.isOk()) return rc;
+        op->authToken = std::move(found);
+    }
+
+    return ResponseCode::NO_ERROR;
+}
+
+namespace {
+
+class Finalize {
+  private:
+    std::function<void()> f_;
+
+  public:
+    explicit Finalize(std::function<void()> f) : f_(f) {}
+    ~Finalize() {
+        if (f_) f_();
+    }
+    void release() { f_ = {}; }
+};
+
+}  // namespace
+
+void KeymasterWorker::update(sp<IBinder> token, AuthorizationSet params, hidl_vec<uint8_t> data,
+                             update_cb worker_cb) {
+    Worker::addRequest([this, CAPTURE_MOVE(token), CAPTURE_MOVE(params), CAPTURE_MOVE(data),
+                        CAPTURE_MOVE(worker_cb)]() {
+        KeyStoreServiceReturnCode rc;
+        auto op = operationMap_.getOperation(token);
+        if (!op) {
+            return worker_cb(operationFailed(ErrorCode::INVALID_OPERATION_HANDLE));
+        }
+
+        Finalize abort_operation_in_case_of_error([&] {
+            operationMap_.removeOperation(token, false);
+            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..c02d389
--- /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;
+        // NOLINTNEXTLINE(google-explicit-constructor)
+        template <typename F> NonCopyableFunction(F f) {
+            f_ = std::make_unique<NonCopyableFunctionTypeEraser<F>>(std::move(f));
+        }
+        NonCopyableFunction(NonCopyableFunction&& other) = default;
+        NonCopyableFunction& operator=(NonCopyableFunction&& other) = default;
+        NonCopyableFunction(const NonCopyableFunction& other) = delete;
+        NonCopyableFunction& operator=(const NonCopyableFunction& other) = delete;
+
+        Ret operator()(Args... args) {
+            if (f_) return (*f_)(std::move(args)...);
+        }
+    };
+
+    using WorkerTask = NonCopyableFunction<void()>;
+
+    std::queue<WorkerTask> pending_requests_;
+    std::mutex pending_requests_mutex_;
+    std::condition_variable pending_requests_cond_var_;
+    bool running_ = false;
+
+  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_aidl_hidl_marshalling_utils.cpp b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
index db9b983..49e18f0 100644
--- a/keystore/keystore_aidl_hidl_marshalling_utils.cpp
+++ b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
@@ -21,14 +21,13 @@
 #include <keystore/KeyCharacteristics.h>
 #include <keystore/KeymasterBlob.h>
 #include <keystore/KeymasterCertificateChain.h>
-#include <keystore/KeystoreArg.h>
 #include <keystore/keymaster_types.h>
 #include <keystore/keystore_hidl_support.h>
 
 namespace keystore {
 
 // reads byte[]
-hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in, bool inPlace) {
+hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in) {
 
     ssize_t length = in.readInt32();
     if (length <= 0) {
@@ -38,7 +37,7 @@
     const void* buf = in.readInplace(length);
     if (!buf) return {};
 
-    return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length), inPlace);
+    return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length));
 }
 
 android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out) {
@@ -220,7 +219,7 @@
 }
 
 status_t ExportResult::writeToParcel(Parcel* out) const {
-    out->writeInt32(resultCode);
+    out->writeInt32(resultCode.getErrorCode());
     return keystore::writeKeymasterBlob(exportData, out);
 }
 
@@ -235,7 +234,7 @@
 }
 
 status_t KeymasterBlob::readFromParcel(const Parcel* in) {
-    data_ = keystore::readKeymasterBlob(*in, true /* in place */);
+    data_ = keystore::readKeymasterBlob(*in);
     return OK;
 }
 
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.h b/keystore/keystore_aidl_hidl_marshalling_utils.h
index 13edbd2..ea72197 100644
--- a/keystore/keystore_aidl_hidl_marshalling_utils.h
+++ b/keystore/keystore_aidl_hidl_marshalling_utils.h
@@ -60,7 +60,7 @@
 /**
  * makes a copy only if inPlace is false
  */
-hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in, bool inPlace = true);
+hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in);
 android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out);
 
 NullOr<hidl_vec<uint8_t>> readBlobAsByteArray(const android::Parcel& in, bool inPlace = true);
diff --git a/keystore/keystore_attestation_id.cpp b/keystore/keystore_attestation_id.cpp
index 3d34ac5..b48639f 100644
--- a/keystore/keystore_attestation_id.cpp
+++ b/keystore/keystore_attestation_id.cpp
@@ -17,7 +17,7 @@
 
 #define LOG_TAG "keystore_att_id"
 
-#include <cutils/log.h>
+#include <log/log.h>
 
 #include <memory>
 #include <string>
@@ -47,6 +47,7 @@
 namespace {
 
 constexpr const char* kAttestationSystemPackageName = "AndroidSystem";
+constexpr const char* kUnknownPackageName = "UnknownPackage";
 
 std::vector<uint8_t> signature2SHA256(const content::pm::Signature& sig) {
     std::vector<uint8_t> digest_buffer(SHA256_DIGEST_LENGTH);
@@ -82,6 +83,10 @@
     ASN1_INTEGER* version;
 } KM_ATTESTATION_PACKAGE_INFO;
 
+// Estimated size:
+// 4 bytes for the package name + package_name length
+// 11 bytes for the version (2 bytes header and up to 9 bytes of data).
+constexpr size_t AAID_PKG_INFO_OVERHEAD = 15;
 ASN1_SEQUENCE(KM_ATTESTATION_PACKAGE_INFO) = {
     ASN1_SIMPLE(KM_ATTESTATION_PACKAGE_INFO, package_name, ASN1_OCTET_STRING),
     ASN1_SIMPLE(KM_ATTESTATION_PACKAGE_INFO, version, ASN1_INTEGER),
@@ -90,11 +95,21 @@
 
 DECLARE_STACK_OF(KM_ATTESTATION_PACKAGE_INFO);
 
+// Estimated size:
+// See estimate above for the stack of package infos.
+// 34 (32 + 2) bytes for each signature digest.
+constexpr size_t AAID_SIGNATURE_SIZE = 34;
 typedef struct km_attestation_application_id {
     STACK_OF(KM_ATTESTATION_PACKAGE_INFO) * package_infos;
     STACK_OF(ASN1_OCTET_STRING) * signature_digests;
 } KM_ATTESTATION_APPLICATION_ID;
 
+// Estimated overhead:
+// 4 for the header of the octet string containing the fully-encoded data.
+// 4 for the sequence header.
+// 4 for the header of the package info set.
+// 4 for the header of the signature set.
+constexpr size_t AAID_GENERAL_OVERHEAD = 16;
 ASN1_SEQUENCE(KM_ATTESTATION_APPLICATION_ID) = {
     ASN1_SET_OF(KM_ATTESTATION_APPLICATION_ID, package_infos, KM_ATTESTATION_PACKAGE_INFO),
     ASN1_SET_OF(KM_ATTESTATION_APPLICATION_ID, signature_digests, ASN1_OCTET_STRING),
@@ -165,10 +180,23 @@
     return retval;
 }
 
+/* The following function are not used. They are mentioned here to silence
+ * warnings about them not being used.
+ */
+void unused_functions_silencer() __attribute__((unused));
+void unused_functions_silencer() {
+    i2d_KM_ATTESTATION_PACKAGE_INFO(nullptr, nullptr);
+    d2i_KM_ATTESTATION_APPLICATION_ID(nullptr, nullptr, 0);
+    d2i_KM_ATTESTATION_PACKAGE_INFO(nullptr, nullptr, 0);
+}
+
+}  // namespace
+
 StatusOr<std::vector<uint8_t>>
 build_attestation_application_id(const KeyAttestationApplicationId& key_attestation_id) {
     auto attestation_id =
         std::unique_ptr<KM_ATTESTATION_APPLICATION_ID>(KM_ATTESTATION_APPLICATION_ID_new());
+    size_t estimated_encoded_size = AAID_GENERAL_OVERHEAD;
 
     auto attestation_pinfo_stack = reinterpret_cast<_STACK*>(attestation_id->package_infos);
 
@@ -187,6 +215,10 @@
             ALOGE("Building DER attestation package info failed %d", rc);
             return rc;
         }
+        estimated_encoded_size += AAID_PKG_INFO_OVERHEAD + package_name.size();
+        if (estimated_encoded_size > KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE) {
+            break;
+        }
         if (!sk_push(attestation_pinfo_stack, attestation_package_info.get())) {
             return NO_MEMORY;
         }
@@ -207,6 +239,10 @@
 
     auto signature_digest_stack = reinterpret_cast<_STACK*>(attestation_id->signature_digests);
     for (auto si : signature_digests) {
+        estimated_encoded_size += AAID_SIGNATURE_SIZE;
+        if (estimated_encoded_size > KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE) {
+            break;
+        }
         auto asn1_item = std::unique_ptr<ASN1_OCTET_STRING>(ASN1_OCTET_STRING_new());
         if (!asn1_item) return NO_MEMORY;
         if (!ASN1_OCTET_STRING_set(asn1_item.get(), si.data(), si.size())) {
@@ -229,18 +265,6 @@
     return result;
 }
 
-/* The following function are not used. They are mentioned here to silence
- * warnings about them not being used.
- */
-void unused_functions_silencer() __attribute__((unused));
-void unused_functions_silencer() {
-    i2d_KM_ATTESTATION_PACKAGE_INFO(nullptr, nullptr);
-    d2i_KM_ATTESTATION_APPLICATION_ID(nullptr, nullptr, 0);
-    d2i_KM_ATTESTATION_PACKAGE_INFO(nullptr, nullptr, 0);
-}
-
-}  // namespace
-
 StatusOr<std::vector<uint8_t>> gather_attestation_application_id(uid_t uid) {
     KeyAttestationApplicationId key_attestation_id;
 
@@ -254,10 +278,15 @@
         /* Get the attestation application ID from package manager */
         auto& pm = KeyAttestationApplicationIdProvider::get();
         auto status = pm.getKeyAttestationApplicationId(uid, &key_attestation_id);
+        // Package Manager call has failed, perform attestation but indicate that the
+        // caller is unknown.
         if (!status.isOk()) {
-            ALOGE("package manager request for key attestation ID failed with: %s %d",
+            ALOGW("package manager request for key attestation ID failed with: %s %d",
                   status.exceptionMessage().string(), status.exceptionCode());
-            return FAILED_TRANSACTION;
+            auto pinfo = std::make_unique<KeyAttestationPackageInfo>(
+                String16(kUnknownPackageName), 1 /* version code */,
+                std::make_shared<KeyAttestationPackageInfo::SignaturesVector>());
+            key_attestation_id = KeyAttestationApplicationId(std::move(pinfo));
         }
     }
 
diff --git a/keystore/keystore_attestation_id.h b/keystore/keystore_attestation_id.h
index 8d20550..63015ee 100644
--- a/keystore/keystore_attestation_id.h
+++ b/keystore/keystore_attestation_id.h
@@ -23,14 +23,28 @@
 namespace android {
 namespace security {
 
+constexpr size_t KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE = 1024;
+
+namespace keymaster {
+
+class KeyAttestationApplicationId;
+
+}  // namespace keymaster
+
 template <typename T> class StatusOr {
   public:
+    // NOLINTNEXTLINE(google-explicit-constructor)
     StatusOr(const status_t error) : _status(error), _value() {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
     StatusOr(const T& value) : _status(NO_ERROR), _value(value) {}
+    // NOLINTNEXTLINE(google-explicit-constructor)
     StatusOr(T&& value) : _status(NO_ERROR), _value(value) {}
 
+    // NOLINTNEXTLINE(google-explicit-constructor)
     operator const T&() const { return _value; }
+    // NOLINTNEXTLINE(google-explicit-constructor)
     operator T&() { return _value; }
+    // NOLINTNEXTLINE(google-explicit-constructor)
     operator T &&() && { return std::move(_value); }
 
     bool isOk() const { return NO_ERROR == _status; }
@@ -57,6 +71,14 @@
  */
 StatusOr<std::vector<uint8_t>> gather_attestation_application_id(uid_t uid);
 
+/**
+ * Generates a DER-encoded vector containing information from KeyAttestationApplicationId.
+ * The size of the returned vector will not exceed KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE.
+ */
+
+StatusOr<std::vector<uint8_t>> build_attestation_application_id(
+    const ::android::security::keymaster::KeyAttestationApplicationId& key_attestation_id);
+
 }  // namespace security
 }  // namespace android
 #endif  // KEYSTORE_KEYSTORE_ATTESTATION_ID_H_
diff --git a/keystore/keystore_cli.cpp b/keystore/keystore_cli.cpp
index 1e100fc..2705a19 100644
--- a/keystore/keystore_cli.cpp
+++ b/keystore/keystore_cli.cpp
@@ -20,7 +20,7 @@
 #include <sys/types.h>
 #include <vector>
 
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
@@ -28,10 +28,10 @@
 
 using namespace android;
 using namespace keystore;
-using android::security::IKeystoreService;
+using android::security::keystore::IKeystoreService;
 
 static const char* responses[] = {
-    NULL,
+    nullptr,
     /* [NO_ERROR]           = */ "No error",
     /* [LOCKED]             = */ "Locked",
     /* [UNINITIALIZED]      = */ "Uninitialized",
@@ -218,7 +218,7 @@
     sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
     sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
 
-    if (service == NULL) {
+    if (service == nullptr) {
         fprintf(stderr, "%s: error: could not connect to keystore service\n", argv[0]);
         return 1;
     }
@@ -254,8 +254,6 @@
 
     // TODO: generate
 
-    SINGLE_ARG_DATA_RETURN(get_pubkey);
-
     // TODO: grant
 
     // TODO: ungrant
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index 6377ec1..b46b221 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -12,7 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include <chrono>
 #include <cstdio>
+#include <future>
 #include <memory>
 #include <string>
 #include <vector>
@@ -29,7 +31,7 @@
 
 #include <android/hardware/confirmationui/1.0/types.h>
 #include <android/security/BnConfirmationPromptCallback.h>
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
 
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -41,7 +43,7 @@
 
 using android::sp;
 using android::String16;
-using android::security::IKeystoreService;
+using android::security::keystore::IKeystoreService;
 using base::CommandLine;
 using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
 
@@ -66,6 +68,7 @@
            "          delete-all\n"
            "          exists --name=<key_name>\n"
            "          list [--prefix=<key_name_prefix>]\n"
+           "          list-apps-with-keys\n"
            "          sign-verify --name=<key_name>\n"
            "          [en|de]crypt --name=<key_name> --in=<file> --out=<file>\n"
            "                       [--seclevel=software|strongbox|tee(default)]\n"
@@ -144,7 +147,7 @@
     if (!sha256_only) {
         parameters.Digest(Digest::SHA_2_224).Digest(Digest::SHA_2_384).Digest(Digest::SHA_2_512);
     }
-    return parameters;
+    return std::move(parameters);
 }
 
 AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
@@ -153,7 +156,7 @@
         .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
         .Padding(PaddingMode::RSA_OAEP)
         .Authorization(TAG_NO_AUTH_REQUIRED);
-    return parameters;
+    return std::move(parameters);
 }
 
 AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) {
@@ -164,7 +167,7 @@
     if (!sha256_only) {
         parameters.Digest(Digest::SHA_2_224).Digest(Digest::SHA_2_384).Digest(Digest::SHA_2_512);
     }
-    return parameters;
+    return std::move(parameters);
 }
 
 AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
@@ -179,7 +182,7 @@
         parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CTR);
         parameters.Padding(PaddingMode::NONE);
     }
-    return parameters;
+    return std::move(parameters);
 }
 
 AuthorizationSet GetHMACParameters(uint32_t key_size, Digest digest) {
@@ -188,7 +191,7 @@
         .Digest(digest)
         .Authorization(TAG_MIN_MAC_LENGTH, 224)
         .Authorization(TAG_NO_AUTH_REQUIRED);
-    return parameters;
+    return std::move(parameters);
 }
 
 std::vector<TestCase> GetTestCases() {
@@ -280,12 +283,13 @@
 
 int AddEntropy(const std::string& input, int32_t flags) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    int32_t result = keystore->addRandomNumberGeneratorEntropy(input, flags);
+    int32_t result = keystore->addRandomNumberGeneratorEntropy(input, flags).getErrorCode();
     printf("AddEntropy: %d\n", result);
     return result;
 }
 
-int GenerateKey(const std::string& name, int32_t flags) {
+// Note: auth_bound keys created with this tool will not be usable.
+int GenerateKey(const std::string& name, int32_t flags, bool auth_bound) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSetBuilder params;
     params.RsaSigningKey(2048, 65537)
@@ -294,18 +298,24 @@
         .Digest(Digest::SHA_2_384)
         .Digest(Digest::SHA_2_512)
         .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
-        .Padding(PaddingMode::RSA_PSS)
-        .Authorization(TAG_NO_AUTH_REQUIRED);
+        .Padding(PaddingMode::RSA_PSS);
+    if (auth_bound) {
+        // Gatekeeper normally generates the secure user id.
+        // Using zero allows the key to be created, but it will not be usuable.
+        params.Authorization(TAG_USER_SECURE_ID, 0);
+    } else {
+        params.Authorization(TAG_NO_AUTH_REQUIRED);
+    }
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
     auto result = keystore->generateKey(name, params, flags, &hardware_enforced_characteristics,
                                         &software_enforced_characteristics);
-    printf("GenerateKey: %d\n", int32_t(result));
+    printf("GenerateKey: %d\n", result.getErrorCode());
     if (result.isOk()) {
         PrintKeyCharacteristics(hardware_enforced_characteristics,
                                 software_enforced_characteristics);
     }
-    return result;
+    return result.getErrorCode();
 }
 
 int GetCharacteristics(const std::string& name) {
@@ -314,32 +324,32 @@
     AuthorizationSet software_enforced_characteristics;
     auto result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics,
                                                   &software_enforced_characteristics);
-    printf("GetCharacteristics: %d\n", int32_t(result));
+    printf("GetCharacteristics: %d\n", result.getErrorCode());
     if (result.isOk()) {
         PrintKeyCharacteristics(hardware_enforced_characteristics,
                                 software_enforced_characteristics);
     }
-    return result;
+    return result.getErrorCode();
 }
 
 int ExportKey(const std::string& name) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     std::string data;
-    int32_t result = keystore->exportKey(KeyFormat::X509, name, &data);
+    int32_t result = keystore->exportKey(KeyFormat::X509, name, &data).getErrorCode();
     printf("ExportKey: %d (%zu)\n", result, data.size());
     return result;
 }
 
 int DeleteKey(const std::string& name) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    int32_t result = keystore->deleteKey(name);
+    int32_t result = keystore->deleteKey(name).getErrorCode();
     printf("DeleteKey: %d\n", result);
     return result;
 }
 
 int DeleteAllKeys() {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    int32_t result = keystore->deleteAllKeys();
+    int32_t result = keystore->deleteAllKeys().getErrorCode();
     printf("DeleteAllKeys: %d\n", result);
     return result;
 }
@@ -364,6 +374,34 @@
     return 0;
 }
 
+int ListAppsWithKeys() {
+
+    sp<android::IServiceManager> sm = android::defaultServiceManager();
+    sp<android::IBinder> binder = sm->getService(String16("android.security.keystore"));
+    sp<IKeystoreService> service = android::interface_cast<IKeystoreService>(binder);
+    if (service == nullptr) {
+        fprintf(stderr, "Error connecting to keystore service.\n");
+        return 1;
+    }
+    int32_t aidl_return;
+    ::std::vector<::std::string> uids;
+    android::binder::Status status = service->listUidsOfAuthBoundKeys(&uids, &aidl_return);
+    if (!status.isOk()) {
+        fprintf(stderr, "Requesting uids of auth bound keys failed with error %s.\n",
+                status.toString8().c_str());
+        return 1;
+    }
+    if (!KeyStoreNativeReturnCode(aidl_return).isOk()) {
+        fprintf(stderr, "Requesting uids of auth bound keys failed with code %d.\n", aidl_return);
+        return 1;
+    }
+    printf("Apps with auth bound keys:\n");
+    for (auto i = uids.begin(); i != uids.end(); ++i) {
+        printf("%s\n", i->c_str());
+    }
+    return 0;
+}
+
 int SignAndVerify(const std::string& name) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSetBuilder sign_params;
@@ -374,8 +412,8 @@
     auto result =
         keystore->beginOperation(KeyPurpose::SIGN, name, sign_params, &output_params, &handle);
     if (!result.isOk()) {
-        printf("Sign: BeginOperation failed: %d\n", int32_t(result));
-        return result;
+        printf("Sign: BeginOperation failed: %d\n", result.getErrorCode());
+        return result.getErrorCode();
     }
     AuthorizationSet empty_params;
     size_t num_input_bytes_consumed;
@@ -383,14 +421,14 @@
     result = keystore->updateOperation(handle, empty_params, "data_to_sign",
                                        &num_input_bytes_consumed, &output_params, &output_data);
     if (!result.isOk()) {
-        printf("Sign: UpdateOperation failed: %d\n", int32_t(result));
-        return result;
+        printf("Sign: UpdateOperation failed: %d\n", result.getErrorCode());
+        return result.getErrorCode();
     }
     result = keystore->finishOperation(handle, empty_params, std::string() /*signature_to_verify*/,
                                        &output_params, &output_data);
     if (!result.isOk()) {
-        printf("Sign: FinishOperation failed: %d\n", int32_t(result));
-        return result;
+        printf("Sign: FinishOperation failed: %d\n", result.getErrorCode());
+        return result.getErrorCode();
     }
     printf("Sign: %zu bytes.\n", output_data.size());
     // We have a signature, now verify it.
@@ -399,24 +437,24 @@
     result =
         keystore->beginOperation(KeyPurpose::VERIFY, name, sign_params, &output_params, &handle);
     if (!result.isOk()) {
-        printf("Verify: BeginOperation failed: %d\n", int32_t(result));
-        return result;
+        printf("Verify: BeginOperation failed: %d\n", result.getErrorCode());
+        return result.getErrorCode();
     }
     result = keystore->updateOperation(handle, empty_params, "data_to_sign",
                                        &num_input_bytes_consumed, &output_params, &output_data);
     if (!result.isOk()) {
-        printf("Verify: UpdateOperation failed: %d\n", int32_t(result));
-        return result;
+        printf("Verify: UpdateOperation failed: %d\n", result.getErrorCode());
+        return result.getErrorCode();
     }
     result = keystore->finishOperation(handle, empty_params, signature_to_verify, &output_params,
                                        &output_data);
     if (result == ErrorCode::VERIFICATION_FAILED) {
         printf("Verify: Failed to verify signature.\n");
-        return result;
+        return result.getErrorCode();
     }
     if (!result.isOk()) {
-        printf("Verify: FinishOperation failed: %d\n", int32_t(result));
-        return result;
+        printf("Verify: FinishOperation failed: %d\n", result.getErrorCode());
+        return result.getErrorCode();
     }
     printf("Verify: OK\n");
     return 0;
@@ -460,33 +498,17 @@
     return KEYSTORE_FLAG_NONE;
 }
 
-class ConfirmationListener : public android::security::BnConfirmationPromptCallback {
+class ConfirmationListener
+    : public android::security::BnConfirmationPromptCallback,
+      public std::promise<std::tuple<ConfirmationResponseCode, std::vector<uint8_t>>> {
   public:
     ConfirmationListener() {}
 
     virtual ::android::binder::Status
     onConfirmationPromptCompleted(int32_t result,
                                   const ::std::vector<uint8_t>& dataThatWasConfirmed) override {
-        ConfirmationResponseCode responseCode = static_cast<ConfirmationResponseCode>(result);
-        printf("Confirmation prompt completed\n"
-               "responseCode = %d\n",
-               responseCode);
-        printf("dataThatWasConfirmed[%zd] = {", dataThatWasConfirmed.size());
-        size_t newLineCountDown = 16;
-        bool hasPrinted = false;
-        for (uint8_t element : dataThatWasConfirmed) {
-            if (hasPrinted) {
-                printf(", ");
-            }
-            if (newLineCountDown == 0) {
-                printf("\n  ");
-                newLineCountDown = 32;
-            }
-            printf("0x%02x", element);
-            hasPrinted = true;
-        }
-        printf("}\n");
-        exit(0);
+        this->set_value({static_cast<ConfirmationResponseCode>(result), dataThatWasConfirmed});
+        return ::android::binder::Status::ok();
     }
 };
 
@@ -496,7 +518,7 @@
     sp<android::IServiceManager> sm = android::defaultServiceManager();
     sp<android::IBinder> binder = sm->getService(String16("android.security.keystore"));
     sp<IKeystoreService> service = android::interface_cast<IKeystoreService>(binder);
-    if (service == NULL) {
+    if (service == nullptr) {
         printf("error: could not connect to keystore service.\n");
         return 1;
     }
@@ -536,6 +558,7 @@
 
     sp<ConfirmationListener> listener = new ConfirmationListener();
 
+    auto future = listener->get_future();
     int32_t aidl_return;
     android::binder::Status status = service->presentConfirmationPrompt(
         listener, promptText16, extraData, locale16, uiOptionsAsFlags, &aidl_return);
@@ -549,26 +572,53 @@
         printf("Presenting confirmation prompt failed with response code %d.\n", responseCode);
         return 1;
     }
+    printf("Waiting for prompt to complete - use Ctrl+C to abort...\n");
 
     if (cancelAfterValue > 0.0) {
         printf("Sleeping %.1f seconds before canceling prompt...\n", cancelAfterValue);
-        base::PlatformThread::Sleep(base::TimeDelta::FromSecondsD(cancelAfterValue));
-        status = service->cancelConfirmationPrompt(listener, &aidl_return);
-        if (!status.isOk()) {
-            printf("Canceling confirmation prompt failed with binder status '%s'.\n",
-                   status.toString8().c_str());
-            return 1;
-        }
-        responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
-        if (responseCode != ConfirmationResponseCode::OK) {
-            printf("Canceling confirmation prompt failed with response code %d.\n", responseCode);
-            return 1;
+        auto fstatus =
+            future.wait_for(std::chrono::milliseconds(uint64_t(cancelAfterValue * 1000)));
+        if (fstatus == std::future_status::timeout) {
+            status = service->cancelConfirmationPrompt(listener, &aidl_return);
+            if (!status.isOk()) {
+                printf("Canceling confirmation prompt failed with binder status '%s'.\n",
+                       status.toString8().c_str());
+                return 1;
+            }
+            responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
+            if (responseCode == ConfirmationResponseCode::Ignored) {
+                // The confirmation was completed by the user so take the response
+            } else if (responseCode != ConfirmationResponseCode::OK) {
+                printf("Canceling confirmation prompt failed with response code %d.\n",
+                       responseCode);
+                return 1;
+            }
         }
     }
 
-    printf("Waiting for prompt to complete - use Ctrl+C to abort...\n");
-    // Use the main thread to process Binder transactions.
-    android::IPCThreadState::self()->joinThreadPool();
+    future.wait();
+
+    auto [rc, dataThatWasConfirmed] = future.get();
+
+    printf("Confirmation prompt completed\n"
+           "responseCode = %d\n",
+           rc);
+    printf("dataThatWasConfirmed[%zd] = {", dataThatWasConfirmed.size());
+    size_t newLineCountDown = 16;
+    bool hasPrinted = false;
+    for (uint8_t element : dataThatWasConfirmed) {
+        if (hasPrinted) {
+            printf(", ");
+        }
+        if (newLineCountDown == 0) {
+            printf("\n  ");
+            newLineCountDown = 32;
+        }
+        printf("0x%02x", element);
+        hasPrinted = true;
+    }
+    printf("}\n");
+
     return 0;
 }
 
@@ -578,6 +628,9 @@
     CommandLine::Init(argc, argv);
     CommandLine* command_line = CommandLine::ForCurrentProcess();
     CommandLine::StringVector args = command_line->GetArgs();
+
+    android::ProcessState::self()->startThreadPool();
+
     if (args.empty()) {
         PrintUsageAndExit();
     }
@@ -591,7 +644,8 @@
                           securityLevelOption2Flags(*command_line));
     } else if (args[0] == "generate") {
         return GenerateKey(command_line->GetSwitchValueASCII("name"),
-                           securityLevelOption2Flags(*command_line));
+                           securityLevelOption2Flags(*command_line),
+                           command_line->HasSwitch("auth_bound"));
     } else if (args[0] == "get-chars") {
         return GetCharacteristics(command_line->GetSwitchValueASCII("name"));
     } else if (args[0] == "export") {
@@ -604,6 +658,8 @@
         return DoesKeyExist(command_line->GetSwitchValueASCII("name"));
     } else if (args[0] == "list") {
         return List(command_line->GetSwitchValueASCII("prefix"));
+    } else if (args[0] == "list-apps-with-keys") {
+        return ListAppsWithKeys();
     } else if (args[0] == "sign-verify") {
         return SignAndVerify(command_line->GetSwitchValueASCII("name"));
     } else if (args[0] == "encrypt") {
diff --git a/keystore/keystore_client_impl.cpp b/keystore/keystore_client_impl.cpp
index 994e3f2..b9a142e 100644
--- a/keystore/keystore_client_impl.cpp
+++ b/keystore/keystore_client_impl.cpp
@@ -16,10 +16,11 @@
 
 #include "keystore/keystore_client_impl.h"
 
+#include <future>
 #include <string>
 #include <vector>
 
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
 #include <binder/IBinder.h>
 #include <binder/IInterface.h>
 #include <binder/IServiceManager.h>
@@ -30,6 +31,7 @@
 
 #include <keystore/keymaster_types.h>
 #include <keystore/keystore_hidl_support.h>
+#include <keystore/keystore_promises.h>
 
 #include "keystore_client.pb.h"
 
@@ -46,6 +48,7 @@
 using android::String16;
 using android::security::keymaster::ExportResult;
 using android::security::keymaster::OperationResult;
+using android::security::keystore::KeystoreResponse;
 using keystore::AuthorizationSet;
 using keystore::AuthorizationSetBuilder;
 using keystore::KeyCharacteristics;
@@ -57,7 +60,8 @@
 KeystoreClientImpl::KeystoreClientImpl() {
     service_manager_ = android::defaultServiceManager();
     keystore_binder_ = service_manager_->getService(String16("android.security.keystore"));
-    keystore_ = android::interface_cast<android::security::IKeystoreService>(keystore_binder_);
+    keystore_ =
+        android::interface_cast<android::security::keystore::IKeystoreService>(keystore_binder_);
 }
 
 bool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name,
@@ -157,7 +161,7 @@
     uint64_t handle;
     auto result = beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
     if (!result.isOk()) {
-        ALOGE("BeginOperation failed: %d", int32_t(result));
+        ALOGE("BeginOperation failed: %d", result.getErrorCode());
         return false;
     }
     AuthorizationSet empty_params;
@@ -166,13 +170,13 @@
     result = updateOperation(handle, empty_params, input_data, &num_input_bytes_consumed,
                              &ignored_params, output_data);
     if (!result.isOk()) {
-        ALOGE("UpdateOperation failed: %d", int32_t(result));
+        ALOGE("UpdateOperation failed: %d", result.getErrorCode());
         return false;
     }
     result =
         finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data);
     if (!result.isOk()) {
-        ALOGE("FinishOperation failed: %d", int32_t(result));
+        ALOGE("FinishOperation failed: %d", result.getErrorCode());
         return false;
     }
     return true;
@@ -180,10 +184,21 @@
 
 KeyStoreNativeReturnCode
 KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy, int32_t flags) {
-    int32_t result;
-    auto binder_result = keystore_->addRngEntropy(blob2hidlVec(entropy), flags, &result);
+    int32_t error_code;
+
+    android::sp<KeystoreResponsePromise> promise(new KeystoreResponsePromise());
+    auto future = promise->get_future();
+
+    auto binder_result =
+        keystore_->addRngEntropy(promise, blob2hidlVec(entropy), flags, &error_code);
     if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    return KeyStoreNativeReturnCode(result);
+
+    KeyStoreNativeReturnCode rc(error_code);
+    if (!rc.isOk()) return rc;
+
+    auto result = future.get();
+
+    return KeyStoreNativeReturnCode(result.response_code());
 }
 
 KeyStoreNativeReturnCode
@@ -191,19 +206,26 @@
                                 int32_t flags, AuthorizationSet* hardware_enforced_characteristics,
                                 AuthorizationSet* software_enforced_characteristics) {
     String16 key_name16(key_name.data(), key_name.size());
-    ::android::security::keymaster::KeyCharacteristics characteristics;
-    int32_t result;
+    int32_t error_code;
+    android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
+    auto future = promise->get_future();
     auto binder_result = keystore_->generateKey(
-        key_name16, ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
-        hidl_vec<uint8_t>() /* entropy */, kDefaultUID, flags, &characteristics, &result);
+        promise, key_name16,
+        ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
+        hidl_vec<uint8_t>() /* entropy */, kDefaultUID, flags, &error_code);
     if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
 
+    KeyStoreNativeReturnCode rc(error_code);
+    if (!rc.isOk()) return rc;
+
+    auto [km_response, characteristics] = future.get();
+
     /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
      * There are no references to Parcel memory after that, and ownership of the newly acquired
      * memory is with the AuthorizationSet objects. */
     *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
     *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
-    return KeyStoreNativeReturnCode(result);
+    return KeyStoreNativeReturnCode(km_response.response_code());
 }
 
 KeyStoreNativeReturnCode
@@ -211,18 +233,25 @@
                                           AuthorizationSet* hardware_enforced_characteristics,
                                           AuthorizationSet* software_enforced_characteristics) {
     String16 key_name16(key_name.data(), key_name.size());
-    ::android::security::keymaster::KeyCharacteristics characteristics;
-    int32_t result;
+    int32_t error_code;
+    android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
+    auto future = promise->get_future();
     auto binder_result = keystore_->getKeyCharacteristics(
-        key_name16, android::security::keymaster::KeymasterBlob(),
-        android::security::keymaster::KeymasterBlob(), kDefaultUID, &characteristics, &result);
+        promise, key_name16, android::security::keymaster::KeymasterBlob(),
+        android::security::keymaster::KeymasterBlob(), kDefaultUID, &error_code);
+    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+
+    KeyStoreNativeReturnCode rc(error_code);
+    if (!rc.isOk()) return rc;
+
+    auto [km_response, characteristics] = future.get();
 
     /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
      * There are no references to Parcel memory after that, and ownership of the newly acquired
      * memory is with the AuthorizationSet objects. */
     *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
     *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
-    return KeyStoreNativeReturnCode(result);
+    return KeyStoreNativeReturnCode(km_response.response_code());
 }
 
 KeyStoreNativeReturnCode
@@ -232,29 +261,48 @@
                               AuthorizationSet* software_enforced_characteristics) {
     String16 key_name16(key_name.data(), key_name.size());
     auto hidlKeyData = blob2hidlVec(key_data);
-    ::android::security::keymaster::KeyCharacteristics characteristics;
-    int32_t result;
+    int32_t error_code;
+    android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
+    auto future = promise->get_future();
     auto binder_result = keystore_->importKey(
-        key_name16, ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
-        (int)key_format, hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics, &result);
+        promise, key_name16,
+        ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
+        (int)key_format, hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &error_code);
+    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+
+    KeyStoreNativeReturnCode rc(error_code);
+    if (!rc.isOk()) return rc;
+
+    auto [km_response, characteristics] = future.get();
+
     /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
      * There are no references to Parcel memory after that, and ownership of the newly acquired
      * memory is with the AuthorizationSet objects. */
     *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
     *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
-    return KeyStoreNativeReturnCode(result);
+    return KeyStoreNativeReturnCode(km_response.response_code());
 }
 
 KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
                                                        const std::string& key_name,
                                                        std::string* export_data) {
     String16 key_name16(key_name.data(), key_name.size());
-    ExportResult export_result;
+    int32_t error_code;
+    android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise);
+    auto future = promise->get_future();
     auto binder_result = keystore_->exportKey(
-        key_name16, (int)export_format, android::security::keymaster::KeymasterBlob(),
-        android::security::keymaster::KeymasterBlob(), kDefaultUID, &export_result);
+        promise, key_name16, (int)export_format, android::security::keymaster::KeymasterBlob(),
+        android::security::keymaster::KeymasterBlob(), kDefaultUID, &error_code);
     if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+
+    KeyStoreNativeReturnCode rc(error_code);
+    if (!rc.isOk()) return rc;
+
+    auto export_result = future.get();
+    if (!export_result.resultCode.isOk()) return export_result.resultCode;
+
     *export_data = hidlVec2String(export_result.exportData);
+
     return export_result.resultCode;
 }
 
@@ -279,12 +327,18 @@
                                    AuthorizationSet* output_parameters, uint64_t* handle) {
     android::sp<android::IBinder> token(new android::BBinder);
     String16 key_name16(key_name.data(), key_name.size());
-    OperationResult result;
+    int32_t error_code;
+    android::sp<OperationResultPromise> promise(new OperationResultPromise{});
+    auto future = promise->get_future();
     auto binder_result = keystore_->begin(
-        token, key_name16, (int)purpose, true /*pruneable*/,
+        promise, token, key_name16, (int)purpose, true /*pruneable*/,
         android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
-        hidl_vec<uint8_t>() /* entropy */, kDefaultUID, &result);
+        hidl_vec<uint8_t>() /* entropy */, kDefaultUID, &error_code);
     if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+    KeyStoreNativeReturnCode rc(error_code);
+    if (!rc.isOk()) return rc;
+
+    OperationResult result = future.get();
     if (result.resultCode.isOk()) {
         *handle = getNextVirtualHandle();
         active_operations_[*handle] = result.token;
@@ -302,13 +356,19 @@
     if (active_operations_.count(handle) == 0) {
         return ErrorCode::INVALID_OPERATION_HANDLE;
     }
-    OperationResult result;
     auto hidlInputData = blob2hidlVec(input_data);
+    int32_t error_code;
+    android::sp<OperationResultPromise> promise(new OperationResultPromise{});
+    auto future = promise->get_future();
     auto binder_result = keystore_->update(
-        active_operations_[handle],
+        promise, active_operations_[handle],
         android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
-        hidlInputData, &result);
+        hidlInputData, &error_code);
     if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+    KeyStoreNativeReturnCode rc(error_code);
+    if (!rc.isOk()) return rc;
+
+    OperationResult result = future.get();
 
     if (result.resultCode.isOk()) {
         *num_input_bytes_consumed = result.inputConsumed;
@@ -328,14 +388,19 @@
     if (active_operations_.count(handle) == 0) {
         return ErrorCode::INVALID_OPERATION_HANDLE;
     }
-    OperationResult result;
+    int32_t error_code;
     auto hidlSignature = blob2hidlVec(signature_to_verify);
+    android::sp<OperationResultPromise> promise(new OperationResultPromise{});
+    auto future = promise->get_future();
     auto binder_result = keystore_->finish(
-        active_operations_[handle],
+        promise, active_operations_[handle],
         android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
-        (std::vector<uint8_t>)hidlSignature, hidl_vec<uint8_t>(), &result);
+        (std::vector<uint8_t>)hidlSignature, hidl_vec<uint8_t>(), &error_code);
     if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+    KeyStoreNativeReturnCode rc(error_code);
+    if (!rc.isOk()) return rc;
 
+    OperationResult result = future.get();
     if (result.resultCode.isOk()) {
         if (result.outParams.size()) {
             *output_parameters = result.outParams;
@@ -352,13 +417,18 @@
         return ErrorCode::INVALID_OPERATION_HANDLE;
     }
     int32_t result;
+    android::sp<KeystoreResponsePromise> promise(new KeystoreResponsePromise{});
+    auto future = promise->get_future();
     // Current implementation does not return exceptions in android::binder::Status
-    auto binder_result = keystore_->abort(active_operations_[handle], &result);
+    auto binder_result = keystore_->abort(promise, active_operations_[handle], &result);
     if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    if (KeyStoreNativeReturnCode(result).isOk()) {
+    KeyStoreNativeReturnCode rc(result);
+    if (!rc.isOk()) return rc;
+    rc = KeyStoreNativeReturnCode(future.get().response_code());
+    if (rc.isOk()) {
         active_operations_.erase(handle);
     }
-    return KeyStoreNativeReturnCode(result);
+    return rc;
 }
 
 bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
@@ -397,7 +467,7 @@
         if (!verified) {
             auto result = deleteKey(key_name);
             if (!result.isOk()) {
-                ALOGE("Failed to delete invalid encryption key: %d", int32_t(result));
+                ALOGE("Failed to delete invalid encryption key: %d", result.getErrorCode());
                 return false;
             }
             key_exists = false;
@@ -415,7 +485,7 @@
             generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
                         &software_enforced_characteristics);
         if (!result.isOk()) {
-            ALOGE("Failed to generate encryption key: %d", int32_t(result));
+            ALOGE("Failed to generate encryption key: %d", result.getErrorCode());
             return false;
         }
         if (hardware_enforced_characteristics.size() == 0) {
@@ -436,7 +506,7 @@
         if (!verified) {
             auto result = deleteKey(key_name);
             if (!result.isOk()) {
-                ALOGE("Failed to delete invalid authentication key: %d", int32_t(result));
+                ALOGE("Failed to delete invalid authentication key: %d", result.getErrorCode());
                 return false;
             }
             key_exists = false;
@@ -454,7 +524,7 @@
             generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
                         &software_enforced_characteristics);
         if (!result.isOk()) {
-            ALOGE("Failed to generate authentication key: %d", int32_t(result));
+            ALOGE("Failed to generate authentication key: %d", result.getErrorCode());
             return false;
         }
         if (hardware_enforced_characteristics.size() == 0) {
@@ -471,7 +541,7 @@
     auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
                                         &software_enforced_characteristics);
     if (!result.isOk()) {
-        ALOGE("Failed to query encryption key: %d", int32_t(result));
+        ALOGE("Failed to query encryption key: %d", result.getErrorCode());
         return false;
     }
     *verified = true;
@@ -512,7 +582,7 @@
     auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
                                         &software_enforced_characteristics);
     if (!result.isOk()) {
-        ALOGE("Failed to query authentication key: %d", int32_t(result));
+        ALOGE("Failed to query authentication key: %d", result.getErrorCode());
         return false;
     }
     *verified = true;
diff --git a/keystore/keystore_get.cpp b/keystore/keystore_get.cpp
index cf67fa4..a6f8755 100644
--- a/keystore/keystore_get.cpp
+++ b/keystore/keystore_get.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
 #include <binder/IServiceManager.h>
 
 #include <keystore/keystore_get.h>
@@ -26,10 +26,10 @@
 ssize_t keystore_get(const char* key, size_t keyLength, uint8_t** value) {
     sp<IServiceManager> sm = defaultServiceManager();
     sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<android::security::IKeystoreService> service =
-        interface_cast<android::security::IKeystoreService>(binder);
+    sp<android::security::keystore::IKeystoreService> service =
+        interface_cast<android::security::keystore::IKeystoreService>(binder);
 
-    if (service == NULL) {
+    if (service == nullptr) {
         return -1;
     }
 
diff --git a/keystore/keystore_get_wifi_hidl.cpp b/keystore/keystore_get_wifi_hidl.cpp
index 79639b6..155201f 100644
--- a/keystore/keystore_get_wifi_hidl.cpp
+++ b/keystore/keystore_get_wifi_hidl.cpp
@@ -34,13 +34,13 @@
 using android::system::wifi::keystore::V1_0::IKeystore;
 
 ssize_t keystore_get(const char *key, size_t keyLength, uint8_t** value) {
-    if (key == NULL || keyLength == 0 || value == NULL) {
+    if (key == nullptr || keyLength == 0 || value == nullptr) {
         ALOGE("Null pointer argument passed");
         return -1;
     }
 
     sp<IKeystore> service = IKeystore::tryGetService();
-    if (service == NULL) {
+    if (service == nullptr) {
         ALOGE("could not contact keystore HAL");
         return -1;
     }
diff --git a/keystore/keystore_keymaster_enforcement.h b/keystore/keystore_keymaster_enforcement.h
index e114ea9..e7515a1 100644
--- a/keystore/keystore_keymaster_enforcement.h
+++ b/keystore/keystore_keymaster_enforcement.h
@@ -39,7 +39,7 @@
     }
 
     bool activation_date_valid(uint64_t activation_date) const override {
-        time_t now = time(NULL);
+        time_t now = time(nullptr);
         if (now == static_cast<time_t>(-1)) {
             // Failed to obtain current time -- fail safe: activation_date hasn't yet occurred.
             return false;
@@ -57,7 +57,7 @@
     }
 
     bool expiration_date_passed(uint64_t expiration_date) const override {
-        time_t now = time(NULL);
+        time_t now = time(nullptr);
         if (now == static_cast<time_t>(-1)) {
             // Failed to obtain current time -- fail safe: expiration_date has passed.
             return true;
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
index 52e83c8..70f38cc 100644
--- a/keystore/keystore_main.cpp
+++ b/keystore/keystore_main.cpp
@@ -18,7 +18,7 @@
 
 #include <android-base/logging.h>
 #include <android/hidl/manager/1.1/IServiceManager.h>
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
 #include <android/system/wifi/keystore/1.0/IKeystore.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -151,10 +151,11 @@
     SecurityLevel minimalAllowedSecurityLevelForNewKeys =
         halVersion.majorVersion >= 2 ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE;
 
-    keystore::KeyStore keyStore(kmDevices, minimalAllowedSecurityLevelForNewKeys);
-    keyStore.initialize();
+    android::sp<keystore::KeyStore> keyStore(
+        new keystore::KeyStore(kmDevices, minimalAllowedSecurityLevelForNewKeys));
+    keyStore->initialize();
     android::sp<android::IServiceManager> sm = android::defaultServiceManager();
-    android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(&keyStore);
+    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/keystore_utils.cpp b/keystore/keystore_utils.cpp
index e5ae29a..78056d6 100644
--- a/keystore/keystore_utils.cpp
+++ b/keystore/keystore_utils.cpp
@@ -22,7 +22,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
@@ -107,8 +107,7 @@
 namespace keystore {
 
 hidl_vec<uint8_t> blob2hidlVec(const Blob& blob) {
-    hidl_vec<uint8_t> result;
-    result.setToExternal(const_cast<uint8_t*>(blob.getValue()), blob.getLength());
+    hidl_vec<uint8_t> result(blob.getValue(), blob.getValue() + blob.getLength());
     return result;
 }
 
diff --git a/keystore/legacy_keymaster_device_wrapper.cpp b/keystore/legacy_keymaster_device_wrapper.cpp
index 187252e..86d286e 100644
--- a/keystore/legacy_keymaster_device_wrapper.cpp
+++ b/keystore/legacy_keymaster_device_wrapper.cpp
@@ -19,7 +19,7 @@
 
 #include "legacy_keymaster_device_wrapper.h"
 
-#include <cutils/log.h>
+#include <log/log.h>
 
 #include <hardware/keymaster2.h>
 #include <hardware/keymaster_defs.h>
@@ -66,7 +66,7 @@
 
 class KmParamSet : public keymaster_key_param_set_t {
   public:
-    KmParamSet(const hidl_vec<KeyParameter>& keyParams) {
+    explicit KmParamSet(const hidl_vec<KeyParameter>& keyParams) {
         params = new keymaster_key_param_t[keyParams.size()];
         length = keyParams.size();
         for (size_t i = 0; i < keyParams.size(); ++i) {
@@ -106,7 +106,8 @@
             }
         }
     }
-    KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} {
+    KmParamSet(KmParamSet&& other) noexcept
+        : keymaster_key_param_set_t{other.params, other.length} {
         other.length = 0;
         other.params = nullptr;
     }
@@ -131,14 +132,18 @@
 }
 
 inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_key_blob_t& blob) {
-    hidl_vec<uint8_t> result;
-    result.setToExternal(const_cast<unsigned char*>(blob.key_material), blob.key_material_size);
-    return result;
+    if (blob.key_material == nullptr || blob.key_material_size == 0) {
+        return {};
+    } else {
+        return hidl_vec<uint8_t>(blob.key_material, blob.key_material + blob.key_material_size);
+    }
 }
 inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_blob_t& blob) {
-    hidl_vec<uint8_t> result;
-    result.setToExternal(const_cast<unsigned char*>(blob.data), blob.data_length);
-    return result;
+    if (blob.data == nullptr || blob.data_length == 0) {
+        return {};
+    } else {
+        return hidl_vec<uint8_t>(blob.data, blob.data + blob.data_length);
+    }
 }
 
 inline static hidl_vec<hidl_vec<uint8_t>>
@@ -185,8 +190,7 @@
             break;
         case KM_BIGNUM:
         case KM_BYTES:
-            result[i].blob.setToExternal(const_cast<unsigned char*>(params[i].blob.data),
-                                         params[i].blob.data_length);
+            result[i].blob = kmBlob2hidlVec(params[i].blob);
             break;
         case KM_INVALID:
         default:
diff --git a/keystore/legacy_keymaster_device_wrapper.h b/keystore/legacy_keymaster_device_wrapper.h
index ad26221..cd2e5a7 100644
--- a/keystore/legacy_keymaster_device_wrapper.h
+++ b/keystore/legacy_keymaster_device_wrapper.h
@@ -43,7 +43,7 @@
 
 class LegacyKeymasterDeviceWrapper : public IKeymasterDevice {
   public:
-    LegacyKeymasterDeviceWrapper(keymaster2_device_t* dev);
+    explicit LegacyKeymasterDeviceWrapper(keymaster2_device_t* dev);
     virtual ~LegacyKeymasterDeviceWrapper();
 
     // Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
index 4069060..71ab340 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;
+    operationUploader.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..e0865a4 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,23 +56,21 @@
                              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;
+    OperationProtoHandler operationUploader;
 };
 
 }  // namespace keystore
diff --git a/keystore/operation_config.proto b/keystore/operation_config.proto
index 37b4cbb..efbb4fe 100644
--- a/keystore/operation_config.proto
+++ b/keystore/operation_config.proto
@@ -20,6 +20,7 @@
 
 option optimize_for = LITE_RUNTIME;
 
+// A single operation config
 message OperationConfig {
   // What type of encryption algorithm is the key being used in the op for.
   optional string algorithm = 1;
@@ -61,3 +62,16 @@
   // Standalone or is a file system required
   optional string key_blob_usage_reqs = 12;
 }
+
+message OperationConfigEvent {
+  optional OperationConfig op_config = 1;
+
+  // counts corresponds to the number of times each op_config in the above array
+  // was recorded during the collection period.
+  optional uint32 count = 2;
+}
+
+message OperationConfigEvents {
+    repeated OperationConfigEvent op_config_events = 1;
+}
+
diff --git a/keystore/operation_proto_handler.cpp b/keystore/operation_proto_handler.cpp
index 77e1b73..1833acb 100644
--- a/keystore/operation_proto_handler.cpp
+++ b/keystore/operation_proto_handler.cpp
@@ -23,11 +23,14 @@
 #include <keystore/keymaster_types.h>
 #include <keystore/keystore_hidl_support.h>
 #include <utils/String16.h>
+#include <utils/StrongPointer.h>
 
-#include "operation_config.pb.h"
+using namespace std::chrono;
 
 namespace keystore {
 
+constexpr auto kCollectionTime = 1h;
+
 void determinePurpose(KeyPurpose purpose, OperationConfig* operationConfig) {
     switch (purpose) {
     case KeyPurpose::VERIFY:
@@ -102,19 +105,42 @@
     }
 }
 
-void uploadOpAsProto(Operation& op, bool wasOpSuccessful) {
+void OperationProtoHandler::uploadOpAsProto(Operation& op, bool wasOpSuccessful) {
     OperationConfig operationConfig;
     determinePurpose(op.purpose, &operationConfig);
     checkKeyCharacteristics(op.characteristics.softwareEnforced, &operationConfig);
     checkKeyCharacteristics(op.characteristics.hardwareEnforced, &operationConfig);
     checkOpCharacteristics(op.params, &operationConfig);
-    auto dropbox = std::make_unique<android::os::DropBoxManager>();
     operationConfig.set_was_op_successful(wasOpSuccessful);
+    // Only bother with counting an hour out when an operation entry is actually
+    // added
+    if (protoMap.empty()) {
+        start_time = std::chrono::steady_clock::now();
+    }
+    auto cur_time = std::chrono::steady_clock::now();
 
-    size_t size = operationConfig.ByteSize();
-    auto data = std::make_unique<uint8_t[]>(size);
-    operationConfig.SerializeWithCachedSizesToArray(data.get());
-    dropbox->addData(android::String16("keymaster"), data.get(), size, 0);
+    // Add operations to a map within the time duration of an hour. Deduplicate
+    // repeated ops by incrementing the counter of the original one stored and
+    // discarding the new one.
+    protoMap[operationConfig.SerializeAsString()]++;
+
+    if (cur_time - start_time >= kCollectionTime) {
+        // Iterate through the unordered map and dump all the operation protos
+        // accumulated over the hour into the holding list proto after setting
+        // their counts.
+        OperationConfigEvents opConfigEvents;
+        for (auto elem : protoMap) {
+            OperationConfigEvent* event = opConfigEvents.add_op_config_events();
+            event->mutable_op_config()->ParseFromString(elem.first);
+            event->set_count(elem.second);
+        }
+        android::sp<android::os::DropBoxManager> dropbox(new android::os::DropBoxManager);
+        size_t size = opConfigEvents.ByteSize();
+        auto data = std::make_unique<uint8_t[]>(size);
+        opConfigEvents.SerializeWithCachedSizesToArray(data.get());
+        dropbox->addData(android::String16("keymaster"), data.get(), size, 0);
+        protoMap.clear();
+    }
 }
 
 }  // namespace keystore
diff --git a/keystore/operation_proto_handler.h b/keystore/operation_proto_handler.h
index bf461b4..838f3ec 100644
--- a/keystore/operation_proto_handler.h
+++ b/keystore/operation_proto_handler.h
@@ -17,14 +17,25 @@
 #ifndef KEYSTORE_OPERATION_PROTO_HANDLER_H_
 #define KEYSTORE_OPERATION_PROTO_HANDLER_H_
 
+#include "operation_config.pb.h"
 #include "operation_struct.h"
+#include <chrono>
+#include <unordered_map>
+#include <vector>
 
 namespace keystore {
 
 using ::android::IBinder;
 using keymaster::support::Keymaster;
 
-void uploadOpAsProto(Operation& op, bool wasOpSuccessful);
+class OperationProtoHandler {
+  public:
+    void uploadOpAsProto(Operation& op, bool wasOpSuccessful);
+
+  private:
+    std::unordered_map<std::string, int> protoMap;
+    std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();
+};
 
 }  // namespace keystore
 
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/permissions.cpp b/keystore/permissions.cpp
index c86a02a..a172761 100644
--- a/keystore/permissions.cpp
+++ b/keystore/permissions.cpp
@@ -18,8 +18,8 @@
 
 #include "permissions.h"
 
-#include <cutils/log.h>
 #include <cutils/sockets.h>
+#include <log/log.h>
 #include <private/android_filesystem_config.h>
 
 #include <selinux/android.h>
@@ -54,9 +54,16 @@
     uid_t euid;
 };
 
-user_euid user_euids[] = {
-    {AID_VPN, AID_SYSTEM}, {AID_WIFI, AID_SYSTEM}, {AID_ROOT, AID_SYSTEM},
-    {AID_WIFI, AID_KEYSTORE}, {AID_KEYSTORE, AID_WIFI}
+user_euid user_euids[] = {{AID_VPN, AID_SYSTEM},
+                          {AID_WIFI, AID_SYSTEM},
+                          {AID_ROOT, AID_SYSTEM},
+                          {AID_WIFI, AID_KEYSTORE},
+                          {AID_KEYSTORE, AID_WIFI},
+
+#ifdef GRANT_ROOT_ALL_PERMISSIONS
+                          // Allow VTS tests to act on behalf of the wifi user
+                          {AID_WIFI, AID_ROOT}
+#endif
 };
 
 struct user_perm {
@@ -69,7 +76,13 @@
     {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY)},
     {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY)},
     {AID_BLUETOOTH, static_cast<perm_t>(P_GET | P_INSERT | P_DELETE | P_EXIST | P_SIGN | P_VERIFY)},
+
+#ifdef GRANT_ROOT_ALL_PERMISSIONS
+    // Allow VTS tests running as root to perform all operations
+    {AID_ROOT, static_cast<perm_t>((uint32_t)(~0))},
+#else
     {AID_ROOT, static_cast<perm_t>(P_GET)},
+#endif
 };
 
 static const perm_t DEFAULT_PERMS = static_cast<perm_t>(
@@ -120,7 +133,7 @@
 
 static bool keystore_selinux_check_access(uid_t uid, perm_t perm, pid_t spid) {
     audit_data ad;
-    char* sctx = NULL;
+    char* sctx = nullptr;
     const char* selinux_class = "keystore_key";
     const char* str_perm = get_perm_label(perm);
 
diff --git a/keystore/tests/Android.bp b/keystore/tests/Android.bp
index c3f5177..1ce1210 100644
--- a/keystore/tests/Android.bp
+++ b/keystore/tests/Android.bp
@@ -8,23 +8,31 @@
         "-O0",
     ],
     srcs: [
+        "aaid_truncation_test.cpp",
         "auth_token_table_test.cpp",
         "auth_token_formatting_test.cpp",
+        "blob_test.cpp",
         "confirmationui_rate_limiting_test.cpp",
         "gtest_main.cpp",
     ],
     name: "keystore_unit_tests",
-    tags: ["test"],
     static_libs: [
         "android.hardware.confirmationui@1.0",
         "libbase",
+        "libcrypto",
+        "libcutils",
         "libgtest_main",
         "libhidlbase",
         "libkeymaster4support",
         "libkeystore_test",
         "liblog",
+        "libutils",
+        "libvndksupport",
     ],
-    shared_libs: ["libkeymaster_messages"],
+    shared_libs: [
+        "libbinder",
+        "libkeymaster_messages",
+    ],
    sanitize: {
      cfi: false,
    }
diff --git a/keystore/tests/aaid_truncation_test.cpp b/keystore/tests/aaid_truncation_test.cpp
new file mode 100644
index 0000000..e5d5e9f
--- /dev/null
+++ b/keystore/tests/aaid_truncation_test.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <string>
+#include <utils/String16.h>
+
+#include "../keystore_attestation_id.h"
+#include <keymaster/logger.h>
+
+#include <keystore/KeyAttestationApplicationId.h>
+#include <keystore/KeyAttestationPackageInfo.h>
+#include <keystore/Signature.h>
+
+using ::android::String16;
+using ::android::security::KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE;
+using ::android::security::keymaster::KeyAttestationApplicationId;
+using ::android::security::keymaster::KeyAttestationPackageInfo;
+using std::vector;
+
+namespace keystore {
+
+namespace test {
+
+namespace {
+
+constexpr const char* kDummyPackageName = "DummyPackage";
+
+constexpr const char* kLongPackageName =
+    "a.long.package.name"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+
+constexpr const char* kReasonablePackageName =
+    "a.reasonable.length.package.name"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+
+constexpr const size_t kTooManyPackages = 4;
+
+// Signatures should be 32 bytes
+constexpr const uint8_t kDummySignature[32] = {
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
+constexpr const size_t kTooManySignatures = 35;
+
+}  // namespace
+
+using ::android::content::pm::Signature;
+using ::android::security::build_attestation_application_id;
+
+std::unique_ptr<KeyAttestationPackageInfo>
+make_package_info_with_signatures(const char* package_name,
+                                  KeyAttestationPackageInfo::SignaturesVector signatures) {
+    return std::make_unique<KeyAttestationPackageInfo>(
+        String16(package_name), 1 /* version code */,
+        std::make_shared<KeyAttestationPackageInfo::SignaturesVector>(std::move(signatures)));
+}
+
+std::unique_ptr<KeyAttestationPackageInfo> make_package_info(const char* package_name) {
+    return make_package_info_with_signatures(package_name,
+                                             KeyAttestationPackageInfo::SignaturesVector());
+}
+
+TEST(AaidTruncationTest, shortPackageInfoTest) {
+    KeyAttestationApplicationId app_id(make_package_info(kDummyPackageName));
+
+    auto result = build_attestation_application_id(app_id);
+    ASSERT_TRUE(result.isOk());
+    std::vector<uint8_t>& encoded_app_id = result;
+    ASSERT_LT(encoded_app_id.size(), KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE);
+}
+
+TEST(AaidTruncationTest, tooLongPackageNameTest) {
+    KeyAttestationApplicationId app_id(make_package_info(kLongPackageName));
+
+    auto result = build_attestation_application_id(app_id);
+    ASSERT_TRUE(result.isOk());
+    std::vector<uint8_t>& encoded_app_id = result;
+    ASSERT_LT(encoded_app_id.size(), KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE);
+}
+
+TEST(AaidTruncationTest, tooManySignaturesTest) {
+    std::vector<uint8_t> dummy_sig_data(kDummySignature, kDummySignature + 32);
+    KeyAttestationPackageInfo::SignaturesVector signatures;
+    // Add 35 signatures which will surely exceed the 1K limit.
+    for (size_t i = 0; i < kTooManySignatures; ++i) {
+        signatures.push_back(std::make_unique<Signature>(dummy_sig_data));
+    }
+
+    KeyAttestationApplicationId app_id(
+        make_package_info_with_signatures(kDummyPackageName, std::move(signatures)));
+
+    auto result = build_attestation_application_id(app_id);
+    ASSERT_TRUE(result.isOk());
+    std::vector<uint8_t>& encoded_app_id = result;
+    ASSERT_LT(encoded_app_id.size(), KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE);
+}
+
+TEST(AaidTruncationTest, combinedPackagesAndSignaturesTest) {
+    std::vector<uint8_t> dummy_sig_data(kDummySignature, kDummySignature + 32);
+    KeyAttestationApplicationId::PackageInfoVector packages;
+
+    for (size_t i = 0; i < kTooManyPackages; ++i) {
+        KeyAttestationPackageInfo::SignaturesVector signatures;
+        // Add a few signatures for each package
+        for (int j = 0; j < 3; ++j) {
+            signatures.push_back(std::make_unique<Signature>(dummy_sig_data));
+        }
+        packages.push_back(
+            make_package_info_with_signatures(kReasonablePackageName, std::move(signatures)));
+    }
+
+    KeyAttestationApplicationId app_id(std::move(packages));
+    auto result = build_attestation_application_id(app_id);
+    ASSERT_TRUE(result.isOk());
+    std::vector<uint8_t>& encoded_app_id = result;
+    ASSERT_LT(encoded_app_id.size(), KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE);
+}
+
+}  // namespace test
+}  // namespace keystore
diff --git a/keystore/tests/auth_token_table_test.cpp b/keystore/tests/auth_token_table_test.cpp
index 511a78d..f6ce10e 100644
--- a/keystore/tests/auth_token_table_test.cpp
+++ b/keystore/tests/auth_token_table_test.cpp
@@ -79,7 +79,7 @@
         .Authorization(TAG_USER_SECURE_ID, rsid);
     // Use timeout == 0 to indicate tags that require auth per operation.
     if (timeout != 0) builder.Authorization(TAG_AUTH_TIMEOUT, timeout);
-    return builder;
+    return std::move(builder);
 }
 
 // Tests obviously run so fast that a real-time clock with a one-second granularity rarely changes
@@ -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/tests/blob_test.cpp b/keystore/tests/blob_test.cpp
new file mode 100644
index 0000000..485bd88
--- /dev/null
+++ b/keystore/tests/blob_test.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <string>
+#include <utils/String16.h>
+
+#include "../blob.h"
+
+namespace keystore {
+
+namespace test {
+
+namespace {
+
+constexpr const char* kNameToEncode = "some key name !\\ %#|\"";
+
+}  // namespace
+
+TEST(BlobTest, nameEncodingAndDecodingTest) {
+    std::string toEncode(kNameToEncode);
+    std::string decoded(decodeKeyName(encodeKeyName(toEncode)));
+
+    ASSERT_EQ(toEncode, decoded);
+}
+
+}  // namespace test
+}  // namespace keystore
diff --git a/keystore/tests/list_auth_bound_keys_test.sh b/keystore/tests/list_auth_bound_keys_test.sh
new file mode 100755
index 0000000..f609b34
--- /dev/null
+++ b/keystore/tests/list_auth_bound_keys_test.sh
@@ -0,0 +1,77 @@
+#!/usr/bin/env bash
+
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+# Simple adb based test for keystore method list_auth_bound_keys
+# Depends on keystore_cli_v2 tool and root
+#
+
+set -e
+
+ROOT_ID=0
+USER1_ID=10901
+USER2_ID=10902
+SYSTEM_ID=1000
+
+function cli {
+	adb shell "su $1 keystore_cli_v2 $2"
+}
+
+#start as root
+adb root
+
+# generate keys as user
+echo "generating keys"
+cli $USER1_ID "delete --name=no_auth_key" || true
+cli $USER1_ID "generate --name=no_auth_key"
+cli $USER2_ID "delete --name=auth_key" || true
+if ! cli $USER2_ID "generate --name=auth_key --auth_bound"; then
+	echo "Unable to generate auth bound key, make sure device/emulator has a pin/password set."
+	echo "$ adb shell locksettings set-pin 1234"
+	exit 1
+fi
+
+# try to list keys as user
+if cli $USER2_ID list-apps-with-keys; then
+	echo "Error: list-apps-with-keys succeeded as user, this is not expected!"
+	exit 1
+fi
+
+# try to list keys as root
+if cli $ROOT_ID "list-apps-with-keys"; then
+	echo "Error: list-apps-with-keys succeeded as root, this is not expected!"
+	exit 1
+fi
+
+# try to list keys as system
+success=false
+while read -r line; do
+	echo $line
+    if [ "$line" == "$USER2_ID" ]; then
+    	success=true
+    fi
+    if [ "$line" == "$USER1_ID" ]; then
+    	echo "Error: User1 id not expected in list"
+    	exit 1
+    fi
+done <<< $(cli $SYSTEM_ID "list-apps-with-keys")
+if [ $success = true ]; then
+	echo "Success!"
+else
+	echo "Error: User2 id not in list"
+	exit 1
+fi
\ No newline at end of file
diff --git a/keystore/user_state.cpp b/keystore/user_state.cpp
index aab6175..bc3f6d9 100644
--- a/keystore/user_state.cpp
+++ b/keystore/user_state.cpp
@@ -28,30 +28,37 @@
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 
 #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);
@@ -75,7 +82,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) {
@@ -90,23 +97,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;
     }
-    mMasterKey = src->mMasterKey;
+    mMasterKey = (*src)->mMasterKey;
     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;
     }
@@ -115,8 +122,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;
     }
@@ -126,7 +133,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;
@@ -137,11 +144,15 @@
     generateKeyFromPassword(passwordKey, pw, mSalt);
     Blob masterKeyBlob(mMasterKey.data(), mMasterKey.size(), mSalt, sizeof(mSalt),
                        TYPE_MASTER_KEY_AES256);
-    return masterKeyBlob.writeBlob(mMasterKeyFile, passwordKey, STATE_NO_ERROR);
+    auto lockedEntry = LockedKeyBlobEntry::get(mMasterKeyEntry);
+    return lockedEntry.writeBlobs(masterKeyBlob, {}, passwordKey, STATE_NO_ERROR);
 }
 
 ResponseCode UserState::readMasterKey(const android::String8& pw) {
-    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;
     }
@@ -158,7 +169,7 @@
     if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
         salt = (uint8_t*)&rawBlob + length - SALT_SIZE;
     } else {
-        salt = NULL;
+        salt = nullptr;
     }
 
     size_t masterKeySize = MASTER_KEY_SIZE_BYTES;
@@ -168,8 +179,10 @@
 
     std::vector<uint8_t> passwordKey(masterKeySize);
     generateKeyFromPassword(passwordKey, 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;
     }
@@ -178,7 +191,7 @@
 
     if (response == ResponseCode::NO_ERROR && masterKeyBlobLength == masterKeySize) {
         // If salt was missing, generate one and write a new master key file with the salt.
-        if (salt == NULL) {
+        if (salt == nullptr) {
             if (!generateSalt()) {
                 return ResponseCode::SYSTEM_ERROR;
             }
@@ -187,6 +200,7 @@
         if (response == ResponseCode::NO_ERROR) {
             mMasterKey = std::vector<uint8_t>(masterKeyBlob.getValue(),
                                               masterKeyBlob.getValue() + masterKeyBlob.getLength());
+
             setupMasterKeys();
         }
         return response;
@@ -211,7 +225,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) {
@@ -222,7 +236,7 @@
     }
 
     struct dirent* file;
-    while ((file = readdir(dir)) != NULL) {
+    while ((file = readdir(dir)) != nullptr) {
         // skip . and ..
         if (!strcmp(".", file->d_name) || !strcmp("..", file->d_name)) {
             continue;
@@ -237,7 +251,7 @@
 void UserState::generateKeyFromPassword(std::vector<uint8_t>& key, const android::String8& pw,
                                         uint8_t* salt) {
     size_t saltSize;
-    if (salt != NULL) {
+    if (salt != nullptr) {
         saltSize = SALT_SIZE;
     } else {
         // Pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
@@ -275,3 +289,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 c4f3cd4..b0671e3 100644
--- a/keystore/user_state.h
+++ b/keystore/user_state.h
@@ -24,19 +24,33 @@
 #include <utils/String8.h>
 
 #include <keystore/keystore.h>
+
+#include "blob.h"
+#include "keystore_utils.h"
+
+#include <android-base/logging.h>
+#include <condition_variable>
+#include <keystore/keystore_concurrency.h>
+#include <mutex>
+#include <set>
 #include <vector>
 
+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; }
@@ -48,8 +62,8 @@
 
     ResponseCode initialize(const android::String8& pw);
 
-    ResponseCode copyMasterKey(UserState* src);
-    ResponseCode copyMasterKeyFile(UserState* src);
+    ResponseCode copyMasterKey(LockedUserState<UserState>* src);
+    ResponseCode copyMasterKeyFile(LockedUserState<UserState>* src);
     ResponseCode writeMasterKey(const android::String8& pw);
     ResponseCode readMasterKey(const android::String8& pw);
 
@@ -57,6 +71,9 @@
 
     bool reset();
 
+    bool operator<(const UserState& rhs) const;
+    bool operator<(uid_t userId) const;
+
   private:
     static const int SHA1_DIGEST_SIZE_BYTES = 16;
     static const int SHA256_DIGEST_SIZE_BYTES = 32;
@@ -73,11 +90,9 @@
     bool generateMasterKey();
     void setupMasterKeys();
 
+    KeyBlobEntry mMasterKeyEntry;
+
     uid_t mUserId;
-
-    char* mUserDir;
-    char* mMasterKeyFile;
-
     State mState;
     int8_t mRetry;
 
@@ -85,4 +100,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_
