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 8d095e1..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,7 +78,7 @@
         pdk: {
             enabled: false,
         },
-        debuggable: {
+	debuggable: {
             cflags: [
                 // Allow VTS tests running as root to have
                 // additional permissions.
@@ -91,7 +93,6 @@
 cc_binary {
     name: "keystore_cli",
     defaults: ["keystore_defaults"],
-    tags: ["debug"],
 
     srcs: ["keystore_cli.cpp"],
     shared_libs: [
@@ -112,7 +113,6 @@
 cc_binary {
     name: "keystore_cli_v2",
     defaults: ["keystore_defaults"],
-    tags: ["debug"],
 
     cflags: [
         "-DKEYMASTER_NAME_TAGS",
@@ -144,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",
@@ -237,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",
@@ -255,6 +265,9 @@
         "libkeymaster4support",
     ],
 
+    aidl: {
+        include_dirs: ["frameworks/base/core/java/"],
+    },
     export_include_dirs: ["include"],
 }
 
@@ -262,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 {
@@ -292,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 b297c59..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 {
@@ -126,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_
