diff --git a/identity/Android.bp b/identity/Android.bp
index d66f4ec..8267a6b 100644
--- a/identity/Android.bp
+++ b/identity/Android.bp
@@ -42,6 +42,7 @@
         "libbinder_ndk",
         "android.hardware.keymaster@4.0",
         "libcredstore_aidl",
+        "libcrypto",
         "libutils",
         "libhidlbase",
         "android.hardware.identity-support-lib",
@@ -53,7 +54,7 @@
     static_libs: [
         "android.hardware.identity-V3-cpp",
         "android.hardware.keymaster-V3-cpp",
-        "libcppbor",
+        "libcppbor_external",
     ]
 }
 
diff --git a/identity/CredentialData.cpp b/identity/CredentialData.cpp
index d95c1ac..74b995d 100644
--- a/identity/CredentialData.cpp
+++ b/identity/CredentialData.cpp
@@ -273,7 +273,7 @@
     }
 
     for (size_t n = 0; n < map->size(); n++) {
-        auto [keyItem, valueItem] = (*map)[n];
+        auto& [keyItem, valueItem] = (*map)[n];
         const cppbor::Tstr* tstr = keyItem->asTstr();
         if (tstr == nullptr) {
             LOG(ERROR) << "Key item in top-level map is not a tstr";
@@ -325,7 +325,7 @@
                 return false;
             }
             for (size_t m = 0; m < map->size(); m++) {
-                auto [ecKeyItem, ecValueItem] = (*map)[m];
+                auto& [ecKeyItem, ecValueItem] = (*map)[m];
                 const cppbor::Tstr* ecTstr = ecKeyItem->asTstr();
                 if (ecTstr == nullptr) {
                     LOG(ERROR) << "Key item in encryptedChunks map is not a tstr";
diff --git a/keystore-engine/Android.bp b/keystore-engine/Android.bp
index 9980765..0cecfd8 100644
--- a/keystore-engine/Android.bp
+++ b/keystore-engine/Android.bp
@@ -26,7 +26,6 @@
 
     srcs: [
         "android_engine.cpp",
-        "keystore_backend_binder.cpp",
         "keystore2_engine.cpp",
     ],
 
@@ -38,14 +37,9 @@
 
     shared_libs: [
         "android.system.keystore2-V1-ndk_platform",
-        "libbinder",
         "libbinder_ndk",
         "libcrypto",
         "libcutils",
-        "libhidlbase",
-        "libkeystore_aidl",
-        "libkeystore_binder",
-        "libkeystore_parcelables",
         "liblog",
         "libbase",
         "libutils",
@@ -53,14 +47,15 @@
 
 }
 
-// This builds a variant of libkeystore-engine that uses a HIDL HAL
-// owned by the WiFi user to perform signing operations.
+// This builds a variant of libkeystore-engine that is available vendor.
+// It used to use a HIDL interface to connect to keystore through wificond.
+// Now That Keystore 2.0 has a vintf stable interface this library is
+// actually identical to libkeystore-engine.
 cc_library_shared {
     name: "libkeystore-engine-wifi-hidl",
 
     srcs: [
         "android_engine.cpp",
-        "keystore_backend_hidl.cpp",
         "keystore2_engine.cpp",
     ],
 
@@ -68,17 +63,14 @@
         "-fvisibility=hidden",
         "-Wall",
         "-Werror",
-        "-DBACKEND_WIFI_HIDL",
     ],
 
     shared_libs: [
         "android.system.keystore2-V1-ndk_platform",
-        "android.system.wifi.keystore@1.0",
         "libbase",
         "libbinder_ndk",
         "libcrypto",
         "liblog",
-        "libhidlbase",
         "libcutils",
         "libutils",
     ],
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
index 5881523..e46204e 100644
--- a/keystore-engine/android_engine.cpp
+++ b/keystore-engine/android_engine.cpp
@@ -22,307 +22,10 @@
 
 #define LOG_TAG "keystore-engine"
 
-#include <pthread.h>
-#include <string.h>
-
 #include <log/log.h>
 
-#include <openssl/bn.h>
-#include <openssl/ec.h>
-#include <openssl/ec_key.h>
-#include <openssl/ecdsa.h>
-#include <openssl/engine.h>
-#include <openssl/evp.h>
-#include <openssl/rsa.h>
-#include <openssl/x509.h>
-
-#include <memory>
-
 #include "keystore2_engine.h"
 
-#ifndef BACKEND_WIFI_HIDL
-#include "keystore_backend_binder.h"
-#else
-#include "keystore_backend_hidl.h"
-#endif
-
-namespace {
-KeystoreBackend *g_keystore_backend;
-void ensure_keystore_engine();
-
-/* key_id_dup is called when one of the RSA or EC_KEY objects is duplicated. */
-int key_id_dup(CRYPTO_EX_DATA* /* to */,
-               const CRYPTO_EX_DATA* /* from */,
-               void** from_d,
-               int /* index */,
-               long /* argl */,
-               void* /* argp */) {
-    char *key_id = reinterpret_cast<char *>(*from_d);
-    if (key_id != nullptr) {
-        *from_d = strdup(key_id);
-    }
-    return 1;
-}
-
-/* key_id_free is called when one of the RSA, DSA or EC_KEY object is freed. */
-void key_id_free(void* /* parent */,
-                 void* ptr,
-                 CRYPTO_EX_DATA* /* ad */,
-                 int /* index */,
-                 long /* argl */,
-                 void* /* argp */) {
-    char *key_id = reinterpret_cast<char *>(ptr);
-    free(key_id);
-}
-
-/* Many OpenSSL APIs take ownership of an argument on success but don't free
- * 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) auto _dummy __attribute__((unused)) = (obj).release()
-
-const char* rsa_get_key_id(const RSA* rsa);
-
-/* rsa_private_transform takes a big-endian integer from |in|, calculates the
- * d'th power of it, modulo the RSA modulus, and writes the result as a
- * big-endian integer to |out|. Both |in| and |out| are |len| bytes long. It
- * returns one on success and zero otherwise. */
-int rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) {
-    ALOGV("rsa_private_transform(%p, %p, %p, %u)", rsa, out, in, (unsigned) len);
-
-    ensure_keystore_engine();
-
-    const char *key_id = rsa_get_key_id(rsa);
-    if (key_id == nullptr) {
-        ALOGE("key had no key_id!");
-        return 0;
-    }
-
-    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) {
-        ALOGW("There was an error during rsa_decrypt: could not connect");
-        return 0;
-    } else if (ret != 0) {
-        ALOGW("Error during sign from keystore: %d", ret);
-        return 0;
-    } else if (reply_len == 0 || reply == nullptr) {
-        ALOGW("No valid signature returned");
-        return 0;
-    }
-
-    if (reply_len > len) {
-        /* The result of the RSA operation can never be larger than the size of
-         * the modulus so we assume that the result has extra zeros on the
-         * left. This provides attackers with an oracle, but there's nothing
-         * that we can do about it here. */
-        ALOGW("Reply len %zu greater than expected %zu", reply_len, len);
-        memcpy(out, &reply[reply_len - len], len);
-    } else if (reply_len < len) {
-        /* If the Keystore implementation returns a short value we assume that
-         * it's because it removed leading zeros from the left side. This is
-         * bad because it provides attackers with an oracle but we cannot do
-         * anything about a broken Keystore implementation here. */
-        ALOGW("Reply len %zu lesser than expected %zu", reply_len, len);
-        memset(out, 0, len);
-        memcpy(out + len - reply_len, &reply[0], reply_len);
-    } else {
-        memcpy(out, &reply[0], len);
-    }
-
-    ALOGV("rsa=%p keystore_rsa_priv_dec successful", rsa);
-    return 1;
-}
-
-const char* ecdsa_get_key_id(const EC_KEY* ec_key);
-
-/* ecdsa_sign signs |digest_len| bytes from |digest| with |ec_key| and writes
- * the resulting signature (an ASN.1 encoded blob) to |sig|. It returns one on
- * success and zero otherwise. */
-static int ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
-                      unsigned int* sig_len, EC_KEY* ec_key) {
-    ALOGV("ecdsa_sign(%p, %u, %p)", digest, (unsigned) digest_len, ec_key);
-
-    ensure_keystore_engine();
-
-    const char *key_id = ecdsa_get_key_id(ec_key);
-    if (key_id == nullptr) {
-        ALOGE("key had no key_id!");
-        return 0;
-    }
-
-    size_t ecdsa_size = ECDSA_size(ec_key);
-
-    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 == nullptr) {
-        ALOGW("No valid signature returned");
-        return 0;
-    } else if (reply_len > ecdsa_size) {
-        ALOGW("Signature is too large");
-        return 0;
-    }
-
-    // Reviewer: should't sig_len be checked here? Or is it just assumed that it is at least ecdsa_size?
-    memcpy(sig, &reply[0], reply_len);
-    *sig_len = reply_len;
-
-    ALOGV("ecdsa_sign(%p, %u, %p) => success", digest, (unsigned)digest_len,
-          ec_key);
-    return 1;
-}
-
-/* KeystoreEngine is a BoringSSL ENGINE that implements RSA and ECDSA by
- * forwarding the requested operations to Keystore. */
-class KeystoreEngine {
- public:
-  KeystoreEngine()
-      : rsa_index_(RSA_get_ex_new_index(0 /* argl */,
-                                        nullptr /* argp */,
-                                        nullptr /* new_func */,
-                                        key_id_dup,
-                                        key_id_free)),
-        ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */,
-                                              nullptr /* argp */,
-                                              nullptr /* new_func */,
-                                              key_id_dup,
-                                              key_id_free)),
-        engine_(ENGINE_new()) {
-    memset(&rsa_method_, 0, sizeof(rsa_method_));
-    rsa_method_.common.is_static = 1;
-    rsa_method_.private_transform = rsa_private_transform;
-    rsa_method_.flags = RSA_FLAG_OPAQUE;
-    ENGINE_set_RSA_method(engine_, &rsa_method_, sizeof(rsa_method_));
-
-    memset(&ecdsa_method_, 0, sizeof(ecdsa_method_));
-    ecdsa_method_.common.is_static = 1;
-    ecdsa_method_.sign = ecdsa_sign;
-    ecdsa_method_.flags = ECDSA_FLAG_OPAQUE;
-    ENGINE_set_ECDSA_method(engine_, &ecdsa_method_, sizeof(ecdsa_method_));
-  }
-
-  int rsa_ex_index() const { return rsa_index_; }
-  int ec_key_ex_index() const { return ec_key_index_; }
-
-  const ENGINE* engine() const { return engine_; }
-
- private:
-  const int rsa_index_;
-  const int ec_key_index_;
-  RSA_METHOD rsa_method_;
-  ECDSA_METHOD ecdsa_method_;
-  ENGINE* const engine_;
-};
-
-pthread_once_t g_keystore_engine_once = PTHREAD_ONCE_INIT;
-KeystoreEngine *g_keystore_engine;
-
-/* init_keystore_engine is called to initialize |g_keystore_engine|. This
- * should only be called by |pthread_once|. */
-void init_keystore_engine() {
-  g_keystore_engine = new KeystoreEngine;
-#ifndef BACKEND_WIFI_HIDL
-  g_keystore_backend = new KeystoreBackendBinder;
-#else
-  g_keystore_backend = new KeystoreBackendHidl;
-#endif
-}
-
-/* ensure_keystore_engine ensures that |g_keystore_engine| is pointing to a
- * valid |KeystoreEngine| object and creates one if not. */
-void ensure_keystore_engine() {
-  pthread_once(&g_keystore_engine_once, init_keystore_engine);
-}
-
-const char* rsa_get_key_id(const RSA* rsa) {
-  return reinterpret_cast<char*>(
-      RSA_get_ex_data(rsa, g_keystore_engine->rsa_ex_index()));
-}
-
-const char* ecdsa_get_key_id(const EC_KEY* ec_key) {
-  return reinterpret_cast<char*>(
-      EC_KEY_get_ex_data(ec_key, g_keystore_engine->ec_key_ex_index()));
-}
-
-/* wrap_rsa returns an |EVP_PKEY| that contains an RSA key where the public
- * part is taken from |public_rsa| and the private operations are forwarded to
- * KeyStore and operate on the key named |key_id|. */
-static EVP_PKEY *wrap_rsa(const char *key_id, const RSA *public_rsa) {
-    bssl::UniquePtr<RSA> rsa(RSA_new_method(g_keystore_engine->engine()));
-    if (rsa.get() == nullptr) {
-        return nullptr;
-    }
-
-    char *key_id_copy = strdup(key_id);
-    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 nullptr;
-    }
-
-    rsa->n = BN_dup(public_rsa->n);
-    rsa->e = BN_dup(public_rsa->e);
-    if (rsa->n == nullptr || rsa->e == nullptr) {
-        return nullptr;
-    }
-
-    bssl::UniquePtr<EVP_PKEY> result(EVP_PKEY_new());
-    if (result.get() == nullptr ||
-        !EVP_PKEY_assign_RSA(result.get(), rsa.get())) {
-        return nullptr;
-    }
-    OWNERSHIP_TRANSFERRED(rsa);
-
-    return result.release();
-}
-
-/* wrap_ecdsa returns an |EVP_PKEY| that contains an ECDSA key where the public
- * part is taken from |public_rsa| and the private operations are forwarded to
- * KeyStore and operate on the key named |key_id|. */
-static EVP_PKEY *wrap_ecdsa(const char *key_id, const EC_KEY *public_ecdsa) {
-    bssl::UniquePtr<EC_KEY> ec(EC_KEY_new_method(g_keystore_engine->engine()));
-    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 nullptr;
-    }
-
-    char *key_id_copy = strdup(key_id);
-    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 nullptr;
-    }
-
-    bssl::UniquePtr<EVP_PKEY> result(EVP_PKEY_new());
-    if (result.get() == nullptr ||
-        !EVP_PKEY_assign_EC_KEY(result.get(), ec.get())) {
-        return nullptr;
-    }
-    OWNERSHIP_TRANSFERRED(ec);
-
-    return result.release();
-}
-
-}  /* anonymous namespace */
-
 extern "C" {
 
 EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id) __attribute__((visibility("default")));
@@ -334,48 +37,7 @@
 EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id) {
     ALOGV("EVP_PKEY_from_keystore(\"%s\")", key_id);
 
-    if (auto ks2_key = EVP_PKEY_from_keystore2(key_id)) {
-        return ks2_key;
-    }
-
-    ensure_keystore_engine();
-
-    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 nullptr;
-    } else if (ret != 0 || pubkey == nullptr) {
-        ALOGW("keystore reports error: %d", ret);
-        return nullptr;
-    }
-
-    const uint8_t *inp = pubkey;
-    bssl::UniquePtr<EVP_PKEY> pkey(d2i_PUBKEY(nullptr, &inp, pubkey_len));
-    if (pkey.get() == nullptr) {
-        ALOGW("Cannot convert pubkey");
-        return nullptr;
-    }
-
-    EVP_PKEY *result;
-    switch (EVP_PKEY_type(pkey->type)) {
-    case EVP_PKEY_RSA: {
-        bssl::UniquePtr<RSA> public_rsa(EVP_PKEY_get1_RSA(pkey.get()));
-        result = wrap_rsa(key_id, public_rsa.get());
-        break;
-    }
-    case EVP_PKEY_EC: {
-        bssl::UniquePtr<EC_KEY> public_ecdsa(EVP_PKEY_get1_EC_KEY(pkey.get()));
-        result = wrap_ecdsa(key_id, public_ecdsa.get());
-        break;
-    }
-    default:
-        ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type));
-        result = nullptr;
-    }
-
-    return result;
+    return EVP_PKEY_from_keystore2(key_id);
 }
 
 }  // extern "C"
diff --git a/keystore-engine/keystore_backend.h b/keystore-engine/keystore_backend.h
deleted file mode 100644
index 88c94b3..0000000
--- a/keystore-engine/keystore_backend.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2017 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#ifndef ANDROID_KEYSTORE_BACKEND_H
-#define ANDROID_KEYSTORE_BACKEND_H
-
-#include <stdint.h>
-
-class KeystoreBackend {
-  public:
-    virtual ~KeystoreBackend() {}
-    virtual int32_t sign(const char *key_id, const uint8_t* in, size_t len,
-                         uint8_t** reply, size_t* reply_len) = 0;
-    virtual int32_t get_pubkey(const char *key_id, uint8_t** pubkey,
-                               size_t* reply_len) = 0;
-};
-
-#endif  // ANDROID_KEYSTORE_BACKEND_H
diff --git a/keystore-engine/keystore_backend_binder.cpp b/keystore-engine/keystore_backend_binder.cpp
deleted file mode 100644
index 8b5a584..0000000
--- a/keystore-engine/keystore_backend_binder.cpp
+++ /dev/null
@@ -1,286 +0,0 @@
-/* Copyright 2017 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#include "keystore_backend_binder.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>
-
-#include <future>
-#include <thread>
-
-using android::security::keystore::IKeystoreService;
-using namespace android;
-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) {
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16(keystore_service_name));
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-
-    if (service == nullptr) {
-        LOG(ERROR) << AT << "could not contact keystore";
-        return -1;
-    }
-
-    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;
-    }
-
-    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>() /* input */,
-        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;
-}
-
-int32_t KeystoreBackendBinder::get_pubkey(const char* key_id, uint8_t** pubkey,
-                                          size_t* pubkey_len) {
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16(keystore_service_name));
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-
-    if (service == nullptr) {
-        LOG(ERROR) << AT << "could not contact keystore";
-        return -1;
-    }
-
-    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;
-    }
-
-    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
deleted file mode 100644
index 4c828c5..0000000
--- a/keystore-engine/keystore_backend_binder.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2017 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#ifndef ANDROID_KEYSTORE_BACKEND_BINDER_H
-#define ANDROID_KEYSTORE_BACKEND_BINDER_H
-
-#include "keystore_backend.h"
-
-class KeystoreBackendBinder : public KeystoreBackend {
-  public:
-    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;
-    int32_t get_pubkey(const char *key_id, uint8_t** pubkey,
-                     size_t* reply_len) override;
-};
-
-#endif  // ANDROID_KEYSTORE_BACKEND_BINDER_H
diff --git a/keystore-engine/keystore_backend_hidl.cpp b/keystore-engine/keystore_backend_hidl.cpp
deleted file mode 100644
index 30cf890..0000000
--- a/keystore-engine/keystore_backend_hidl.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Copyright 2017 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#include "keystore_backend_hidl.h"
-
-#include <android/system/wifi/keystore/1.0/IKeystore.h>
-#include <log/log.h>
-
-using android::hardware::hidl_vec;
-using android::hardware::Return;
-using android::sp;
-using android::system::wifi::keystore::V1_0::IKeystore;
-
-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 == nullptr || in == nullptr || reply == nullptr || reply_len == nullptr) {
-        ALOGE("Null pointer argument passed");
-        return -1;
-    }
-
-    sp<IKeystore> service = IKeystore::tryGetService();
-    if (service == nullptr) {
-        ALOGE("could not contact keystore HAL");
-        return -1;
-    }
-
-    bool success = false;
-    auto cb = [&](IKeystore::KeystoreStatusCode status,
-                  hidl_vec<uint8_t> signedData) {
-      if (status == IKeystore::KeystoreStatusCode::SUCCESS) {
-          *reply_len = signedData.size();
-          *reply = signedData.releaseData();
-          success = true;
-      }
-    };
-    Return<void> ret = service->sign(
-        key_id, std::vector<uint8_t>(in, in + len), cb);
-    if (!ret.isOk() || !success) {
-        return 1;
-    }
-    return 0;
-}
-
-int32_t KeystoreBackendHidl::get_pubkey(
-        const char *key_id, uint8_t** pubkey, size_t* pubkey_len) {
-    if (key_id == nullptr || pubkey == nullptr || pubkey_len == nullptr) {
-        ALOGE("Null pointer argument passed");
-        return -1;
-    }
-
-    sp<IKeystore> service = IKeystore::tryGetService();
-    if (service == nullptr) {
-        ALOGE("could not contact keystore HAL");
-        return -1;
-    }
-
-    bool success = false;
-    auto cb = [&](IKeystore::KeystoreStatusCode status,
-                  hidl_vec<uint8_t> publicKey) {
-      if (status == IKeystore::KeystoreStatusCode::SUCCESS) {
-          *pubkey_len = publicKey.size();
-          *pubkey = publicKey.releaseData();
-          success = true;
-      }
-    };
-    Return<void> ret = service->getPublicKey(key_id, cb);
-    if (!ret.isOk() || !success) {
-        return 1;
-    }
-    return 0;
-}
diff --git a/keystore-engine/keystore_backend_hidl.h b/keystore-engine/keystore_backend_hidl.h
deleted file mode 100644
index fd38f69..0000000
--- a/keystore-engine/keystore_backend_hidl.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2017 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#ifndef ANDROID_KEYSTORE_BACKEND_HIDL_H
-#define ANDROID_KEYSTORE_BACKEND_HIDL_H
-
-#include "keystore_backend.h"
-
-class KeystoreBackendHidl : public KeystoreBackend {
-  public:
-    KeystoreBackendHidl() {}
-    virtual ~KeystoreBackendHidl() {}
-    int32_t sign(const char *key_id, const uint8_t* in, size_t len,
-                 uint8_t** reply, size_t* reply_len) override;
-    int32_t get_pubkey(const char *key_id, uint8_t** pubkey,
-                     size_t* reply_len) override;
-};
-
-#endif  // ANDROID_KEYSTORE_BACKEND_HIDL_H
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 7278cee..0f2000c 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -35,97 +35,6 @@
 }
 
 cc_binary {
-    name: "keystore",
-    defaults: ["keystore_defaults"],
-
-    srcs: [
-        "KeyStore.cpp",
-        "auth_token_table.cpp",
-        "blob.cpp",
-        "confirmation_manager.cpp",
-        "grant_store.cpp",
-        "key_creation_log_handler.cpp",
-        "key_operation_log_handler.cpp",
-        "key_attestation_log_handler.cpp",
-        "key_store_service.cpp",
-        "keyblob_utils.cpp",
-        "keymaster_enforcement.cpp",
-        "keymaster_worker.cpp",
-        "keystore_main.cpp",
-        "keystore_utils.cpp",
-        "legacy_keymaster_device_wrapper.cpp",
-        "operation.cpp",
-        "permissions.cpp",
-        "user_state.cpp",
-    ],
-    shared_libs: [
-        "android.hardware.confirmationui@1.0",
-        "android.hardware.keymaster@3.0",
-        "android.hardware.keymaster@4.0",
-        "android.hardware.keymaster@4.1",
-        "libbase",
-        "libbinder",
-        "libcrypto",
-        "libcutils",
-        "libhardware",
-        "libhidlbase",
-        "libkeymaster4support",
-        "libkeymaster4_1support",
-        "libkeymaster_messages",
-        "libkeymaster_portable",
-        "libkeystore-attestation-application-id",
-        "libkeystore_aidl",
-        "libkeystore_binder",
-        "libkeystore_parcelables",
-        "liblog",
-        "libprotobuf-cpp-lite",
-        "libselinux",
-        "libservices",
-        "libsoftkeymasterdevice",
-        "libutils",
-        "libstatslog",
-    ],
-    init_rc: ["keystore.rc"],
-    aidl: {
-        include_dirs: ["frameworks/base/core/java/"],
-    },
-
-    product_variables: {
-        pdk: {
-            enabled: false,
-        },
-	debuggable: {
-            cflags: [
-                // Allow VTS tests running as root to have
-                // additional permissions.
-                "-DGRANT_ROOT_ALL_PERMISSIONS",
-            ],
-        },
-    },
-
-    required: ["keystore_cli_v2"],
-}
-
-cc_binary {
-    name: "keystore_cli",
-    defaults: ["keystore_defaults"],
-
-    srcs: ["keystore_cli.cpp"],
-    shared_libs: [
-        "android.hardware.keymaster@4.0",
-        "libbinder",
-        "libcrypto",
-        "libcutils",
-        "libhidlbase",
-        "libkeystore_aidl", // for IKeyStoreService.asInterface()
-        "libkeystore_binder",
-        "libkeystore_parcelables",
-        "liblog",
-        "libutils",
-    ],
-}
-
-cc_binary {
     name: "keystore_cli_v2",
     defaults: ["keystore_defaults"],
 
@@ -133,95 +42,25 @@
         "-DKEYMASTER_NAME_TAGS",
         "-Wno-unused-parameter",
     ],
-    srcs: ["keystore_cli_v2.cpp"],
+    srcs: [
+        "keystore_cli_v2.cpp",
+        "keystore_client.proto",
+    ],
     shared_libs: [
-        "android.hardware.confirmationui@1.0",
+        "android.security.apc-ndk_platform",
+        "android.system.keystore2-V1-ndk_platform",
         "libbinder",
-        "android.hardware.keymaster@4.0",
+        "libbinder_ndk",
         "libchrome",
+        "libcrypto",
+        "libkeymint_support",
+        "libprotobuf-cpp-lite",
         "libutils",
-        "libhidlbase",
-        "libkeymaster4support",
-        "libkeystore_aidl",
-        "libkeystore_binder",
-        "libkeystore_parcelables",
     ],
 
     local_include_dirs: ["include"],
 }
 
-cc_library_shared {
-    name: "libkeystore_parcelables",
-    defaults: ["keystore_defaults"],
-    export_include_dirs: ["include"],
-    srcs: [
-        "KeymasterArguments.cpp",
-        "keystore_aidl_hidl_marshalling_utils.cpp",
-        "KeystoreResponse.cpp",
-        "OperationResult.cpp",
-    ],
-    shared_libs: [
-        "android.hardware.keymaster@4.0",
-        "android.hardware.keymaster@4.1",
-        "libbinder",
-        "libhardware",
-        "libhidlbase",
-        "libkeymaster4support",
-        "libkeymaster4_1support",
-        "liblog",
-        "libprotobuf-cpp-lite",
-        "libutils",
-        "libkeystore-attestation-application-id",
-    ],
-    export_shared_lib_headers: [
-        "android.hardware.keymaster@4.0",
-        "android.hardware.keymaster@4.1",
-        "libbinder",
-        "libhidlbase",
-        "libkeymaster4_1support",
-    ],
-}
-// Library for keystore clients
-cc_library_shared {
-    name: "libkeystore_binder",
-    defaults: ["keystore_defaults"],
-
-    srcs: [
-        "keyblob_utils.cpp",
-        "keystore_client.proto",
-        "keystore_client_impl.cpp",
-        "keystore_get.cpp",
-    ],
-    shared_libs: [
-        "android.hardware.keymaster@4.0",
-        "libbinder",
-        "libhidlbase",
-        "libkeymaster4support",
-        "libkeystore_aidl",
-        "libkeystore_parcelables",
-        "liblog",
-        "libprotobuf-cpp-lite",
-        "libutils",
-    ],
-
-    proto: {
-        type: "lite",
-        export_proto_headers: true,
-    },
-    aidl: {
-        export_aidl_headers: true,
-        include_dirs: ["frameworks/base/core/java/"],
-    },
-    export_include_dirs: ["include"],
-    export_shared_lib_headers: [
-        "android.hardware.keymaster@4.0",
-        "libbinder",
-        "libhidlbase",
-        "libkeystore_aidl",
-        "libkeystore_parcelables",
-    ],
-}
-
 // Library used by both keystore and credstore for generating the ASN.1 stored
 // in Tag::ATTESTATION_APPLICATION_ID
 cc_library_shared {
@@ -265,77 +104,3 @@
 
     vendor: true,
 }
-
-// Library for unit tests
-cc_library_static {
-    name: "libkeystore_test",
-    defaults: ["keystore_defaults"],
-
-    srcs: [
-        "auth_token_table.cpp",
-        "blob.cpp",
-    ],
-    cflags: [ "-O0", ],
-    static_libs: ["libgtest_main"],
-    shared_libs: [
-        "android.hardware.keymaster@4.0",
-        "libbinder",
-        "libcrypto",
-        "libhidlbase",
-        "libkeymaster4support",
-        "libkeystore-attestation-application-id",
-        "libutils",
-        "libkeystore_aidl",
-        "libkeystore_parcelables",
-    ],
-    export_shared_lib_headers: [
-        "android.hardware.keymaster@4.0",
-        "libhidlbase",
-        "libkeymaster4support",
-    ],
-
-    aidl: {
-        include_dirs: ["frameworks/base/core/java/"],
-    },
-    export_include_dirs: ["include"],
-}
-
-filegroup {
-    name: "keystore_aidl",
-    srcs: [
-        "binder/android/security/IConfirmationPromptCallback.aidl",
-        "binder/android/security/keystore/ICredstoreTokenCallback.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 {
-    name: "libkeystore_aidl",
-    srcs: [":keystore_aidl"],
-    aidl: {
-        export_aidl_headers: true,
-        include_dirs: [
-            "system/security/keystore/binder",
-        ],
-    },
-    shared_libs: [
-        "libbinder",
-        "libcutils",
-        "libhardware",
-        "libhidlbase",
-        "libkeystore_parcelables",
-        "liblog",
-        "libselinux",
-        "libutils",
-    ],
-    export_shared_lib_headers: [
-        "libbinder",
-        "libkeystore_parcelables",
-    ],
-}
diff --git a/keystore/KeyStore.cpp b/keystore/KeyStore.cpp
deleted file mode 100644
index 1f80899..0000000
--- a/keystore/KeyStore.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Copyright (C) 2016 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 "keystore"
-
-#include "KeyStore.h"
-
-#include <dirent.h>
-#include <fcntl.h>
-
-#include <openssl/bio.h>
-
-#include <utils/String16.h>
-#include <utils/String8.h>
-
-#include <android-base/scopeguard.h>
-#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <android/security/keystore/IKeystoreService.h>
-#include <log/log_event_list.h>
-
-#include <private/android_logger.h>
-
-#include "keystore_utils.h"
-#include "permissions.h"
-#include <keystore/keystore_hidl_support.h>
-
-#include "keymaster_worker.h"
-
-namespace keystore {
-
-const char* KeyStore::kOldMasterKey = ".masterkey";
-const char* KeyStore::kMetaDataFile = ".metadata";
-
-const android::String16 KeyStore::kRsaKeyType("RSA");
-const android::String16 KeyStore::kEcKeyType("EC");
-
-using android::String8;
-
-KeyStore::KeyStore(const KeymasterDevices& kmDevices,
-                   SecurityLevel minimalAllowedSecurityLevelForNewKeys)
-    : 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, SecurityLevel(i));
-        }
-    }
-}
-
-KeyStore::~KeyStore() {
-}
-
-ResponseCode KeyStore::initialize() {
-    readMetaData();
-    if (upgradeKeystore()) {
-        writeMetaData();
-    }
-
-    return ResponseCode::NO_ERROR;
-}
-
-ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
-    auto userState = mUserStateDB.getUserState(userId);
-    return userState->initialize(pw);
-}
-
-ResponseCode KeyStore::copyMasterKey(uid_t srcUser, uid_t dstUser) {
-    auto userState = mUserStateDB.getUserState(dstUser);
-    auto initState = mUserStateDB.getUserState(srcUser);
-    return userState->copyMasterKey(&initState);
-}
-
-ResponseCode KeyStore::writeMasterKey(const android::String8& pw, uid_t userId) {
-    auto userState = mUserStateDB.getUserState(userId);
-    return userState->writeMasterKey(pw);
-}
-
-ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) {
-    auto userState = mUserStateDB.getUserState(userId);
-    return userState->readMasterKey(pw);
-}
-
-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;
-}
-
-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) {
-        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);
-    if (grant) {
-        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;
-
-    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 (LockedKeyBlobEntry& lockedEntry : matches) {
-        bool shouldDelete = true;
-
-        if (keepUnenryptedEntries) {
-            Blob blob;
-            Blob charBlob;
-            ResponseCode rc;
-
-            std::tie(rc, blob, charBlob) = lockedEntry.readBlobs(encryptionKey, state);
-
-            switch (rc) {
-            case ResponseCode::SYSTEM_ERROR:
-            case ResponseCode::VALUE_CORRUPTED:
-                // If we can't read blobs, delete them.
-                shouldDelete = true;
-                break;
-
-            case ResponseCode::NO_ERROR:
-            case ResponseCode::LOCKED:
-                // Delete encrypted blobs but keep unencrypted blobs and super-encrypted blobs.  We
-                // need to keep super-encrypted blobs so we can report that the user is
-                // unauthenticated if a caller tries to use them, rather than reporting that they
-                // don't exist.
-                shouldDelete = blob.isEncrypted();
-                break;
-
-            default:
-                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(lockedEntry);
-        }
-    }
-
-    userState = mUserStateDB.getUserState(userId);
-    if (!userState->deleteMasterKey()) {
-        ALOGE("Failed to delete user %d's master key", userId);
-    }
-    if (!keepUnenryptedEntries) {
-        if (!userState->reset()) {
-            ALOGE("Failed to remove user %d's directory", userId);
-        }
-    }
-}
-
-bool KeyStore::isEmpty(uid_t userId) const {
-    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;
-        }
-        userDirName = userState->getUserDirName();
-    }
-
-    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) {
-    auto userState = mUserStateDB.getUserState(userId);
-    userState->zeroizeMasterKeysInMemory();
-    userState->setState(STATE_LOCKED);
-}
-
-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());
-}
-
-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(blobfile, type);
-        }
-    });
-
-    result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState());
-    if (rc != ResponseCode::NO_ERROR) {
-        return result;
-    }
-
-    // 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(&keyBlob, version)) {
-            if ((rc = this->put(blobfile, keyBlob, {})) != ResponseCode::NO_ERROR ||
-                (result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState()),
-                 rc) != ResponseCode::NO_ERROR) {
-                return result;
-            }
-        }
-    }
-
-    return result;
-}
-
-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());
-}
-
-ResponseCode KeyStore::del(const LockedKeyBlobEntry& blobfile) {
-    Blob keyBlob;
-    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_KEYMASTER_10) {
-        dev->deleteKey(blob2hidlVec(keyBlob), [dev, alias, uid](Return<ErrorCode> rc) {
-            auto ret = KS_HANDLE_HIDL_ERROR(dev, 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;
-            }
-            if (!success) {
-                LOG(ERROR) << "Keymaster delete for key " << alias << " of uid " << uid
-                           << " failed";
-            }
-        });
-    }
-
-    return result;
-}
-
-std::string KeyStore::addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid) {
-    return mGrants.put(granteeUid, blobfile);
-}
-
-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);
-}
-
-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
-    if (getDevice(SecurityLevel::STRONGBOX)) return true;
-    if (!getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)) {
-        ALOGW("can't get keymaster device");
-        return false;
-    }
-
-    auto version = getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)->halVersion();
-    if (keyType == kRsaKeyType) return true;  // All versions support RSA
-    return keyType == kEcKeyType && version.supportsEc;
-}
-
-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;
-
-    lockedEntry = getLockedBlobEntryIfExists(keyName.string(), uid);
-
-    if (!lockedEntry) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
-
-    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);
-    }
-    return result;
-}
-
-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) {
-        ALOGE("Failed to upgrade key blob. Ancient blob version 0 is no longer supported");
-
-        return false;
-    }
-
-    /* From V1 -> V2: All old keys were encrypted */
-    if (version == 1) {
-        ALOGV("upgrading to version 2");
-
-        blob->setEncrypted(true);
-        version = 2;
-        updated = true;
-    }
-
-    /*
-     * If we've updated, set the key blob to the right version
-     * and write it.
-     */
-    if (updated) {
-        blob->setVersion(version);
-    }
-
-    return updated;
-}
-
-void KeyStore::readMetaData() {
-    int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
-    if (in < 0) {
-        return;
-    }
-    size_t fileLength = readFully(in, (uint8_t*)&mMetaData, sizeof(mMetaData));
-    if (fileLength != sizeof(mMetaData)) {
-        ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, sizeof(mMetaData));
-    }
-    close(in);
-}
-
-void KeyStore::writeMetaData() {
-    const char* tmpFileName = ".metadata.tmp";
-    int out =
-        TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
-    if (out < 0) {
-        ALOGE("couldn't write metadata file: %s", strerror(errno));
-        return;
-    }
-    size_t fileLength = writeFully(out, (uint8_t*)&mMetaData, sizeof(mMetaData));
-    if (fileLength != sizeof(mMetaData)) {
-        ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
-              sizeof(mMetaData));
-    }
-    close(out);
-    rename(tmpFileName, kMetaDataFile);
-}
-
-bool KeyStore::upgradeKeystore() {
-    bool upgraded = false;
-
-    if (mMetaData.version == 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().c_str()) < 0) {
-                ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
-                return false;
-            }
-        }
-
-        // Initialize again in case we had a key.
-        userState->initialize();
-
-        // Try to migrate existing keys.
-        DIR* dir = opendir(".");
-        if (!dir) {
-            // Give up now; maybe we can upgrade later.
-            ALOGE("couldn't open keystore's directory; something is wrong");
-            return false;
-        }
-
-        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;
-            }
-
-            // Find the current file's user.
-            char* end;
-            unsigned long thisUid = strtoul(file->d_name, &end, 10);
-            if (end[0] != '_' || end[1] == 0) {
-                continue;
-            }
-            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().c_str());
-            if (otherdir == nullptr) {
-                ALOGW("couldn't open user directory for rename");
-                continue;
-            }
-            if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
-                ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
-            }
-            closedir(otherdir);
-        }
-        closedir(dir);
-
-        mMetaData.version = 1;
-        upgraded = true;
-    }
-
-    return upgraded;
-}
-
-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
deleted file mode 100644
index 7841a80..0000000
--- a/keystore/KeyStore.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2016 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_KEYSTORE_H_
-#define KEYSTORE_KEYSTORE_H_
-
-#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <keymasterV4_1/Keymaster.h>
-#include <utils/Vector.h>
-
-#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;
-
-template <typename T, size_t count> class Devices : public std::array<T, count> {
-  public:
-    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];
-    }
-};
-
-}  // namespace keystore
-
-namespace std {
-template <typename T, size_t N> struct tuple_size<keystore::Devices<T, N>> {
-  public:
-    static constexpr size_t value = std::tuple_size<std::array<T, N>>::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();
-
-    std::shared_ptr<KeymasterWorker> getDevice(SecurityLevel securityLevel) const {
-        return mKmDevices[securityLevel];
-    }
-
-    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) {
-            return mKmDevices[SecurityLevel::SOFTWARE];
-        } else {
-            return nullptr;
-        }
-    }
-
-    std::shared_ptr<KeymasterWorker> getDevice(const Blob& blob) {
-        return mKmDevices[blob.getSecurityLevel()];
-    }
-
-    ResponseCode initialize();
-
-    State getState(uid_t userId) { return mUserStateDB.getUserState(userId)->getState(); }
-
-    ResponseCode initializeUser(const android::String8& pw, uid_t userId);
-
-    ResponseCode copyMasterKey(uid_t srcUser, uid_t dstUser);
-    ResponseCode writeMasterKey(const android::String8& pw, uid_t userId);
-    ResponseCode readMasterKey(const android::String8& pw, uid_t userId);
-
-    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
-     * be removed.
-     */
-    void resetUser(uid_t userId, bool keepUnenryptedEntries);
-    bool isEmpty(uid_t userId) const;
-
-    void lock(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 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 LockedKeyBlobEntry& blobfile,
-                           uid_t userId, int32_t flags);
-
-    bool isHardwareBacked(const android::String16& keyType) const;
-
-    std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry>
-    getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type);
-
-    void binderDied(const ::android::wp<IBinder>& who) override;
-
-    UserStateDB& getUserStateDB() { return mUserStateDB; }
-    AuthTokenTable& getAuthTokenTable() { return mAuthTokenTable; }
-    KeystoreKeymasterEnforcement& getEnforcementPolicy() { return mEnforcementPolicy; }
-    ConfirmationManager& getConfirmationManager() { return *mConfirmationManager; }
-
-    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);
-    }
-
-  private:
-    static const char* kOldMasterKey;
-    static const char* kMetaDataFile;
-    static const android::String16 kRsaKeyType;
-    static const android::String16 kEcKeyType;
-
-    KeymasterWorkers mKmDevices;
-
-    bool mAllowNewFallback;
-
-    UserStateDB mUserStateDB;
-    AuthTokenTable mAuthTokenTable;
-    KeystoreKeymasterEnforcement mEnforcementPolicy;
-    sp<ConfirmationManager> mConfirmationManager;
-
-    ::keystore::GrantStore mGrants;
-
-    typedef struct { uint32_t version; } keystore_metadata_t;
-
-    keystore_metadata_t mMetaData;
-
-    /**
-     * Upgrade the key from the current version to whatever is newest.
-     */
-    bool upgradeBlob(Blob* blob, const uint8_t oldVersion);
-
-    void readMetaData();
-    void writeMetaData();
-
-    bool upgradeKeystore();
-
-    std::mutex operationDeviceMapMutex_;
-    std::map<sp<IBinder>, std::shared_ptr<KeymasterWorker>> operationDeviceMap_;
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_KEYSTORE_H_
diff --git a/keystore/KeymasterArguments.cpp b/keystore/KeymasterArguments.cpp
deleted file mode 100644
index 60b86cc..0000000
--- a/keystore/KeymasterArguments.cpp
+++ /dev/null
@@ -1,45 +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/KeymasterArguments.h"
-#include "keystore_aidl_hidl_marshalling_utils.h"
-
-#include <binder/Parcel.h>
-
-namespace android {
-namespace security {
-namespace keymaster {
-
-using ::android::status_t;
-status_t KeymasterArguments::readFromParcel(const android::Parcel* in) {
-    data_ = keystore::readParamSetFromParcel(*in);
-    return OK;
-};
-
-status_t KeymasterArguments::writeToParcel(android::Parcel* out) const {
-    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) {}
-
-}  // namespace keymaster
-}  // namespace security
-}  // namespace android
diff --git a/keystore/KeystoreResponse.cpp b/keystore/KeystoreResponse.cpp
deleted file mode 100644
index c46973a..0000000
--- a/keystore/KeystoreResponse.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-**
-** 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
deleted file mode 100644
index dec4d40..0000000
--- a/keystore/OperationResult.cpp
+++ /dev/null
@@ -1,66 +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/OperationResult.h"
-
-#include <utility>
-
-#include <binder/Parcel.h>
-
-#include <keystore/keymaster_types.h>
-
-#include "keystore_aidl_hidl_marshalling_utils.h"
-
-namespace android {
-namespace security {
-namespace keymaster {
-
-using ::android::status_t;
-using ::keystore::ErrorCode;
-
-OperationResult::OperationResult() : resultCode(), token(), handle(0), inputConsumed(0), data() {}
-
-status_t OperationResult::readFromParcel(const Parcel* inn) {
-    const Parcel& in = *inn;
-    resultCode = ErrorCode(in.readInt32());
-    token = in.readStrongBinder();
-    handle = static_cast<uint64_t>(in.readInt64());
-    inputConsumed = in.readInt32();
-    data = keystore::readKeymasterBlob(in);
-    outParams = keystore::readParamSetFromParcel(in);
-    return OK;
-}
-
-status_t OperationResult::writeToParcel(Parcel* out) const {
-    out->writeInt32(resultCode.getErrorCode());
-    out->writeStrongBinder(token);
-    out->writeInt64(handle);
-    out->writeInt32(inputConsumed);
-    keystore::writeKeymasterBlob(data, out);
-    keystore::writeParamSetToParcel(outParams, out);
-    return OK;
-}
-
-OperationResult operationFailed(const ::keystore::KeyStoreServiceReturnCode& error) {
-    OperationResult opResult = {};
-    opResult.resultCode = error;
-    return opResult;
-}
-
-}  // namespace keymaster
-}  // namespace security
-}  // namespace android
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
deleted file mode 100644
index 971f9ef..0000000
--- a/keystore/auth_token_table.cpp
+++ /dev/null
@@ -1,302 +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.
- */
-
-#define LOG_TAG "keystore"
-
-#include "auth_token_table.h"
-
-#include <assert.h>
-#include <time.h>
-
-#include <algorithm>
-
-#include <log/log.h>
-
-namespace keystore {
-
-template <typename IntType, uint32_t byteOrder> struct choose_hton;
-
-template <typename IntType> struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> {
-    inline static IntType hton(const IntType& value) {
-        IntType result = 0;
-        const unsigned char* inbytes = reinterpret_cast<const unsigned char*>(&value);
-        unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result);
-        for (int i = sizeof(IntType) - 1; i >= 0; --i) {
-            *(outbytes++) = inbytes[i];
-        }
-        return result;
-    }
-};
-
-template <typename IntType> struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> {
-    inline static IntType hton(const IntType& value) { return value; }
-};
-
-template <typename IntType> inline IntType hton(const IntType& value) {
-    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
-}
-
-template <typename IntType> inline IntType ntoh(const IntType& value) {
-    // same operation and hton
-    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
-}
-
-//
-// Some trivial template wrappers around std algorithms, so they take containers not ranges.
-//
-template <typename Container, typename Predicate>
-typename Container::iterator find_if(Container& container, Predicate pred) {
-    return std::find_if(container.begin(), container.end(), pred);
-}
-
-template <typename Container, typename Predicate>
-typename Container::iterator remove_if(Container& container, Predicate pred) {
-    return std::remove_if(container.begin(), container.end(), pred);
-}
-
-template <typename Container> typename Container::iterator min_element(Container& container) {
-    return std::min_element(container.begin(), container.end());
-}
-
-time_t clock_gettime_raw() {
-    struct timespec time;
-    clock_gettime(CLOCK_MONOTONIC_RAW, &time);
-    return time.tv_sec;
-}
-
-void AuthTokenTable::AddAuthenticationToken(HardwareAuthToken&& auth_token) {
-    Entry new_entry(std::move(auth_token), clock_function_());
-    // STOPSHIP: debug only, to be removed
-    ALOGD("AddAuthenticationToken: timestamp = %llu, time_received = %lld",
-          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");
-        *min_element(entries_) = std::move(new_entry);
-    } else {
-        entries_.push_back(std::move(new_entry));
-    }
-}
-
-inline bool is_secret_key_operation(Algorithm algorithm, KeyPurpose purpose) {
-    if ((algorithm != Algorithm::RSA && algorithm != Algorithm::EC)) return true;
-    if (purpose == KeyPurpose::SIGN || purpose == KeyPurpose::DECRYPT) return true;
-    return false;
-}
-
-inline bool KeyRequiresAuthentication(const AuthorizationSet& key_info, KeyPurpose purpose) {
-    auto algorithm = defaultOr(key_info.GetTagValue(TAG_ALGORITHM), Algorithm::AES);
-    return is_secret_key_operation(algorithm, purpose) &&
-           key_info.find(Tag::NO_AUTH_REQUIRED) == -1;
-}
-
-inline bool KeyRequiresAuthPerOperation(const AuthorizationSet& key_info, KeyPurpose purpose) {
-    auto algorithm = defaultOr(key_info.GetTagValue(TAG_ALGORITHM), Algorithm::AES);
-    return is_secret_key_operation(algorithm, purpose) && key_info.find(Tag::AUTH_TIMEOUT) == -1;
-}
-
-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);
-
-    std::vector<uint64_t> key_sids;
-    ExtractSids(key_info, &key_sids);
-
-    if (KeyRequiresAuthPerOperation(key_info, purpose))
-        return FindAuthPerOpAuthorization(key_sids, auth_type, op_handle);
-    else
-        return FindTimedAuthorization(key_sids, auth_type, key_info);
-}
-
-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->SatisfiesAuth(sids, auth_type)) return {AUTH_TOKEN_WRONG_SID, {}};
-
-    return {OK, matching_op->token()};
-}
-
-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, {}};
-
-    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, {}};
-
-    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, {}};
-        }
-    }
-
-    newest_match->UpdateLastUse(now);
-    return {OK, newest_match->token()};
-}
-
-std::tuple<AuthTokenTable::Error, HardwareAuthToken>
-AuthTokenTable::FindAuthorizationForCredstore(uint64_t challenge, uint64_t secureUserId,
-                                              int64_t authTokenMaxAgeMillis) {
-    std::vector<uint64_t> sids = {secureUserId};
-    HardwareAuthenticatorType auth_type = HardwareAuthenticatorType::ANY;
-    time_t now = clock_function_();
-    int64_t nowMillis = now * 1000;
-
-    // It's an error to call this without a non-zero challenge.
-    if (challenge == 0) {
-        return {OP_HANDLE_REQUIRED, {}};
-    }
-
-    // First see if we can find a token which matches the given challenge. If we
-    // can, return the newest one. We specifically don't care about its age.
-    //
-    Entry* newest_match_for_challenge = nullptr;
-    for (auto& entry : entries_) {
-        if (entry.token().challenge == challenge && !entry.completed() &&
-            entry.SatisfiesAuth(sids, auth_type)) {
-            if (newest_match_for_challenge == nullptr ||
-                entry.is_newer_than(newest_match_for_challenge)) {
-                newest_match_for_challenge = &entry;
-            }
-        }
-    }
-    if (newest_match_for_challenge != nullptr) {
-        newest_match_for_challenge->UpdateLastUse(now);
-        return {OK, newest_match_for_challenge->token()};
-    }
-
-    // If that didn't work, we'll take the most recent token within the specified
-    // deadline, if any. Of course if the deadline is zero it doesn't make sense
-    // to look at all.
-    if (authTokenMaxAgeMillis == 0) {
-        return {AUTH_TOKEN_NOT_FOUND, {}};
-    }
-
-    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 == nullptr) {
-        return {AUTH_TOKEN_NOT_FOUND, {}};
-    }
-
-    int64_t tokenAgeMillis = nowMillis - newest_match->time_received() * 1000;
-    if (tokenAgeMillis >= authTokenMaxAgeMillis) {
-        return {AUTH_TOKEN_EXPIRED, {}};
-    }
-
-    newest_match->UpdateLastUse(now);
-    return {OK, newest_match->token()};
-}
-
-void AuthTokenTable::ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids) {
-    assert(sids);
-    for (auto& param : key_info)
-        if (param.tag == Tag::USER_SECURE_ID)
-            sids->push_back(authorizationValue(TAG_USER_SECURE_ID, param).value());
-}
-
-void AuthTokenTable::RemoveEntriesSupersededBy(const Entry& entry) {
-    entries_.erase(remove_if(entries_, [&](Entry& e) { return entry.Supersedes(e); }),
-                   entries_.end());
-}
-
-void AuthTokenTable::onDeviceOffBody() {
-    last_off_body_ = clock_function_();
-}
-
-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;
-
-    assert(!IsSupersededBySomeEntry(*found));
-    found->mark_completed();
-
-    if (IsSupersededBySomeEntry(*found)) entries_.erase(found);
-}
-
-AuthTokenTable::Entry::Entry(HardwareAuthToken&& token, time_t current_time)
-    : token_(std::move(token)), time_received_(current_time), last_use_(current_time),
-      operation_completed_(token_.challenge == 0) {}
-
-bool AuthTokenTable::Entry::SatisfiesAuth(const std::vector<uint64_t>& sids,
-                                          HardwareAuthenticatorType auth_type) {
-    for (auto sid : sids) {
-        if (SatisfiesAuth(sid, auth_type)) return true;
-    }
-    return false;
-}
-
-void AuthTokenTable::Entry::UpdateLastUse(time_t time) {
-    this->last_use_ = time;
-}
-
-bool AuthTokenTable::Entry::Supersedes(const Entry& entry) const {
-    if (!entry.completed()) return false;
-
-    return (token_.userId == entry.token_.userId &&
-            token_.authenticatorType == entry.token_.authenticatorType &&
-            token_.authenticatorId == entry.token_.authenticatorId && is_newer_than(&entry));
-}
-
-}  // namespace keystore
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
deleted file mode 100644
index 787b9b1..0000000
--- a/keystore/auth_token_table.h
+++ /dev/null
@@ -1,177 +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.
- */
-
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <keystore/keymaster_types.h>
-
-#ifndef KEYSTORE_AUTH_TOKEN_TABLE_H_
-#define KEYSTORE_AUTH_TOKEN_TABLE_H_
-
-namespace keystore {
-
-namespace test {
-class AuthTokenTableTest;
-}  // namespace test
-
-time_t clock_gettime_raw();
-
-/**
- * AuthTokenTable manages a set of received authorization tokens and can provide the appropriate
- * token for authorizing a key operation.
- *
- * To keep the table from growing without bound, superseded entries are removed when possible, and
- * least recently used entries are automatically pruned when when the table exceeds a size limit,
- * which is expected to be relatively small, since the implementation uses a linear search.
- */
-class AuthTokenTable {
-  public:
-    explicit AuthTokenTable(size_t max_entries = 32, time_t (*clock_function)() = clock_gettime_raw)
-        : max_entries_(max_entries), last_off_body_(clock_function()),
-          clock_function_(clock_function) {}
-
-    enum Error {
-        OK,
-        AUTH_NOT_REQUIRED = -1,
-        AUTH_TOKEN_EXPIRED = -2,    // Found a matching token, but it's too old.
-        AUTH_TOKEN_WRONG_SID = -3,  // Found a token with the right challenge, but wrong SID.  This
-                                    // most likely indicates that the authenticator was updated
-                                    // (e.g. new fingerprint enrolled).
-        OP_HANDLE_REQUIRED = -4,    // The key requires auth per use but op_handle was zero.
-        AUTH_TOKEN_NOT_FOUND = -5,
-    };
-
-    /**
-     * Add an authorization token to the table.
-     */
-    void AddAuthenticationToken(HardwareAuthToken&& auth_token);
-
-    /**
-     * Find an authorization token that authorizes the operation specified by \p operation_handle on
-     * a key with the characteristics specified in \p key_info.
-     *
-     * This method is O(n * m), where n is the number of KM_TAG_USER_SECURE_ID entries in key_info
-     * and m is the number of entries in the table.  It could be made better, but n and m should
-     * always be small.
-     *
-     * The table retains ownership of the returned object.
-     */
-    std::tuple<Error, HardwareAuthToken> FindAuthorization(const AuthorizationSet& key_info,
-                                                           KeyPurpose purpose, uint64_t op_handle);
-
-    std::tuple<Error, HardwareAuthToken>
-    FindAuthorizationForCredstore(uint64_t challenge, uint64_t secureUserId,
-                                  int64_t authTokenMaxAgeMillis);
-
-    /**
-     * Mark operation completed.  This allows tokens associated with the specified operation to be
-     * superseded by new tokens.
-     */
-    void MarkCompleted(const uint64_t op_handle);
-
-    /**
-     * Update the last_off_body_ timestamp so that tokens which remain authorized only so long as
-     * the device stays on body can be revoked.
-     */
-    void onDeviceOffBody();
-
-    void Clear();
-
-    /**
-     * 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;
-
-    class Entry {
-      public:
-        Entry(HardwareAuthToken&& token, time_t current_time);
-        Entry(Entry&& entry) noexcept { *this = std::move(entry); }
-
-        void operator=(Entry&& rhs) noexcept {
-            token_ = std::move(rhs.token_);
-            time_received_ = rhs.time_received_;
-            last_use_ = rhs.last_use_;
-            operation_completed_ = rhs.operation_completed_;
-        }
-
-        bool operator<(const Entry& rhs) const { return last_use_ < rhs.last_use_; }
-
-        void UpdateLastUse(time_t time);
-
-        bool Supersedes(const Entry& entry) const;
-        bool SatisfiesAuth(const std::vector<uint64_t>& sids, HardwareAuthenticatorType auth_type);
-
-        bool is_newer_than(const Entry* entry) const {
-            if (!entry) return true;
-            uint64_t ts = token_.timestamp;
-            uint64_t other_ts = entry->token_.timestamp;
-            // Normally comparing timestamp_host_order alone is sufficient, but here is an
-            // additional hack to compare time_received value for some devices where their auth
-            // tokens contain fixed timestamp (due to the a stuck secure RTC on them)
-            return (ts > other_ts) ||
-                   ((ts == other_ts) && (time_received_ > entry->time_received_));
-        }
-
-        void mark_completed() { operation_completed_ = true; }
-
-        const HardwareAuthToken& token() const & { return token_; }
-        time_t time_received() const { return time_received_; }
-        bool completed() const { return operation_completed_; }
-
-      private:
-        bool SatisfiesAuth(uint64_t sid, HardwareAuthenticatorType auth_type) const {
-            return (sid == token_.userId || sid == token_.authenticatorId) &&
-                   (auth_type & token_.authenticatorType) != 0;
-        }
-
-        HardwareAuthToken token_;
-        time_t time_received_;
-        time_t last_use_;
-        bool operation_completed_;
-    };
-
-    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_;
-    time_t (*clock_function_)();
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_AUTH_TOKEN_TABLE_H_
diff --git a/keystore/binder/android/security/IConfirmationPromptCallback.aidl b/keystore/binder/android/security/IConfirmationPromptCallback.aidl
deleted file mode 100644
index 96a1a04..0000000
--- a/keystore/binder/android/security/IConfirmationPromptCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 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.
- */
-
-package android.security;
-
-/**
- * This must be kept manually in sync with system/security/keystore until AIDL
- * can generate both Java and C++ bindings.
- *
- * @hide
- */
-interface IConfirmationPromptCallback {
-    oneway void onConfirmationPromptCompleted(in int result, in byte[] dataThatWasConfirmed);
-}
diff --git a/keystore/binder/android/security/keymaster/ExportResult.aidl b/keystore/binder/android/security/keymaster/ExportResult.aidl
deleted file mode 100644
index 1748653..0000000
--- a/keystore/binder/android/security/keymaster/ExportResult.aidl
+++ /dev/null
@@ -1,20 +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.keymaster;
-
-/* @hide */
-parcelable ExportResult cpp_header "keystore/ExportResult.h";
diff --git a/keystore/binder/android/security/keymaster/KeyCharacteristics.aidl b/keystore/binder/android/security/keymaster/KeyCharacteristics.aidl
deleted file mode 100644
index 32e75ad..0000000
--- a/keystore/binder/android/security/keymaster/KeyCharacteristics.aidl
+++ /dev/null
@@ -1,20 +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.keymaster;
-
-/* @hide */
-parcelable KeyCharacteristics cpp_header "keystore/KeyCharacteristics.h";
diff --git a/keystore/binder/android/security/keymaster/KeymasterArguments.aidl b/keystore/binder/android/security/keymaster/KeymasterArguments.aidl
deleted file mode 100644
index 44d9f09..0000000
--- a/keystore/binder/android/security/keymaster/KeymasterArguments.aidl
+++ /dev/null
@@ -1,20 +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.keymaster;
-
-/* @hide */
-parcelable KeymasterArguments cpp_header "keystore/KeymasterArguments.h";
diff --git a/keystore/binder/android/security/keymaster/KeymasterBlob.aidl b/keystore/binder/android/security/keymaster/KeymasterBlob.aidl
deleted file mode 100644
index 5c5db9e..0000000
--- a/keystore/binder/android/security/keymaster/KeymasterBlob.aidl
+++ /dev/null
@@ -1,20 +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.keymaster;
-
-/* @hide */
-parcelable KeymasterBlob cpp_header "keystore/KeymasterBlob.h";
diff --git a/keystore/binder/android/security/keymaster/KeymasterCertificateChain.aidl b/keystore/binder/android/security/keymaster/KeymasterCertificateChain.aidl
deleted file mode 100644
index ddb5cae..0000000
--- a/keystore/binder/android/security/keymaster/KeymasterCertificateChain.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2016 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.keymaster;
-
-/* @hide */
-parcelable KeymasterCertificateChain cpp_header "keystore/KeymasterCertificateChain.h";
diff --git a/keystore/binder/android/security/keymaster/OperationResult.aidl b/keystore/binder/android/security/keymaster/OperationResult.aidl
deleted file mode 100644
index db689d4..0000000
--- a/keystore/binder/android/security/keymaster/OperationResult.aidl
+++ /dev/null
@@ -1,20 +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.keymaster;
-
-/* @hide */
-parcelable OperationResult cpp_header "keystore/OperationResult.h";
diff --git a/keystore/binder/android/security/keystore/ICredstoreTokenCallback.aidl b/keystore/binder/android/security/keystore/ICredstoreTokenCallback.aidl
deleted file mode 100644
index b42e3d4..0000000
--- a/keystore/binder/android/security/keystore/ICredstoreTokenCallback.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright (c) 2020, 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;
-
-
-/**
- * @hide
- */
-oneway interface ICredstoreTokenCallback {
-	void onFinished(boolean success, in byte[] authToken, in byte[] verificationToken);
-}
diff --git a/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl
deleted file mode 100644
index dca928d..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * 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.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/keystore/IKeystoreExportKeyCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
deleted file mode 100644
index e42e927..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * 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.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/keystore/IKeystoreKeyCharacteristicsCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
deleted file mode 100644
index e1f0ffe..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * 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.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/keystore/IKeystoreOperationResultCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
deleted file mode 100644
index f37b838..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * 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.keystore.KeystoreResponse;
-import android.security.keymaster.OperationResult;
-
-/**
- * @hide
- */
-@SensitiveData
-oneway interface IKeystoreOperationResultCallback {
-    void onFinished(in OperationResult result);
-}
diff --git a/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl
deleted file mode 100644
index 912e605..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * 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.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
deleted file mode 100644
index 3b9a1b4..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreService.aidl
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * 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.ICredstoreTokenCallback;
-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
- */
-@SensitiveData
-interface IKeystoreService {
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    int getState(int userId);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    byte[] get(String name, int uid);
-    @UnsupportedAppUsage
-    int insert(String name, in byte[] item, int uid, int flags);
-    @UnsupportedAppUsage
-    int del(String name, int uid);
-    @UnsupportedAppUsage
-    int exist(String name, int uid);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    String[] list(String namePrefix, int uid);
-    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);
-    @UnsupportedAppUsage
-    int ungrant(String name, int granteeUid);
-    long getmtime(String name, int uid);
-    @UnsupportedAppUsage
-    int is_hardware_backed(String string);
-    @UnsupportedAppUsage
-    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[] input, 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);
-
-    // This method looks through auth-tokens cached by keystore which match
-    // the passed-in |secureUserId|.
-    //
-    // If one or more of these tokens has a |challenge| field which matches
-    // the passed-in |challenge| parameter, the most recent is returned. In
-    // this case the |authTokenMaxAgeMillis| parameter is not used.
-    //
-    // Otherwise, the most recent auth-token of these tokens which is younger
-    // than |authTokenMaxAgeMillis| is returned.
-    //
-    // The passed in |challenge| parameter must always be non-zero.
-    //
-    // This method is called by credstore (and only credstore).
-    //
-    void getTokensForCredstore(in long challenge, in long secureUserId, in int authTokenMaxAgeMillis,
-                               in ICredstoreTokenCallback cb);
-}
diff --git a/keystore/binder/android/security/keystore/KeystoreResponse.aidl b/keystore/binder/android/security/keystore/KeystoreResponse.aidl
deleted file mode 100644
index 128b456..0000000
--- a/keystore/binder/android/security/keystore/KeystoreResponse.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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;
-
-/* @hide */
-parcelable KeystoreResponse cpp_header "keystore/KeystoreResponse.h";
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
deleted file mode 100644
index ffdb454..0000000
--- a/keystore/blob.cpp
+++ /dev/null
@@ -1,791 +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.
- */
-
-#define LOG_TAG "keystore"
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.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>
-#include <android-base/unique_fd.h>
-
-namespace {
-
-constexpr size_t kGcmIvSizeBytes = 96 / 8;
-
-#if defined(__clang__)
-#define OPTNONE __attribute__((optnone))
-#elif defined(__GNUC__)
-#define OPTNONE __attribute__((optimize("O0")))
-#else
-#error Need a definition for OPTNONE
-#endif
-
-class ArrayEraser {
-  public:
-    ArrayEraser(uint8_t* arr, size_t size) : mArr(arr), mSize(size) {}
-    OPTNONE ~ArrayEraser() { std::fill(mArr, mArr + mSize, 0); }
-
-  private:
-    volatile uint8_t* mArr;
-    size_t mSize;
-};
-
-/**
- * Returns a EVP_CIPHER appropriate for the given key, based on the key's size.
- */
-const EVP_CIPHER* getAesCipherForKey(const std::vector<uint8_t>& key) {
-    const EVP_CIPHER* cipher = EVP_aes_256_gcm();
-    if (key.size() == kAes128KeySizeBytes) {
-        cipher = EVP_aes_128_gcm();
-    }
-    return cipher;
-}
-
-/*
- * Encrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
- * 'iv' and write output to 'out' (which may be the same location as 'in') and 128-bit tag to
- * 'tag'.
- */
-ResponseCode AES_gcm_encrypt(const uint8_t* in, uint8_t* out, size_t len,
-                             const std::vector<uint8_t>& key, const uint8_t* iv, uint8_t* tag) {
-
-    // There can be 128-bit and 256-bit keys
-    const EVP_CIPHER* cipher = getAesCipherForKey(key);
-
-    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
-
-    EVP_EncryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key.data(), iv);
-    EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
-
-    std::unique_ptr<uint8_t[]> out_tmp(new uint8_t[len]);
-    uint8_t* out_pos = out_tmp.get();
-    int out_len;
-
-    EVP_EncryptUpdate(ctx.get(), out_pos, &out_len, in, len);
-    out_pos += out_len;
-    EVP_EncryptFinal_ex(ctx.get(), out_pos, &out_len);
-    out_pos += out_len;
-    if (out_pos - out_tmp.get() != static_cast<ssize_t>(len)) {
-        ALOGD("Encrypted ciphertext is the wrong size, expected %zu, got %zd", len,
-              out_pos - out_tmp.get());
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    std::copy(out_tmp.get(), out_pos, out);
-    EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kGcmTagLength, tag);
-
-    return ResponseCode::NO_ERROR;
-}
-
-/*
- * Decrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
- * 'iv', checking 128-bit tag at 'tag' and writing plaintext to 'out'(which may be the same
- * location as 'in').
- */
-ResponseCode AES_gcm_decrypt(const uint8_t* in, uint8_t* out, size_t len,
-                             const std::vector<uint8_t> key, const uint8_t* iv,
-                             const uint8_t* tag) {
-
-    // There can be 128-bit and 256-bit keys
-    const EVP_CIPHER* cipher = getAesCipherForKey(key);
-
-    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
-
-    EVP_DecryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key.data(), iv);
-    EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
-    EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kGcmTagLength, const_cast<uint8_t*>(tag));
-
-    std::unique_ptr<uint8_t[]> out_tmp(new uint8_t[len]);
-    ArrayEraser out_eraser(out_tmp.get(), len);
-    uint8_t* out_pos = out_tmp.get();
-    int out_len;
-
-    EVP_DecryptUpdate(ctx.get(), out_pos, &out_len, in, len);
-    out_pos += out_len;
-    if (!EVP_DecryptFinal_ex(ctx.get(), out_pos, &out_len)) {
-        ALOGE("Failed to decrypt blob; ciphertext or tag is likely corrupted");
-        return ResponseCode::VALUE_CORRUPTED;
-    }
-    out_pos += out_len;
-    if (out_pos - out_tmp.get() != static_cast<ssize_t>(len)) {
-        ALOGE("Encrypted plaintext is the wrong size, expected %zu, got %zd", len,
-              out_pos - out_tmp.get());
-        return ResponseCode::VALUE_CORRUPTED;
-    }
-
-    std::copy(out_tmp.get(), out_pos, out);
-
-    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) {
-    mBlob = std::make_unique<blobv3>();
-    memset(mBlob.get(), 0, sizeof(blobv3));
-    if (valueLength > kValueSize) {
-        valueLength = kValueSize;
-        ALOGW("Provided blob length too large");
-    }
-    if (infoLength + valueLength > kValueSize) {
-        infoLength = kValueSize - valueLength;
-        ALOGW("Provided info length too large");
-    }
-    mBlob->length = valueLength;
-    memcpy(mBlob->value, value, valueLength);
-
-    mBlob->info = infoLength;
-    memcpy(mBlob->value + valueLength, info, infoLength);
-
-    mBlob->version = CURRENT_BLOB_VERSION;
-    mBlob->type = uint8_t(type);
-
-    if (type == TYPE_MASTER_KEY || type == TYPE_MASTER_KEY_AES256) {
-        mBlob->flags = KEYSTORE_FLAG_ENCRYPTED;
-    } else {
-        mBlob->flags = KEYSTORE_FLAG_NONE;
-    }
-}
-
-Blob::Blob(blobv3 b) {
-    mBlob = std::make_unique<blobv3>(b);
-}
-
-Blob::Blob() {
-    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) {
-        return true;
-    }
-
-    return mBlob->flags & KEYSTORE_FLAG_ENCRYPTED;
-}
-
-bool Blob::isSuperEncrypted() const {
-    return mBlob->flags & KEYSTORE_FLAG_SUPER_ENCRYPTED;
-}
-
-bool Blob::isCriticalToDeviceEncryption() const {
-    return mBlob->flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
-}
-
-inline uint8_t setFlag(uint8_t flags, bool set, KeyStoreFlag flag) {
-    return set ? (flags | flag) : (flags & ~flag);
-}
-
-void Blob::setEncrypted(bool 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);
-}
-
-void Blob::setCriticalToDeviceEncryption(bool critical) {
-    mBlob->flags = setFlag(mBlob->flags, critical, KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
-}
-
-void Blob::setFallback(bool fallback) {
-    if (fallback) {
-        mBlob->flags |= KEYSTORE_FLAG_FALLBACK;
-    } else {
-        mBlob->flags &= ~KEYSTORE_FLAG_FALLBACK;
-    }
-}
-
-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 = rawBlob->length;
-    rawBlob->length = htonl(rawBlob->length);
-
-    if (blob.isEncrypted() || blob.isSuperEncrypted()) {
-        if (state != STATE_NO_ERROR) {
-            ALOGD("couldn't insert encrypted blob while not unlocked");
-            return ResponseCode::LOCKED;
-        }
-
-        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(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 + rawBlob->info;
-
-    char tmpFileName[] = ".tmpXXXXXX";
-    {
-        android::base::unique_fd out(TEMP_FAILURE_RETRY(mkstemp(tmpFileName)));
-        if (out < 0) {
-            LOG(ERROR) << "could not open temp file: " << tmpFileName
-                       << " for writing blob file: " << filename.c_str()
-                       << " because: " << strerror(errno);
-            return ResponseCode::SYSTEM_ERROR;
-        }
-
-        const size_t writtenBytes =
-            writeFully(out, reinterpret_cast<uint8_t*>(rawBlob), fileLength);
-
-        if (writtenBytes != fileLength) {
-            LOG(ERROR) << "blob not fully written " << writtenBytes << " != " << fileLength;
-            unlink(tmpFileName);
-            return ResponseCode::SYSTEM_ERROR;
-        }
-    }
-
-    if (rename(tmpFileName, filename.c_str()) == -1) {
-        LOG(ERROR) << "could not rename blob file to " << filename
-                   << " because: " << strerror(errno);
-        unlink(tmpFileName);
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    fsyncDirectory(getContainingDirectory(filename));
-
-    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*)rawBlob.get(), sizeof(blobv3));
-    if (close(in) != 0) {
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    if (fileLength == 0) {
-        LOG(ERROR) << __func__ << " VALUE_CORRUPTED file length == 0";
-        return ResponseCode::VALUE_CORRUPTED;
-    }
-
-    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)) {
-        LOG(ERROR) << __func__ << " VALUE_CORRUPTED blob file too short: " << fileLength;
-        return ResponseCode::VALUE_CORRUPTED;
-    }
-
-    if (rawBlob->version == 3) {
-        const ssize_t encryptedLength = ntohl(rawBlob->length);
-
-        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) {
-                // If the blob was superencrypted and decryption failed, it is
-                // almost certain that decryption is failing due to a user's
-                // changed master key.
-                if ((rawBlob->flags & KEYSTORE_FLAG_SUPER_ENCRYPTED) &&
-                    (rc == ResponseCode::VALUE_CORRUPTED)) {
-                    return ResponseCode::KEY_PERMANENTLY_INVALIDATED;
-                }
-                LOG(ERROR) << __func__ << " AES_gcm_decrypt returned: " << uint32_t(rc);
-
-                return rc;
-            }
-        }
-    } else if (rawBlob->version < 3) {
-        blobv2& v2blob = reinterpret_cast<blobv2&>(*rawBlob);
-        const size_t headerLength = offsetof(blobv2, encrypted);
-        const ssize_t encryptedLength = fileLength - headerLength - v2blob.info;
-        if (encryptedLength < 0) {
-            LOG(ERROR) << __func__ << " VALUE_CORRUPTED v2blob file too short";
-            return ResponseCode::VALUE_CORRUPTED;
-        }
-
-        if (rawBlobIsEncrypted(*rawBlob)) {
-            if (encryptedLength % AES_BLOCK_SIZE != 0) {
-                LOG(ERROR) << __func__
-                           << " VALUE_CORRUPTED encrypted length is not a multiple"
-                              " of the AES block size";
-                return ResponseCode::VALUE_CORRUPTED;
-            }
-
-            AES_KEY key;
-            AES_set_decrypt_key(aes_key.data(), kAesKeySize * 8, &key);
-            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(v2blob.digested, digestedLength, computedDigest);
-            if (memcmp(v2blob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
-                LOG(ERROR) << __func__ << " v2blob MD5 digest mismatch";
-                return ResponseCode::VALUE_CORRUPTED;
-            }
-        }
-    }
-
-    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))) {
-        LOG(ERROR) << __func__ << " raw blob length is out of bounds";
-        return ResponseCode::VALUE_CORRUPTED;
-    }
-
-    if (rawBlob->info != 0 && rawBlob->version < 3) {
-        // move info from after padding to after data
-        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);
-}
-
-void Blob::setSecurityLevel(keystore::SecurityLevel 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 {
-    int trys = 3;
-    while (trys--) {
-        if (!access(getKeyBlobPath().c_str(), R_OK | W_OK)) return true;
-        if (errno == ENOENT) return false;
-        LOG(WARNING) << "access encountered " << strerror(errno) << " (" << errno << ")"
-                     << " while checking for key blob";
-        if (errno != EAGAIN) break;
-    }
-    return false;
-}
-
-bool KeyBlobEntry::hasCharacteristicsBlob() const {
-    int trys = 3;
-    while (trys--) {
-        if (!access(getCharacteristicsBlobPath().c_str(), R_OK | W_OK)) return true;
-        if (errno == ENOENT) return false;
-        LOG(WARNING) << "access encountered " << strerror(errno) << " (" << errno << ")"
-                     << " while checking for key characteristics blob";
-        if (errno != EAGAIN) break;
-    }
-    return false;
-}
-
-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
deleted file mode 100644
index e0bd146..0000000
--- a/keystore/blob.h
+++ /dev/null
@@ -1,285 +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.
- */
-
-#ifndef KEYSTORE_BLOB_H_
-#define KEYSTORE_BLOB_H_
-
-#include <stdint.h>
-
-#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;
-constexpr size_t kAesKeySize = 128 / 8;
-constexpr size_t kGcmTagLength = 128 / 8;
-constexpr size_t kGcmIvLength = 96 / 8;
-constexpr size_t kAes128KeySizeBytes = 128 / 8;
-constexpr size_t kAes256KeySizeBytes = 256 / 8;
-
-/* Here is the file format. There are two parts in blob.value, the secret and
- * the description. The secret is stored in ciphertext, and its original size
- * can be found in blob.length. The description is stored after the secret in
- * plaintext, and its size is specified in blob.info. The total size of the two
- * parts must be no more than kValueSize bytes. The first field is the version,
- * the second is the blob's type, and the third byte is flags. Fields other
- * than blob.info, blob.length, and blob.value are modified by encryptBlob()
- * and decryptBlob(). Thus they should not be accessed from outside. */
-
-struct __attribute__((packed)) blobv3 {
-    uint8_t version;
-    uint8_t type;
-    uint8_t flags;
-    uint8_t info;
-    uint8_t initialization_vector[AES_BLOCK_SIZE];  // Only 96 bits is used, rest is zeroed.
-    uint8_t aead_tag[kGcmTagLength];
-    int32_t length;  // in network byte order, only for backward compatibility
-    uint8_t value[kValueSize + AES_BLOCK_SIZE];
-};
-
-struct __attribute__((packed)) blobv2 {
-    uint8_t version;
-    uint8_t type;
-    uint8_t flags;
-    uint8_t info;
-    uint8_t vector[AES_BLOCK_SIZE];
-    uint8_t encrypted[0];  // Marks offset to encrypted data.
-    uint8_t digest[MD5_DIGEST_LENGTH];
-    uint8_t digested[0];  // Marks offset to digested data.
-    int32_t length;       // in network byte order
-    uint8_t value[kValueSize + AES_BLOCK_SIZE];
-};
-
-static_assert(sizeof(blobv3) == sizeof(blobv2) &&
-                  offsetof(blobv3, initialization_vector) == offsetof(blobv2, vector) &&
-                  offsetof(blobv3, aead_tag) == offsetof(blobv2, digest) &&
-                  offsetof(blobv3, aead_tag) == offsetof(blobv2, encrypted) &&
-                  offsetof(blobv3, length) == offsetof(blobv2, length) &&
-                  offsetof(blobv3, value) == offsetof(blobv2, value),
-              "Oops.  Blob layout changed.");
-
-static const uint8_t CURRENT_BLOB_VERSION = 3;
-
-typedef enum {
-    TYPE_ANY = 0,  // meta type that matches anything
-    TYPE_GENERIC = 1,
-    TYPE_MASTER_KEY = 2,
-    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() {
-        if (mBlob) *mBlob = {};
-    }
-
-    Blob& operator=(const Blob& rhs);
-    Blob& operator=(Blob&& rhs);
-    explicit operator bool() const { return bool(mBlob); }
-
-    const uint8_t* getValue() const { return mBlob->value; }
-
-    int32_t getLength() const { return mBlob->length; }
-
-    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);
-
-    bool isSuperEncrypted() const;
-    void setSuperEncrypted(bool superEncrypted);
-
-    bool isCriticalToDeviceEncryption() const;
-    void setCriticalToDeviceEncryption(bool critical);
-
-    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); }
-
-    keystore::SecurityLevel getSecurityLevel() const;
-    void setSecurityLevel(keystore::SecurityLevel);
-
-    std::tuple<bool, keystore::AuthorizationSet, keystore::AuthorizationSet>
-    getKeyCharacteristics() const;
-
-    bool putKeyCharacteristics(const keystore::AuthorizationSet& hwEnforced,
-                               const keystore::AuthorizationSet& swEnforced);
-
-  private:
-    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
deleted file mode 100644
index 76df1cc..0000000
--- a/keystore/confirmation_manager.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define LOG_TAG "ConfirmationManager"
-
-#include "confirmation_manager.h"
-
-#include <android/hardware/confirmationui/1.0/IConfirmationResultCallback.h>
-#include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <android/security/BpConfirmationPromptCallback.h>
-#include <binder/BpBinder.h>
-#include <binder/IPCThreadState.h>
-#include <binder/Parcel.h>
-
-#include "keystore_aidl_hidl_marshalling_utils.h"
-
-namespace keystore {
-
-using android::IBinder;
-using android::sp;
-using android::String16;
-using android::String8;
-using android::wp;
-using android::binder::Status;
-using android::hardware::hidl_vec;
-using android::hardware::Return;
-using android::hardware::confirmationui::V1_0::IConfirmationResultCallback;
-using android::hardware::confirmationui::V1_0::IConfirmationUI;
-using android::hardware::confirmationui::V1_0::UIOption;
-
-using android::security::BpConfirmationPromptCallback;
-using std::lock_guard;
-using std::mutex;
-using std::vector;
-
-ConfirmationManager::ConfirmationManager(IBinder::DeathRecipient* deathRecipient)
-    : IConfirmationResultCallback(), mDeathRecipient(deathRecipient) {}
-
-// Called by keystore main thread.
-Status ConfirmationManager::presentConfirmationPrompt(const sp<IBinder>& listener,
-                                                      const String16& promptText,
-                                                      const hidl_vec<uint8_t>& extraData,
-                                                      const String16& locale, int uiOptionsAsFlags,
-                                                      int32_t* aidl_return) {
-    lock_guard<mutex> lock(mMutex);
-
-    if (mCurrentListener != nullptr) {
-        *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::OperationPending);
-        return Status::ok();
-    }
-
-    sp<IConfirmationUI> confirmationUI = IConfirmationUI::tryGetService();
-    if (confirmationUI == nullptr) {
-        ALOGW("Error getting confirmationUI service\n");
-        *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::Unimplemented);
-        return Status::ok();
-    }
-
-    uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
-    if (!mRateLimiting.tryPrompt(callingUid)) {
-        *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::SystemError);
-        return Status::ok();
-    }
-
-    String8 promptText8(promptText);
-    String8 locale8(locale);
-    vector<UIOption> uiOptionsVector;
-    for (int n = 0; n < 32; n++) {
-        if (uiOptionsAsFlags & (1 << n)) {
-            uiOptionsVector.push_back(UIOption(n));
-        }
-    }
-    ConfirmationResponseCode responseCode;
-    responseCode = confirmationUI->promptUserConfirmation(sp<IConfirmationResultCallback>(this),
-                                                          promptText8.string(), extraData,
-                                                          locale8.string(), uiOptionsVector);
-    if (responseCode != ConfirmationResponseCode::OK) {
-        ALOGW("Unexpecxted responseCode %d from promptUserConfirmation\n", responseCode);
-        *aidl_return = static_cast<int32_t>(responseCode);
-        return Status::ok();
-    }
-
-    listener->linkToDeath(mDeathRecipient);
-    confirmationUI->linkToDeath(this, 0);
-    mCurrentListener = listener;
-    mCurrentConfirmationUI = confirmationUI;
-
-    *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::OK);
-    return Status::ok();
-}
-
-// Called by keystore main thread.
-Status ConfirmationManager::cancelConfirmationPrompt(const sp<IBinder>& listener,
-                                                     int32_t* aidl_return) {
-    mMutex.lock();
-    if (mCurrentListener != listener) {
-        // If the prompt was displayed by another application, return
-        // OperationPending.
-        mMutex.unlock();
-        *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::OperationPending);
-        return Status::ok();
-    }
-    mMutex.unlock();
-
-    cancelPrompt();
-
-    *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::OK);
-    return Status::ok();
-}
-
-void ConfirmationManager::cancelPrompt() {
-    mMutex.lock();
-    mRateLimiting.cancelPrompt();
-    sp<IConfirmationUI> confirmationUI = mCurrentConfirmationUI;
-    mMutex.unlock();
-    if (confirmationUI != nullptr) {
-        confirmationUI->abort();
-    }
-}
-
-// Called by keystore main thread.
-Status ConfirmationManager::isConfirmationPromptSupported(bool* aidl_return) {
-    sp<IConfirmationUI> confirmationUI = IConfirmationUI::tryGetService();
-    if (confirmationUI == nullptr) {
-        ALOGW("Error getting confirmationUI service\n");
-        *aidl_return = false;
-        return Status::ok();
-    }
-
-    *aidl_return = true;
-    return Status::ok();
-}
-
-void ConfirmationManager::finalizeTransaction(ConfirmationResponseCode responseCode,
-                                              hidl_vec<uint8_t> dataThatWasConfirmed) {
-    mMutex.lock();
-    mRateLimiting.processResult(responseCode);
-    sp<IBinder> listener = mCurrentListener;
-    if (mCurrentListener != nullptr) {
-        mCurrentListener->unlinkToDeath(mDeathRecipient);
-        mCurrentListener = nullptr;
-    }
-    if (mCurrentConfirmationUI != nullptr) {
-        mCurrentConfirmationUI->unlinkToDeath(this);
-        mCurrentConfirmationUI = nullptr;
-    }
-    mMutex.unlock();
-
-    // Deliver result to the application that started the operation.
-    if (listener != nullptr) {
-        sp<BpConfirmationPromptCallback> obj = new BpConfirmationPromptCallback(listener);
-        Status status = obj->onConfirmationPromptCompleted(static_cast<int32_t>(responseCode),
-                                                           dataThatWasConfirmed);
-        if (!status.isOk()) {
-            ALOGW("Error sending onConfirmationPromptCompleted - status: %s\n",
-                  status.toString8().c_str());
-        }
-    }
-}
-
-// Called by hwbinder thread (not keystore main thread).
-Return<void> ConfirmationManager::result(ConfirmationResponseCode responseCode,
-                                         const hidl_vec<uint8_t>& dataThatWasConfirmed,
-                                         const hidl_vec<uint8_t>& confirmationToken) {
-    finalizeTransaction(responseCode, dataThatWasConfirmed);
-    lock_guard<mutex> lock(mMutex);
-    mLatestConfirmationToken = confirmationToken;
-    return Return<void>();
-}
-
-// Called by keystore main thread or keymaster worker
-hidl_vec<uint8_t> ConfirmationManager::getLatestConfirmationToken() {
-    lock_guard<mutex> lock(mMutex);
-    return mLatestConfirmationToken;
-}
-
-void ConfirmationManager::binderDied(const wp<IBinder>& who) {
-    // This is also called for other binders so need to check it's for
-    // us before acting on it.
-    mMutex.lock();
-    if (who == mCurrentListener) {
-        // Clear this so we don't call back into the already dead
-        // binder in finalizeTransaction().
-        mCurrentListener->unlinkToDeath(mDeathRecipient);
-        mCurrentListener = nullptr;
-        mMutex.unlock();
-        ALOGW("The process which requested the confirmation dialog died.\n");
-        cancelPrompt();
-    } else {
-        mMutex.unlock();
-    }
-}
-
-void ConfirmationManager::serviceDied(uint64_t /* cookie */,
-                                      const wp<android::hidl::base::V1_0::IBase>& /* who */) {
-    ALOGW("The ConfirmationUI HAL died.\n");
-    finalizeTransaction(ConfirmationResponseCode::SystemError, {});
-}
-
-}  // namespace keystore
diff --git a/keystore/confirmation_manager.h b/keystore/confirmation_manager.h
deleted file mode 100644
index 7f0a11d..0000000
--- a/keystore/confirmation_manager.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 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_CONFIRMATION_MANAGER_H_
-#define KEYSTORE_CONFIRMATION_MANAGER_H_
-
-#include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-#include <binder/Status.h>
-#include <keystore/keymaster_types.h>
-#include <map>
-#include <mutex>
-#include <utils/LruCache.h>
-#include <utils/StrongPointer.h>
-#include <vector>
-
-#include "confirmationui_rate_limiting.h"
-
-namespace keystore {
-
-using android::binder::Status;
-using android::hardware::confirmationui::V1_0::IConfirmationResultCallback;
-using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
-
-class ConfirmationManager;
-
-class ConfirmationManager : public android::hardware::hidl_death_recipient,
-                            public IConfirmationResultCallback {
-  public:
-    explicit ConfirmationManager(android::IBinder::DeathRecipient* deathRecipient);
-
-    // Calls into the confirmationui HAL to start a new prompt.
-    //
-    // Returns OperationPending if another application is already
-    // showing a confirmation. Otherwise returns the return code from
-    // the HAL.
-    Status presentConfirmationPrompt(const android::sp<android::IBinder>& listener,
-                                     const android::String16& promptText,
-                                     const hidl_vec<uint8_t>& extraData,
-                                     const android::String16& locale, int uiOptionsAsFlags,
-                                     int32_t* aidl_return);
-
-    // Calls into the confirmationui HAL to cancel displaying a
-    // prompt.
-    //
-    // Returns OperatingPending if another application is showing a
-    // confirmation. Otherwise returns the return code from the HAL.
-    Status cancelConfirmationPrompt(const android::sp<android::IBinder>& listener,
-                                    int32_t* aidl_return);
-
-    // Checks if the confirmationUI HAL is available.
-    Status isConfirmationPromptSupported(bool* aidl_return);
-
-    // Gets the latest confirmation token received from the ConfirmationUI HAL.
-    hidl_vec<uint8_t> getLatestConfirmationToken();
-
-    // Called by KeyStoreService when a client binder has died.
-    void binderDied(const android::wp<android::IBinder>& who);
-
-    // hidl_death_recipient overrides:
-    virtual void serviceDied(uint64_t cookie,
-                             const android::wp<android::hidl::base::V1_0::IBase>& who) override;
-
-    // IConfirmationResultCallback overrides:
-    android::hardware::Return<void> result(ConfirmationResponseCode responseCode,
-                                           const hidl_vec<uint8_t>& dataThatWasConfirmed,
-                                           const hidl_vec<uint8_t>& confirmationToken) override;
-
-  private:
-    friend class ConfirmationResultCallback;
-
-    // Set rate limiting to not decrement on next abort and aborts
-    // confirmationui.
-    void cancelPrompt();
-
-    void finalizeTransaction(ConfirmationResponseCode responseCode,
-                             hidl_vec<uint8_t> dataThatWasConfirmed);
-
-    // This mutex protects all data below it.
-    std::mutex mMutex;
-
-    // The mCurrentListener and mCurrentConfirmationUI fields are set
-    // if and only if a prompt is currently showing.
-    android::sp<android::IBinder> mCurrentListener;
-    android::sp<android::hardware::confirmationui::V1_0::IConfirmationUI> mCurrentConfirmationUI;
-    android::IBinder::DeathRecipient* mDeathRecipient;
-    hidl_vec<uint8_t> mLatestConfirmationToken;
-    RateLimiting<> mRateLimiting;
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_CONFIRMATION_MANAGER_H_
diff --git a/keystore/confirmationui_rate_limiting.h b/keystore/confirmationui_rate_limiting.h
deleted file mode 100644
index 658bf41..0000000
--- a/keystore/confirmationui_rate_limiting.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-**
-** 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_CONFIRMATIONUI_RATE_LIMITING_H_
-#define KEYSTORE_CONFIRMATIONUI_RATE_LIMITING_H_
-
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <chrono>
-#include <stdint.h>
-#include <sys/types.h>
-#include <tuple>
-#include <unordered_map>
-
-namespace keystore {
-
-using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
-
-using std::chrono::duration;
-using std::chrono::time_point;
-
-template <typename Clock = std::chrono::steady_clock> class RateLimiting {
-  private:
-    struct Slot {
-        Slot() : previous_start{}, prompt_start{}, counter(0) {}
-        typename Clock::time_point previous_start;
-        typename Clock::time_point prompt_start;
-        uint32_t counter;
-    };
-
-    std::unordered_map<uid_t, Slot> slots_;
-
-    uint_t latest_requester_;
-
-    static std::chrono::seconds getBackoff(uint32_t counter) {
-        using namespace std::chrono_literals;
-        switch (counter) {
-        case 0:
-        case 1:
-        case 2:
-            return 0s;
-        case 3:
-        case 4:
-        case 5:
-            return 30s;
-        default:
-            return 60s * (1ULL << (counter - 6));
-        }
-    }
-
-  public:
-    // Exposes the number of used slots. This is only used by the test to verify the assumption
-    // about used counter slots.
-    size_t usedSlots() const { return slots_.size(); }
-    void doGC() {
-        using namespace std::chrono_literals;
-        using std::chrono::system_clock;
-        using std::chrono::time_point_cast;
-        auto then = Clock::now() - 24h;
-        auto iter = slots_.begin();
-        while (iter != slots_.end()) {
-            if (iter->second.prompt_start <= then) {
-                iter = slots_.erase(iter);
-            } else {
-                ++iter;
-            }
-        }
-    }
-
-    bool tryPrompt(uid_t id) {
-        using namespace std::chrono_literals;
-        // remove slots that have not been touched in 24 hours
-        doGC();
-        auto& slot = slots_[id];
-        auto now = Clock::now();
-        if (!slot.counter || slot.prompt_start <= now - getBackoff(slot.counter)) {
-            latest_requester_ = id;
-            slot.counter += 1;
-            slot.previous_start = slot.prompt_start;
-            slot.prompt_start = now;
-            return true;
-        }
-        return false;
-    }
-
-    // The app is penalized for cancelling a request. Request are rolled back only if
-    // the prompt was cancelled by the system: e.g. a system error or asynchronous event.
-    // When the user cancels the prompt, it is subject to rate limiting.
-    static constexpr const uint_t kInvalidRequester = -1;
-
-    void cancelPrompt() { latest_requester_ = kInvalidRequester; }
-
-    void processResult(ConfirmationResponseCode rc) {
-        if (latest_requester_ == kInvalidRequester) {
-            return;
-        }
-        switch (rc) {
-        case ConfirmationResponseCode::OK:
-            // reset the counter slot
-            slots_.erase(latest_requester_);
-            return;
-        case ConfirmationResponseCode::Canceled:
-            // nothing to do here
-            return;
-        default:;
-        }
-
-        // roll back latest request
-        auto& slot = slots_[latest_requester_];
-        if (slot.counter <= 1) {
-            slots_.erase(latest_requester_);
-            return;
-        }
-        slot.counter -= 1;
-        slot.prompt_start = slot.previous_start;
-    }
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_CONFIRMATIONUI_RATE_LIMITING_H_
diff --git a/keystore/defaults.h b/keystore/defaults.h
deleted file mode 100644
index 6f7ff2d..0000000
--- a/keystore/defaults.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2013 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_DEFAULTS_H_
-#define KEYSTORE_DEFAULTS_H_
-
-/*
- * These must be kept in sync with
- * frameworks/base/keystore/java/android/security/KeyPairGeneratorSpec.java
- */
-
-/* DSA */
-constexpr int32_t DSA_DEFAULT_KEY_SIZE = 1024;
-constexpr int32_t DSA_MIN_KEY_SIZE = 512;
-constexpr int32_t DSA_MAX_KEY_SIZE = 8192;
-
-/* EC */
-constexpr int32_t EC_DEFAULT_KEY_SIZE = 256;
-constexpr int32_t EC_MIN_KEY_SIZE = 192;
-constexpr int32_t EC_MAX_KEY_SIZE = 521;
-
-/* RSA */
-constexpr int32_t RSA_DEFAULT_KEY_SIZE = 2048;
-constexpr int32_t RSA_DEFAULT_EXPONENT = 0x10001;
-constexpr int32_t RSA_MIN_KEY_SIZE = 512;
-constexpr int32_t RSA_MAX_KEY_SIZE = 8192;
-
-#endif /* KEYSTORE_DEFAULTS_H_ */
diff --git a/keystore/grant_store.cpp b/keystore/grant_store.cpp
deleted file mode 100644
index 9e627ce..0000000
--- a/keystore/grant_store.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 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 "grant_store.h"
-
-#include "blob.h"
-#include <algorithm>
-#include <sstream>
-
-namespace keystore {
-
-static constexpr uint64_t kInvalidGrantNo = std::numeric_limits<uint64_t>::max();
-static const char* kKeystoreGrantInfix = "_KEYSTOREGRANT_";
-static constexpr size_t kKeystoreGrantInfixLength = 15;
-
-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);
-    if (pos == std::string::npos) return {kInvalidGrantNo, ""};
-    std::stringstream s(grantAlias.substr(pos + kKeystoreGrantInfixLength));
-    std::string wrapped_alias = grantAlias.substr(0, pos);
-    uint64_t grant_no = kInvalidGrantNo;
-    s >> grant_no;
-    if (s.fail() || grant_no == kInvalidGrantNo) return {kInvalidGrantNo, ""};
-    return {grant_no, wrapped_alias};
-}
-
-std::string GrantStore::put(const uid_t uid, const LockedKeyBlobEntry& lockedEntry) {
-    std::unique_lock<std::shared_mutex> lock(mutex_);
-    std::stringstream s;
-    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(),
-                     [&](const Grant& entry) { return success = entry.entry_ == blobEntry; });
-    while (!success) {
-        std::tie(iterator, success) = uid_grant_list.emplace(blobEntry, std::rand());
-    }
-    s << iterator->grant_no_;
-    return s.str();
-}
-
-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 {};
-    auto uid_set_iter = grants_.find(uid);
-    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 {};
-    if (grant->entry_.alias() != wrappedAlias) return {};
-    return {&(*grant), std::move(lock)};
-}
-
-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->entry_ == *lockedEntry) {
-            uid_grant_list.erase(i);
-            return true;
-        }
-    }
-    return false;
-}
-
-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->entry_.alias() == alias && i->entry_.uid() == granterUid) {
-                uid_grant_list.second.erase(i);
-                break;
-            }
-        }
-    }
-}
-
-void GrantStore::removeAllGrantsToUid(const uid_t granteeUid) {
-    std::unique_lock<std::shared_mutex> lock(mutex_);
-    grants_.erase(granteeUid);
-}
-
-}  // namespace keystore
diff --git a/keystore/grant_store.h b/keystore/grant_store.h
deleted file mode 100644
index 1baf32c..0000000
--- a/keystore/grant_store.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 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_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
- * and the clients UID, to generate a per client name space.
- * Grants allow assotiating a key file with a new name, thereby making
- * it visible in another client's - the grantee's - namespace.
- */
-class Grant {
-public:
-  Grant(const KeyBlobEntry& entry, const uint64_t grant_no);
-  KeyBlobEntry entry_;
-
-  uint64_t grant_no_;  ///< numeric grant identifier - randomly assigned
-
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  operator const uint64_t&() const { return grant_no_; }
-};
-
-/**
- * The GrantStore holds a set of sets of Grants. One set of Grants for each grantee.
- * The uid parameter to each of the GrantStore function determines the grantee's
- * name space. The methods put, get, and removeByAlias/ByFileName create, lookup, and
- * remove a Grant, respectively.
- * put also returns a new alias for the newly granted key which has to be returned
- * to the granter. The grantee, and only the grantee, can use the granted key
- * by this new alias.
- */
-class GrantStore {
-public:
-    GrantStore() : grants_() {}
-    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);
-
-    // GrantStore is neither copyable nor movable.
-    GrantStore(const GrantStore&) = delete;
-    GrantStore& operator=(const GrantStore&) = delete;
-private:
-    std::unordered_map<uid_t, std::set<Grant, std::less<>>> grants_;
-    mutable std::shared_mutex mutex_;
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_GRANT_STORE_H_
diff --git a/keystore/key_attestation_log_handler.cpp b/keystore/key_attestation_log_handler.cpp
deleted file mode 100644
index c3278cb..0000000
--- a/keystore/key_attestation_log_handler.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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 <statslog.h>
-namespace keystore {
-
-void logKeystoreKeyAttestationEvent(bool wasSuccessful, int32_t errorCode) {
-    // Due to a requirement in stats-write() method, the optional fields
-    // which are not required for attestation logging, are marked with -1 for
-    // non-repeated fields and 0 for repeated fields.
-    android::util::stats_write(android::util::KEYSTORE_KEY_EVENT_REPORTED, -1, -1, -1, -1, -1, 0, 0,
-                               0, 0, -1, -1,
-                               android::util::KEYSTORE_KEY_EVENT_REPORTED__TYPE__KEY_ATTESTATION,
-                               wasSuccessful, errorCode);
-}
-
-}  // namespace keystore
\ No newline at end of file
diff --git a/keystore/key_attestation_log_handler.h b/keystore/key_attestation_log_handler.h
deleted file mode 100644
index a418bfa..0000000
--- a/keystore/key_attestation_log_handler.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _KEY_ATTESTATION_LOG_HANDLER_H_
-#define _KEY_ATTESTATION_LOG_HANDLER_H_
-
-namespace keystore {
-
-void logKeystoreKeyAttestationEvent(bool wasSuccessful, int32_t errorCode);
-
-}
-
-#endif  //_KEY_ATTESTATION_LOG_HANDLER_H_
diff --git a/keystore/key_creation_log_handler.cpp b/keystore/key_creation_log_handler.cpp
deleted file mode 100644
index d846257..0000000
--- a/keystore/key_creation_log_handler.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * 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.
- */
-#define LOG_TAG "KeystoreOperation"
-
-#include "key_creation_log_handler.h"
-#include <statslog.h>
-
-namespace keystore {
-
-template <typename Tag>
-int32_t getEnumTagValue(const AuthorizationSet& authorization_set, Tag tag) {
-    auto tagValue = authorization_set.GetTagValue(tag);
-    if (tagValue.isOk()) {
-        static_assert(sizeof(decltype(tagValue.value())) <= sizeof(int32_t),
-                      "Tag type value will be truncated, if cast to int32_t");
-        return static_cast<int32_t>(tagValue.value());
-    }
-    // Usually, if the value is not present, 0 is set. However, since 0 is a valid
-    // enum value, -1 is set for single enum fields.
-    return -1;
-}
-
-int32_t generateBitMapForPaddingModeValues(const AuthorizationSet& authorization_set) {
-    int32_t bitMap = 0;
-    int32_t tagValueCount = authorization_set.GetTagCount(TAG_PADDING);
-    if (tagValueCount == 0) {
-        // unlike in the single enum fields, if no value is provided,
-        // 0 is set for the bitmap
-        return bitMap;
-    }
-    int current_offset = -1;
-    while (tagValueCount > 0) {
-        current_offset = authorization_set.find(TAG_PADDING, current_offset);
-        KeyParameter keyParam = authorization_set[current_offset];
-        auto tagValue = accessTagValue(TAG_PADDING, keyParam);
-        switch (tagValue) {
-        case PaddingMode::NONE:
-            bitMap |= (1 << NONE_BIT_POS);
-            break;
-        case PaddingMode::RSA_OAEP:
-            bitMap |= (1 << PaddingModeBitPosition::RSA_OAEP_BIT_POS);
-            break;
-        case PaddingMode::RSA_PSS:
-            bitMap |= (1 << PaddingModeBitPosition::RSA_PSS_BIT_POS);
-            break;
-        case PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
-            bitMap |= (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_ENCRYPT_BIT_POS);
-            break;
-        case PaddingMode::RSA_PKCS1_1_5_SIGN:
-            bitMap |= (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_SIGN_BIT_POS);
-            break;
-        case PaddingMode::PKCS7:
-            bitMap |= (1 << PaddingModeBitPosition::PKCS7_BIT_POS);
-            break;
-        default:
-            break;
-        }
-        tagValueCount -= 1;
-    }
-    return bitMap;
-}
-
-int32_t generateBitMapForDigestValues(const AuthorizationSet& authorization_set) {
-    int32_t bitMap = 0;
-    int32_t tagValueCount = authorization_set.GetTagCount(TAG_DIGEST);
-    if (tagValueCount == 0) {
-        // unlike in the single enum fields, if no value is provided,
-        // 0 is set for the bitmap
-        return bitMap;
-    }
-    int current_offset = -1;
-    while (tagValueCount > 0) {
-        current_offset = authorization_set.find(TAG_DIGEST, current_offset);
-        KeyParameter keyParam = authorization_set[current_offset];
-        auto tagValue = accessTagValue(TAG_DIGEST, keyParam);
-        switch (tagValue) {
-        case Digest::NONE:
-            bitMap |= (1 << NONE_BIT_POS);
-            break;
-        case Digest::MD5:
-            bitMap |= (1 << DigestBitPosition::MD5_BIT_POS);
-            break;
-        case Digest::SHA1:
-            bitMap |= (1 << DigestBitPosition::SHA1_BIT_POS);
-            break;
-        case Digest::SHA_2_224:
-            bitMap |= (1 << DigestBitPosition::SHA_2_224_BIT_POS);
-            break;
-        case Digest::SHA_2_256:
-            bitMap |= (1 << DigestBitPosition::SHA_2_256_BIT_POS);
-            break;
-        case Digest::SHA_2_384:
-            bitMap |= (1 << DigestBitPosition::SHA_2_384_BIT_POS);
-            break;
-        case Digest::SHA_2_512:
-            bitMap |= (1 << DigestBitPosition::SHA_2_512_BIT_POS);
-            break;
-        default:
-            break;
-        }
-        tagValueCount -= 1;
-    }
-    return bitMap;
-}
-
-int32_t generateBitMapForBlockModeValues(const AuthorizationSet& authorization_set) {
-    int32_t bitMap = 0;
-    int32_t tagValueCount = authorization_set.GetTagCount(TAG_BLOCK_MODE);
-    if (tagValueCount == 0) {
-        // unlike in the single enum fields, if no value is provided,
-        // 0 is set for the bitmap
-        return bitMap;
-    }
-    int current_offset = -1;
-    while (tagValueCount > 0) {
-        current_offset = authorization_set.find(TAG_BLOCK_MODE, current_offset);
-        KeyParameter keyParam = authorization_set[current_offset];
-        auto tagValue = accessTagValue(TAG_BLOCK_MODE, keyParam);
-        switch (tagValue) {
-        case BlockMode::ECB:
-            bitMap |= (1 << BlockModeBitPosition::ECB_BIT_POS);
-            break;
-        case BlockMode::CBC:
-            bitMap |= (1 << BlockModeBitPosition::CBC_BIT_POS);
-            break;
-        case BlockMode::CTR:
-            bitMap |= (1 << BlockModeBitPosition::CTR_BIT_POS);
-            break;
-        case BlockMode::GCM:
-            bitMap |= (1 << BlockModeBitPosition::GCM_BIT_POS);
-            break;
-        default:
-            break;
-        }
-        tagValueCount -= 1;
-    }
-    return bitMap;
-}
-
-int32_t generateBitMapForKeyPurposeValues(const AuthorizationSet& authorization_set) {
-    int32_t bitMap = 0;
-    int32_t tagValueCount = authorization_set.GetTagCount(TAG_PURPOSE);
-    if (tagValueCount == 0) {
-        // unlike in the single enum fields, if no value is provided,
-        // 0 is set for the bitmap
-        return bitMap;
-    }
-    int current_offset = -1;
-    while (tagValueCount > 0) {
-        current_offset = authorization_set.find(TAG_PURPOSE, current_offset);
-        KeyParameter keyParam = authorization_set[current_offset];
-        auto tagValue = accessTagValue(TAG_PURPOSE, keyParam);
-        switch (tagValue) {
-        case KeyPurpose::ENCRYPT:
-            bitMap |= (1 << KeyPurposeBitPosition::ENCRYPT_BIT_POS);
-            break;
-        case KeyPurpose::DECRYPT:
-            bitMap |= (1 << KeyPurposeBitPosition::DECRYPT_BIT_POS);
-            break;
-        case KeyPurpose::SIGN:
-            bitMap |= (1 << KeyPurposeBitPosition::SIGN_BIT_POS);
-            break;
-        case KeyPurpose::VERIFY:
-            bitMap |= (1 << KeyPurposeBitPosition::VERIFY_BIT_POS);
-            break;
-        case KeyPurpose::WRAP_KEY:
-            bitMap |= (1 << KeyPurposeBitPosition::WRAP_KEY_BIT_POS);
-            break;
-        default:
-            break;
-        }
-        tagValueCount -= 1;
-    }
-    return bitMap;
-}
-
-void logKeystoreKeyCreationEvent(const hidl_vec<KeyParameter>& keyParams,
-                                 bool wasCreationSuccessful, int32_t errorCode) {
-    AuthorizationSet authorization_set(keyParams);
-    authorization_set.Deduplicate();
-
-    android::util::stats_write(android::util::KEYSTORE_KEY_EVENT_REPORTED,
-                               getEnumTagValue(authorization_set, TAG_ALGORITHM),
-                               getEnumTagValue(authorization_set, TAG_KEY_SIZE),
-                               getEnumTagValue(authorization_set, TAG_ORIGIN),
-                               getEnumTagValue(authorization_set, TAG_USER_AUTH_TYPE),
-                               getEnumTagValue(authorization_set, TAG_AUTH_TIMEOUT),
-                               generateBitMapForPaddingModeValues(authorization_set),
-                               generateBitMapForDigestValues(authorization_set),
-                               generateBitMapForBlockModeValues(authorization_set),
-                               generateBitMapForKeyPurposeValues(authorization_set),
-                               getEnumTagValue(authorization_set, TAG_EC_CURVE),
-                               getEnumTagValue(authorization_set, TAG_BLOB_USAGE_REQUIREMENTS),
-                               android::util::KEYSTORE_KEY_EVENT_REPORTED__TYPE__KEY_CREATION,
-                               wasCreationSuccessful, errorCode);
-}
-
-}  // namespace keystore
diff --git a/keystore/key_creation_log_handler.h b/keystore/key_creation_log_handler.h
deleted file mode 100644
index a314eb1..0000000
--- a/keystore/key_creation_log_handler.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef KEY_CREATION_LOG_HANDLER_H_
-#define KEY_CREATION_LOG_HANDLER_H_
-
-#include <keystore/keystore_hidl_support.h>
-
-namespace keystore {
-
-/**
- * Following enums are defined as a part of the workaround to log the repeated
- * values of ENUM_REP type. The workaround is to represent the repeated values
- * of ENUM_REP type as a bitmap and the following enums define their positions
- * in the bitmap.
- */
-
-enum PaddingModeBitPosition : int32_t {
-    RSA_OAEP_BIT_POS = 1,
-    RSA_PSS_BIT_POS = 2,
-    RSA_PKCS1_1_5_ENCRYPT_BIT_POS = 3,
-    RSA_PKCS1_1_5_SIGN_BIT_POS = 4,
-    PKCS7_BIT_POS = 5,
-};
-
-enum DigestBitPosition : int32_t {
-    MD5_BIT_POS = 1,
-    SHA1_BIT_POS = 2,
-    SHA_2_224_BIT_POS = 3,
-    SHA_2_256_BIT_POS = 4,
-    SHA_2_384_BIT_POS = 5,
-    SHA_2_512_BIT_POS = 6,
-};
-
-enum BlockModeBitPosition : int32_t {
-    ECB_BIT_POS = 1,
-    CBC_BIT_POS = 2,
-    CTR_BIT_POS = 3,
-    GCM_BIT_POS = 4,
-};
-
-enum KeyPurposeBitPosition : int32_t {
-    ENCRYPT_BIT_POS = 1,
-    DECRYPT_BIT_POS = 2,
-    SIGN_BIT_POS = 3,
-    VERIFY_BIT_POS = 4,
-    WRAP_KEY_BIT_POS = 5,
-};
-
-// None is an enum value for digest and a deprecated value for padding mode
-const int32_t NONE_BIT_POS = 0;
-
-void logKeystoreKeyCreationEvent(const hidl_vec<KeyParameter>& keyParams,
-                                 bool wasCreationSuccessful, int32_t errorCode);
-
-}  // namespace keystore
-
-#endif  // KEY_CREATION_LOG_HANDLER_H_
diff --git a/keystore/key_operation_log_handler.cpp b/keystore/key_operation_log_handler.cpp
deleted file mode 100644
index e7f4345..0000000
--- a/keystore/key_operation_log_handler.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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.
- */
-#define LOG_TAG "KeystoreOperation"
-
-#include "key_operation_log_handler.h"
-#include "key_creation_log_handler.h"
-
-#include <keystore/keystore_hidl_support.h>
-#include <statslog.h>
-
-namespace keystore {
-
-template <typename Tag>
-int32_t getOptionalEnumTagValue(const AuthorizationSet& authorization_set, Tag tag) {
-    auto tagValue = authorization_set.GetTagValue(tag);
-    if (tagValue.isOk()) {
-        static_assert(sizeof(decltype(tagValue.value())) <= sizeof(int32_t),
-                      "Tag type value will be truncated, if cast to int32_t");
-        return static_cast<int32_t>(tagValue.value());
-    }
-    //-1 is an invalid value for all enum types.
-    return -1;
-}
-
-int32_t generateBitMapForPaddingModeValue(const AuthorizationSet& authorization_set) {
-    auto tagValue = authorization_set.GetTagValue(TAG_PADDING);
-    if (tagValue.isOk()) {
-        auto value = tagValue.value();
-        switch (value) {
-        case PaddingMode::NONE:
-            return (1 << NONE_BIT_POS);
-        case PaddingMode::RSA_OAEP:
-            return (1 << PaddingModeBitPosition::RSA_OAEP_BIT_POS);
-        case PaddingMode::RSA_PSS:
-            return (1 << PaddingModeBitPosition::RSA_PSS_BIT_POS);
-        case PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
-            return (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_ENCRYPT_BIT_POS);
-        case PaddingMode::RSA_PKCS1_1_5_SIGN:
-            return (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_SIGN_BIT_POS);
-        case PaddingMode::PKCS7:
-            return (1 << PaddingModeBitPosition::PKCS7_BIT_POS);
-        default:
-            break;
-        }
-    }
-    // unlike in the single enum fields, if no value is provided,
-    // 0 is set for the bitmap
-    return 0;
-}
-
-int32_t generateBitMapForDigestValue(const AuthorizationSet& authorization_set) {
-    auto tagValue = authorization_set.GetTagValue(TAG_DIGEST);
-    if (tagValue.isOk()) {
-        auto value = tagValue.value();
-        switch (value) {
-        case Digest::NONE:
-            return (1 << NONE_BIT_POS);
-        case Digest::MD5:
-            return (1 << DigestBitPosition::MD5_BIT_POS);
-        case Digest::SHA1:
-            return (1 << DigestBitPosition::SHA1_BIT_POS);
-        case Digest::SHA_2_224:
-            return (1 << DigestBitPosition::SHA_2_224_BIT_POS);
-        case Digest::SHA_2_256:
-            return (1 << DigestBitPosition::SHA_2_256_BIT_POS);
-        case Digest::SHA_2_384:
-            return (1 << DigestBitPosition::SHA_2_384_BIT_POS);
-        case Digest::SHA_2_512:
-            return (1 << DigestBitPosition::SHA_2_512_BIT_POS);
-        default:
-            break;
-        }
-    }
-    // unlike in the single enum fields, if no value is provided,
-    // 0 is set for the bitmap
-    return 0;
-}
-
-int32_t generateBitMapForBlockModeValue(const AuthorizationSet& authorization_set) {
-    auto tagValue = authorization_set.GetTagValue(TAG_BLOCK_MODE);
-    if (tagValue.isOk()) {
-        auto value = tagValue.value();
-        switch (value) {
-        case BlockMode::ECB:
-            return (1 << BlockModeBitPosition::ECB_BIT_POS);
-        case BlockMode::CBC:
-            return (1 << BlockModeBitPosition::CBC_BIT_POS);
-        case BlockMode::CTR:
-            return (1 << BlockModeBitPosition::CTR_BIT_POS);
-        case BlockMode::GCM:
-            return (1 << BlockModeBitPosition::GCM_BIT_POS);
-        default:
-            break;
-        }
-    }
-    // unlike in the single enum fields, if no value is provided,
-    // 0 is set for the bitmap
-    return 0;
-}
-
-void logKeystoreKeyOperationEvent(const Operation& op, bool wasOperationSuccessful,
-                                  int32_t responseCode) {
-    AuthorizationSet authorization_set(op.characteristics.softwareEnforced);
-    authorization_set.Union(op.characteristics.hardwareEnforced);
-    AuthorizationSet operation_params(op.params);
-
-    android::util::stats_write(
-        android::util::KEYSTORE_KEY_EVENT_REPORTED,
-        getOptionalEnumTagValue(authorization_set, TAG_ALGORITHM),
-        getOptionalEnumTagValue(authorization_set, TAG_KEY_SIZE),
-        getOptionalEnumTagValue(authorization_set, TAG_ORIGIN),
-        getOptionalEnumTagValue(authorization_set, TAG_USER_AUTH_TYPE),
-        getOptionalEnumTagValue(authorization_set, TAG_AUTH_TIMEOUT),
-        generateBitMapForPaddingModeValue(operation_params),
-        generateBitMapForDigestValue(operation_params),
-        generateBitMapForBlockModeValue(operation_params), static_cast<int32_t>(op.purpose),
-        getOptionalEnumTagValue(authorization_set, TAG_EC_CURVE),
-        getOptionalEnumTagValue(authorization_set, TAG_BLOB_USAGE_REQUIREMENTS),
-        android::util::KEYSTORE_KEY_EVENT_REPORTED__TYPE__KEY_OPERATION, wasOperationSuccessful,
-        responseCode);
-}
-
-}  // namespace keystore
\ No newline at end of file
diff --git a/keystore/key_operation_log_handler.h b/keystore/key_operation_log_handler.h
deleted file mode 100644
index ba27747..0000000
--- a/keystore/key_operation_log_handler.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef KEY_OPERATION_LOG_HANDLER_H_
-#define KEY_OPERATION_LOG_HANDLER_H_
-
-#include "operation_struct.h"
-
-namespace keystore {
-
-void logKeystoreKeyOperationEvent(const Operation& op, bool wasSuccessful, int32_t errorCode);
-
-}  // namespace keystore
-
-#endif  // KEY_OPERATION_LOG_HANDLER_H_
\ No newline at end of file
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
deleted file mode 100644
index 4e5bc48..0000000
--- a/keystore/key_store_service.cpp
+++ /dev/null
@@ -1,1480 +0,0 @@
-/*
- * Copyright (C) 2016 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 "keystore"
-
-#include "key_store_service.h"
-
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include <algorithm>
-#include <atomic>
-#include <sstream>
-
-#include <android-base/scopeguard.h>
-#include <binder/IInterface.h>
-#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 <keymasterV4_0/keymaster_utils.h>
-
-#include "defaults.h"
-#include "key_attestation_log_handler.h"
-#include "keystore_keymaster_enforcement.h"
-#include "keystore_utils.h"
-#include <keystore/keystore_attestation_id.h>
-#include <keystore/keystore_hidl_support.h>
-#include <keystore/keystore_return_types.h>
-
-#include <hardware/hw_auth_token.h>
-
-namespace keystore {
-
-using namespace android;
-
-namespace {
-
-using ::android::binder::Status;
-using android::hardware::keymaster::V4_0::support::authToken2HidlVec;
-using android::hardware::keymaster::V4_0::support::serializeVerificationToken;
-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::ICredstoreTokenCallback;
-using ::android::security::keystore::IKeystoreOperationResultCallback;
-using ::android::security::keystore::IKeystoreResponseCallback;
-using ::android::security::keystore::KeystoreResponse;
-
-constexpr double kIdRotationPeriod = 30 * 24 * 60 * 60; /* Thirty days, in seconds */
-const char* kTimestampFilePath = "timestamp";
-
-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; });
-}
-
-#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(nullptr), sbuf.st_ctime);
-        return {ResponseCode::NO_ERROR, diff_secs < kIdRotationPeriod};
-    }
-
-    if (errno != ENOENT) {
-        ALOGE("Failed to stat \"timestamp\" file, with error %d", errno);
-        return {ResponseCode::SYSTEM_ERROR, false /* don't care */};
-    }
-
-    int fd = creat(kTimestampFilePath, 0600);
-    if (fd < 0) {
-        ALOGE("Couldn't create \"timestamp\" file, with error %d", errno);
-        return {ResponseCode::SYSTEM_ERROR, false /* don't care */};
-    }
-
-    if (close(fd)) {
-        ALOGE("Couldn't close \"timestamp\" file, with error %d", errno);
-        return {ResponseCode::SYSTEM_ERROR, false /* don't care */};
-    }
-
-    return {ResponseCode::NO_ERROR, true};
-}
-
-using ::android::security::KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE;
-
-KeyStoreServiceReturnCode updateParamsForAttestation(uid_t callingUid, AuthorizationSet* params) {
-    KeyStoreServiceReturnCode responseCode;
-    bool factoryResetSinceIdRotation;
-    std::tie(responseCode, factoryResetSinceIdRotation) = hadFactoryResetSinceIdRotation();
-
-    if (!responseCode.isOk()) return responseCode;
-    if (factoryResetSinceIdRotation) params->push_back(TAG_RESET_SINCE_ID_ROTATION);
-
-    auto asn1_attestation_id_result = security::gather_attestation_application_id(callingUid);
-    if (!asn1_attestation_id_result.isOk()) {
-        ALOGE("failed to gather attestation_id");
-        // Couldn't get attestation ID; just use an empty one rather than failing.
-        asn1_attestation_id_result = std::vector<uint8_t>();
-    }
-    std::vector<uint8_t>& asn1_attestation_id = asn1_attestation_id_result;
-
-    /*
-     * 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) {
-        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);
-
-    return ResponseCode::NO_ERROR;
-}
-
-}  // anonymous namespace
-
-Status KeyStoreService::getState(int32_t userId, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_GET_STATE)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-    *aidl_return = mKeyStore->getState(userId);
-    return Status::ok();
-}
-
-Status KeyStoreService::get(const String16& name, int32_t uid, ::std::vector<uint8_t>* item) {
-    uid_t targetUid = getEffectiveUid(uid);
-    if (!checkBinderPermission(P_GET, targetUid)) {
-        // see keystore/keystore.h
-        return Status::fromServiceSpecificError(
-            static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
-    }
-
-    String8 name8(name);
-    ResponseCode rc;
-    Blob keyBlob;
-    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.
-        return Status::fromServiceSpecificError(static_cast<int32_t>(rc));
-    }
-    auto resultBlob = blob2hidlVec(keyBlob);
-    // The static_cast here is needed to prevent a move, forcing a deep copy.
-    if (item) *item = static_cast<const hidl_vec<uint8_t>&>(blob2hidlVec(keyBlob));
-    return Status::ok();
-}
-
-Status KeyStoreService::insert(const String16& name, const ::std::vector<uint8_t>& item,
-                               int targetUid, int32_t flags, int32_t* aidl_return) {
-    targetUid = getEffectiveUid(targetUid);
-    KeyStoreServiceReturnCode result =
-        checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (!result.isOk()) {
-        *aidl_return = result.getErrorCode();
-        return Status::ok();
-    }
-
-    String8 name8(name);
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), targetUid);
-
-    if (!lockedEntry) {
-        ALOGE("failed to grab lock on blob entry %u_%s", targetUid, name8.string());
-        *aidl_return = static_cast<int32_t>(ResponseCode::KEY_ALREADY_EXISTS);
-        return Status::ok();
-    }
-
-    Blob keyBlob(&item[0], item.size(), nullptr, 0, ::TYPE_GENERIC);
-    keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
-
-    *aidl_return = static_cast<int32_t>(mKeyStore->put(lockedEntry, keyBlob, {}));
-    return Status::ok();
-}
-
-Status KeyStoreService::del(const String16& name, int targetUid, int32_t* aidl_return) {
-    targetUid = getEffectiveUid(targetUid);
-    if (!checkBinderPermission(P_DELETE, targetUid)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-    String8 name8(name);
-    ALOGI("del %s %d", name8.string(), targetUid);
-    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(lockedEntry);
-
-    *aidl_return = static_cast<int32_t>(result);
-    return Status::ok();
-}
-
-Status KeyStoreService::exist(const String16& name, int targetUid, int32_t* aidl_return) {
-    targetUid = getEffectiveUid(targetUid);
-    if (!checkBinderPermission(P_EXIST, targetUid)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    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, int32_t targetUid,
-                             ::std::vector<::android::String16>* matches) {
-    targetUid = getEffectiveUid(targetUid);
-    if (!checkBinderPermission(P_LIST, targetUid)) {
-        return Status::fromServiceSpecificError(
-            static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
-    }
-    const String8 prefix8(prefix);
-    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));
-    }
-
-    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::onUserPasswordChanged(int32_t userId, const String16& password,
-                                              int32_t* aidl_return) {
-    if (!checkBinderPermission(P_PASSWORD)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    if (password.size() == 0) {
-        ALOGI("Secure lockscreen for user %d removed, deleting encrypted entries", userId);
-        mKeyStore->resetUser(userId, true);
-        *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-        return Status::ok();
-    } else {
-        const String8 password8(password);
-        switch (mKeyStore->getState(userId)) {
-        case ::STATE_UNINITIALIZED: {
-            // generate master key, encrypt with password, write to file,
-            // initialize mMasterKey*.
-            *aidl_return = static_cast<int32_t>(mKeyStore->initializeUser(password8, userId));
-            return Status::ok();
-        }
-        case ::STATE_NO_ERROR: {
-            // rewrite master key with new password.
-            *aidl_return = static_cast<int32_t>(mKeyStore->writeMasterKey(password8, userId));
-            return Status::ok();
-        }
-        case ::STATE_LOCKED: {
-            ALOGE("Changing user %d's password while locked, clearing old encryption", userId);
-            mKeyStore->resetUser(userId, true);
-            *aidl_return = static_cast<int32_t>(mKeyStore->initializeUser(password8, userId));
-            return Status::ok();
-        }
-        }
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-}
-
-Status KeyStoreService::onUserAdded(int32_t userId, int32_t parentId, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_USER_CHANGED)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    // Sanity check that the new user has an empty keystore.
-    if (!mKeyStore->isEmpty(userId)) {
-        ALOGW("New user %d's keystore not empty. Clearing old entries.", userId);
-    }
-    // Unconditionally clear the keystore, just to be safe.
-    mKeyStore->resetUser(userId, false);
-    if (parentId != -1) {
-        // This profile must share the same master key password as the parent profile. Because the
-        // password of the parent profile is not known here, the best we can do is copy the parent's
-        // master key and master key file. This makes this profile use the same master key as the
-        // parent profile, forever.
-        *aidl_return = static_cast<int32_t>(mKeyStore->copyMasterKey(parentId, userId));
-        return Status::ok();
-    } else {
-        *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-        return Status::ok();
-    }
-}
-
-Status KeyStoreService::onUserRemoved(int32_t userId, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_USER_CHANGED)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    mKeyStore->resetUser(userId, false);
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return Status::ok();
-}
-
-Status KeyStoreService::lock(int32_t userId, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_LOCK)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    State state = mKeyStore->getState(userId);
-    if (state != ::STATE_NO_ERROR) {
-        ALOGD("calling lock in state: %d", state);
-        *aidl_return = static_cast<int32_t>(ResponseCode(state));
-        return Status::ok();
-    }
-
-    mKeyStore->getEnforcementPolicy().set_device_locked(true, userId);
-    mKeyStore->lock(userId);
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return Status::ok();
-}
-
-Status KeyStoreService::unlock(int32_t userId, const String16& pw, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_UNLOCK)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    State state = mKeyStore->getState(userId);
-    if (state != ::STATE_LOCKED) {
-        switch (state) {
-        case ::STATE_NO_ERROR:
-            ALOGI("calling unlock when already unlocked, ignoring.");
-            break;
-        case ::STATE_UNINITIALIZED:
-            ALOGE("unlock called on uninitialized keystore.");
-            break;
-        default:
-            ALOGE("unlock called on keystore in unknown state: %d", state);
-            break;
-        }
-        *aidl_return = static_cast<int32_t>(ResponseCode(state));
-        return Status::ok();
-    }
-
-    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));
-    return Status::ok();
-}
-
-Status KeyStoreService::isEmpty(int32_t userId, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_IS_EMPTY)) {
-        *aidl_return = static_cast<int32_t>(false);
-        return Status::ok();
-    }
-
-    *aidl_return = static_cast<int32_t>(mKeyStore->isEmpty(userId));
-    return Status::ok();
-}
-
-Status KeyStoreService::grant(const String16& name, int32_t granteeUid,
-                              ::android::String16* aidl_return) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    auto result =
-        checkBinderPermissionAndKeystoreState(P_GRANT, /*targetUid=*/-1, /*checkUnlocked=*/false);
-    if (!result.isOk()) {
-        *aidl_return = String16();
-        return Status::ok();
-    }
-
-    String8 name8(name);
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfExists(name8.string(), callingUid);
-    if (!lockedEntry) {
-        *aidl_return = String16();
-        return Status::ok();
-    }
-
-    *aidl_return = String16(mKeyStore->addGrant(lockedEntry, granteeUid).c_str());
-    return Status::ok();
-}
-
-Status KeyStoreService::ungrant(const String16& name, int32_t granteeUid, int32_t* aidl_return) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    KeyStoreServiceReturnCode result =
-        checkBinderPermissionAndKeystoreState(P_GRANT, /*targetUid=*/-1, /*checkUnlocked=*/false);
-    if (!result.isOk()) {
-        *aidl_return = result.getErrorCode();
-        return Status::ok();
-    }
-
-    String8 name8(name);
-
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfExists(name8.string(), callingUid);
-    if (!lockedEntry) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::KEY_NOT_FOUND);
-    }
-
-    *aidl_return = mKeyStore->removeGrant(lockedEntry, granteeUid);
-    return Status::ok();
-}
-
-Status KeyStoreService::getmtime(const String16& name, int32_t uid, int64_t* time) {
-    uid_t targetUid = getEffectiveUid(uid);
-    if (!checkBinderPermission(P_GET, targetUid)) {
-        ALOGW("permission denied for %d: getmtime", targetUid);
-        *time = -1L;
-        return Status::ok();
-    }
-    String8 name8(name);
-
-    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();
-    }
-
-    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.c_str());
-        *time = -1L;
-        return Status::ok();
-    }
-
-    struct stat s;
-    int ret = fstat(fd, &s);
-    close(fd);
-    if (ret == -1) {
-        ALOGW("could not stat %s for getmtime", filename.c_str());
-        *time = -1L;
-        return Status::ok();
-    }
-
-    *time = static_cast<int64_t>(s.st_mtime);
-    return Status::ok();
-}
-
-Status KeyStoreService::is_hardware_backed(const String16& keyType, int32_t* aidl_return) {
-    *aidl_return = static_cast<int32_t>(mKeyStore->isHardwareBacked(keyType) ? 1 : 0);
-    return Status::ok();
-}
-
-Status KeyStoreService::clear_uid(int64_t targetUid64, int32_t* _aidl_return) {
-    uid_t targetUid = getEffectiveUid(targetUid64);
-    if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) {
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-    ALOGI("clear_uid %" PRId64, targetUid64);
-
-    mKeyStore->removeAllGrantsToUid(targetUid);
-
-    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 (LockedKeyBlobEntry& lockedEntry : entries) {
-        if (get_app_id(targetUid) == AID_SYSTEM) {
-            Blob keyBlob;
-            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(lockedEntry);
-    }
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-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) {
-        return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
-    }
-
-    device->addRngEntropy(entropy, [device, cb](Return<ErrorCode> rc) {
-        cb->onFinished(KeyStoreServiceReturnCode(KS_HANDLE_HIDL_ERROR(device, rc)));
-    });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-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) {
-    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))
-                << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
-        }
-    });
-    KeyStoreServiceReturnCode rc =
-        checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (!rc.isOk()) {
-        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);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-
-    if (containsTag(params.getParameters(), Tag::INCLUDE_UNIQUE_ID)) {
-        if (!checkBinderPermission(P_GEN_UNIQUE_ID)) {
-            return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-        }
-    }
-
-    SecurityLevel securityLevel = flagsToSecurityLevel(flags);
-    auto dev = mKeyStore->getDevice(securityLevel);
-    if (!dev) {
-        return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
-    }
-
-    String8 name8(name);
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), uid);
-    if (!lockedEntry) {
-        return AIDL_RETURN(ResponseCode::KEY_ALREADY_EXISTS);
-    }
-
-    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,
-    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);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-
-    String8 name8(name);
-
-    ResponseCode rc;
-    Blob keyBlob;
-    Blob charBlob;
-    LockedKeyBlobEntry lockedEntry;
-
-    std::tie(rc, keyBlob, charBlob, lockedEntry) =
-        mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
-
-    if (rc != ResponseCode::NO_ERROR) {
-        return AIDL_RETURN(rc);
-    }
-
-    auto dev = mKeyStore->getDevice(keyBlob);
-    if (!dev) {
-        return AIDL_RETURN(ResponseCode::SYSTEM_ERROR);
-    }
-
-    // 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));
-        });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-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))
-                << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
-        }
-    });
-    KeyStoreServiceReturnCode rc =
-        checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (!rc.isOk()) {
-        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);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-
-    SecurityLevel securityLevel = flagsToSecurityLevel(flags);
-    auto dev = mKeyStore->getDevice(securityLevel);
-    if (!dev) {
-        LOG(ERROR) << "importKey - cound not get keymaster device";
-        return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
-    }
-
-    String8 name8(name);
-    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);
-    }
-
-    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));
-        });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-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);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-
-    String8 name8(name);
-
-    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 dev = mKeyStore->getDevice(keyBlob);
-
-    dev->exportKey(std::move(lockedEntry), KeyFormat(format), clientId.getData(), appData.getData(),
-                   std::move(keyBlob), std::move(charBlob),
-                   [cb](ExportResult exportResult) { cb->onFinished(exportResult); });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-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,
-                              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);
-        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);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-    if (!checkAllowedOperationParams(params.getParameters())) {
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    String8 name8(name);
-    Blob keyBlob;
-    Blob charBlob;
-    LockedKeyBlobEntry lockedEntry;
-    ResponseCode rc;
-
-    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();
-
-    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) {
-                       mKeyStore->addOperationDevice(result_.token, dev);
-                   }
-                   cb->onFinished(result_);
-               });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-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())) {
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    auto dev = mKeyStore->getOperationDevice(token);
-    if (!dev) {
-        return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
-    }
-
-    dev->update(token, params.getParameters(), input, [this, cb, token](OperationResult result_) {
-        if (!result_.resultCode.isOk()) {
-            mKeyStore->removeOperationDevice(token);
-        }
-        cb->onFinished(result_);
-    });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-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>& input,
-                               const ::std::vector<uint8_t>& signature,
-                               const ::std::vector<uint8_t>& entropy, int32_t* _aidl_return) {
-    if (!checkAllowedOperationParams(params.getParameters())) {
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    auto dev = mKeyStore->getOperationDevice(token);
-    if (!dev) {
-        return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
-    }
-
-    dev->finish(token, params.getParameters(), input, signature, entropy,
-                [this, cb, token](OperationResult result_) {
-                    mKeyStore->removeOperationDevice(token);
-                    cb->onFinished(result_);
-                });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::abort(const ::android::sp<IKeystoreResponseCallback>& cb,
-                              const ::android::sp<::android::IBinder>& token,
-                              int32_t* _aidl_return) {
-    auto dev = mKeyStore->getOperationDevice(token);
-    if (!dev) {
-        return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
-    }
-
-    dev->abort(token, [this, cb, token](KeyStoreServiceReturnCode rc) {
-        mKeyStore->removeOperationDevice(token);
-        cb->onFinished(rc);
-    });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::addAuthToken(const ::std::vector<uint8_t>& authTokenAsVector,
-                                     int32_t* aidl_return) {
-
-    // TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
-    // receive a HardwareAuthToken, rather than an opaque byte array.
-
-    if (!checkBinderPermission(P_ADD_AUTH)) {
-        ALOGW("addAuthToken: permission denied for %d", IPCThreadState::self()->getCallingUid());
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-    if (authTokenAsVector.size() != sizeof(hw_auth_token_t)) {
-        *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 = KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT).getErrorCode();
-        return Status::ok();
-    }
-
-    mKeyStore->getAuthTokenTable().AddAuthenticationToken(
-        hidlVec2AuthToken(hidl_vec<uint8_t>(authTokenAsVector)));
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return Status::ok();
-}
-
-Status KeyStoreService::getTokensForCredstore(int64_t challenge, int64_t secureUserId,
-                                              int32_t authTokenMaxAgeMillis,
-                                              const ::android::sp<ICredstoreTokenCallback>& cb) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (callingUid != AID_CREDSTORE) {
-        return Status::fromServiceSpecificError(static_cast<int32_t>(0));
-    }
-
-    auto [err, authToken] = mKeyStore->getAuthTokenTable().FindAuthorizationForCredstore(
-        challenge, secureUserId, authTokenMaxAgeMillis);
-    // It's entirely possible we couldn't find an authToken (e.g. no user auth
-    // happened within the requested deadline) and in that case, we just
-    // callback immediately signaling success but just not returning any tokens.
-    if (err != AuthTokenTable::OK) {
-        cb->onFinished(true, {} /* serializedAuthToken */, {} /* serializedVerificationToken */);
-        return Status::ok();
-    }
-
-    // If we did find an authToken, get a verificationToken as well...
-    //
-    std::vector<uint8_t> serializedAuthToken = authToken2HidlVec(authToken);
-    std::vector<uint8_t> serializedVerificationToken;
-    std::shared_ptr<KeymasterWorker> dev = mKeyStore->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
-    if (!dev) {
-        LOG(ERROR) << "Unable to get KM device for SecurityLevel::TRUSTED_ENVIRONMENT";
-        dev = mKeyStore->getDevice(SecurityLevel::SOFTWARE);
-        if (!dev) {
-            LOG(ERROR) << "Unable to get KM device for SecurityLevel::SOFTWARE";
-            cb->onFinished(false, {}, {});
-            return Status::fromServiceSpecificError(static_cast<int32_t>(0));
-        }
-    }
-
-    dev->verifyAuthorization(
-        challenge, {} /* params */, authToken,
-        [serializedAuthToken, cb](KeyStoreServiceReturnCode rc, HardwareAuthToken,
-                                  VerificationToken verificationToken) {
-            if (rc != ErrorCode::OK) {
-                LOG(ERROR) << "verifyAuthorization failed, rc=" << rc;
-                cb->onFinished(false, {}, {});
-                return;
-            }
-            std::optional<std::vector<uint8_t>> serializedVerificationToken =
-                serializeVerificationToken(verificationToken);
-            if (!serializedVerificationToken) {
-                LOG(ERROR) << "Error serializing verificationToken";
-                cb->onFinished(false, {}, {});
-                return;
-            }
-            cb->onFinished(true, serializedAuthToken, serializedVerificationToken.value());
-        });
-
-    return Status::ok();
-}
-
-bool isDeviceIdAttestationTag(Tag tag) {
-    switch (tag) {
-    case Tag::ATTESTATION_ID_BRAND:
-    case Tag::ATTESTATION_ID_DEVICE:
-    case Tag::ATTESTATION_ID_MANUFACTURER:
-    case Tag::ATTESTATION_ID_MODEL:
-    case Tag::ATTESTATION_ID_PRODUCT:
-    case Tag::ATTESTATION_ID_IMEI:
-    case Tag::ATTESTATION_ID_MEID:
-    case Tag::ATTESTATION_ID_SERIAL:
-        return true;
-    case Tag::INVALID:
-    case Tag::PURPOSE:
-    case Tag::ALGORITHM:
-    case Tag::KEY_SIZE:
-    case Tag::BLOCK_MODE:
-    case Tag::DIGEST:
-    case Tag::PADDING:
-    case Tag::CALLER_NONCE:
-    case Tag::MIN_MAC_LENGTH:
-    case Tag::EC_CURVE:
-    case Tag::RSA_PUBLIC_EXPONENT:
-    case Tag::INCLUDE_UNIQUE_ID:
-    case Tag::BLOB_USAGE_REQUIREMENTS:
-    case Tag::BOOTLOADER_ONLY:
-    case Tag::ROLLBACK_RESISTANCE:
-    case Tag::HARDWARE_TYPE:
-    case Tag::ACTIVE_DATETIME:
-    case Tag::ORIGINATION_EXPIRE_DATETIME:
-    case Tag::USAGE_EXPIRE_DATETIME:
-    case Tag::MIN_SECONDS_BETWEEN_OPS:
-    case Tag::MAX_USES_PER_BOOT:
-    case Tag::USER_ID:
-    case Tag::USER_SECURE_ID:
-    case Tag::NO_AUTH_REQUIRED:
-    case Tag::USER_AUTH_TYPE:
-    case Tag::AUTH_TIMEOUT:
-    case Tag::ALLOW_WHILE_ON_BODY:
-    case Tag::TRUSTED_USER_PRESENCE_REQUIRED:
-    case Tag::TRUSTED_CONFIRMATION_REQUIRED:
-    case Tag::UNLOCKED_DEVICE_REQUIRED:
-    case Tag::APPLICATION_ID:
-    case Tag::APPLICATION_DATA:
-    case Tag::CREATION_DATETIME:
-    case Tag::ORIGIN:
-    case Tag::ROOT_OF_TRUST:
-    case Tag::OS_VERSION:
-    case Tag::OS_PATCHLEVEL:
-    case Tag::UNIQUE_ID:
-    case Tag::ATTESTATION_CHALLENGE:
-    case Tag::ATTESTATION_APPLICATION_ID:
-    case Tag::VENDOR_PATCHLEVEL:
-    case Tag::BOOT_PATCHLEVEL:
-    case Tag::ASSOCIATED_DATA:
-    case Tag::NONCE:
-    case Tag::MAC_LENGTH:
-    case Tag::RESET_SINCE_ID_ROTATION:
-    case Tag::CONFIRMATION_TOKEN:
-        return false;
-        // no default, all values must be present in the switch, in this way the compiler ensures
-        // that new values added in the Tag enum are also added here.
-    }
-}
-
-// These are attestation id tags that are not unique per device and don't require special permission
-// to be attested. Any addition to this list needs privacy review and approval (PWG).
-bool isDevicePropertyAttestationTag(Tag tag) {
-    switch (tag) {
-    case Tag::ATTESTATION_ID_BRAND:
-    case Tag::ATTESTATION_ID_DEVICE:
-    case Tag::ATTESTATION_ID_MANUFACTURER:
-    case Tag::ATTESTATION_ID_MODEL:
-    case Tag::ATTESTATION_ID_PRODUCT:
-        return true;
-    default:
-        return false;
-    }
-}
-
-bool isDeviceIdAttestationRequested(const KeymasterArguments& params) {
-    const hardware::hidl_vec<KeyParameter>& paramsVec = params.getParameters();
-    for (size_t i = 0; i < paramsVec.size(); ++i) {
-        if (isDeviceIdAttestationTag(paramsVec[i].tag)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-// Device properties can be attested safely without special permission
-bool needsPermissionToAttestDeviceIds(const KeymasterArguments& params) {
-    const hardware::hidl_vec<KeyParameter>& paramsVec = params.getParameters();
-    for (size_t i = 0; i < paramsVec.size(); ++i) {
-        if (isDeviceIdAttestationTag(paramsVec[i].tag) &&
-            !isDevicePropertyAttestationTag(paramsVec[i].tag)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-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())) {
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-
-    if (needsPermissionToAttestDeviceIds(params) && (get_app_id(callingUid) != AID_SYSTEM)) {
-        return AIDL_RETURN(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
-    }
-
-    AuthorizationSet mutableParams = params.getParameters();
-    KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
-
-    auto logErrorOnReturn = android::base::make_scope_guard(
-        [&] { logKeystoreKeyAttestationEvent(false /*wasSuccessful*/, rc.getErrorCode()); });
-
-    if (!rc.isOk()) {
-        return AIDL_RETURN(rc);
-    }
-
-    String8 name8(name);
-    Blob keyBlob;
-    Blob charBlob;
-    LockedKeyBlobEntry lockedEntry;
-
-    std::tie(rc, keyBlob, charBlob, lockedEntry) =
-        mKeyStore->getKeyForName(name8, callingUid, TYPE_KEYMASTER_10);
-
-    if (!rc.isOk()) {
-        return AIDL_RETURN(rc);
-    }
-
-    logErrorOnReturn.Disable();
-
-    auto dev = mKeyStore->getDevice(keyBlob);
-    auto hidlKey = blob2hidlVec(keyBlob);
-    dev->attestKey(
-        std::move(hidlKey), mutableParams.hidl_data(),
-        [dev, cb](Return<void> rc,
-                  std::tuple<ErrorCode, hidl_vec<hidl_vec<uint8_t>>>&& hidlResult) {
-            auto& [ret, certChain] = hidlResult;
-            if (!rc.isOk()) {
-                logKeystoreKeyAttestationEvent(false /*wasSuccessful*/,
-                                               static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
-                cb->onFinished(KeyStoreServiceReturnCode(ResponseCode::SYSTEM_ERROR), {});
-            } else if (ret != ErrorCode::OK) {
-                KeyStoreServiceReturnCode ksrc(ret);
-                logKeystoreKeyAttestationEvent(false /*wasSuccessful*/, ksrc.getErrorCode());
-                dev->logIfKeymasterVendorError(ret);
-                cb->onFinished(ksrc, {});
-            } else {
-                KeyStoreServiceReturnCode ksrc(ret);
-                logKeystoreKeyAttestationEvent(true /*wasSuccessful*/, ksrc.getErrorCode());
-                cb->onFinished(ksrc, KeymasterCertificateChain(std::move(certChain)));
-            }
-        });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-// 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())) {
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    if (!isDeviceIdAttestationRequested(params)) {
-        // There is an attestKey() method for attesting keys without device ID attestation.
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-
-    // Request special permission only for unique ids
-    if (needsPermissionToAttestDeviceIds(params)) {
-        sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
-        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)) {
-            return AIDL_RETURN(ErrorCode::CANNOT_ATTEST_IDS);
-        }
-    }
-
-    AuthorizationSet mutableParams = params.getParameters();
-    KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
-    if (!rc.isOk()) {
-        return AIDL_RETURN(rc);
-    }
-
-    // Generate temporary key.
-    auto dev = mKeyStore->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
-
-    if (!dev) {
-        return AIDL_RETURN(ResponseCode::SYSTEM_ERROR);
-    }
-
-
-    AuthorizationSet keyCharacteristics;
-    keyCharacteristics.push_back(TAG_PURPOSE, KeyPurpose::VERIFY);
-    keyCharacteristics.push_back(TAG_ALGORITHM, Algorithm::EC);
-    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);
-
-    std::promise<KeyStoreServiceReturnCode> resultPromise;
-    auto resultFuture = resultPromise.get_future();
-
-    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) {
-                dev->logIfKeymasterVendorError(ret);
-                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), [dev](Return<ErrorCode> rc) {
-                        // log error but don't return an error
-                        KS_HANDLE_HIDL_ERROR(dev, 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 {
-                        dev->logIfKeymasterVendorError(ret);
-                        cb->onFinished(KeyStoreServiceReturnCode(ret), {});
-                    }
-                });
-        });
-
-    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.
-    mKeyStore->getAuthTokenTable().onDeviceOffBody();
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return 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,
-    int32_t* _aidl_return) {
-
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-
-    if (!checkBinderPermission(P_INSERT, callingUid)) {
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-
-    String8 wrappingKeyName8(wrappingKeyAlias);
-
-    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);
-    }
-
-    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));
-        });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::presentConfirmationPrompt(const sp<IBinder>& listener,
-                                                  const String16& promptText,
-                                                  const ::std::vector<uint8_t>& extraData,
-                                                  const String16& locale, int32_t uiOptionsAsFlags,
-                                                  int32_t* 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 mKeyStore->getConfirmationManager().cancelConfirmationPrompt(listener, aidl_return);
-}
-
-Status KeyStoreService::isConfirmationPromptSupported(bool* aidl_return) {
-    return mKeyStore->getConfirmationManager().isConfirmationPromptSupported(aidl_return);
-}
-
-/**
- * Get the effective target uid for a binder operation that takes an
- * optional uid as the target.
- */
-uid_t KeyStoreService::getEffectiveUid(int32_t targetUid) {
-    if (targetUid == UID_SELF) {
-        return IPCThreadState::self()->getCallingUid();
-    }
-    return static_cast<uid_t>(targetUid);
-}
-
-/**
- * Check if the caller of the current binder method has the required
- * permission and if acting on other uids the grants to do so.
- */
-bool KeyStoreService::checkBinderPermission(perm_t permission, int32_t targetUid) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    pid_t spid = IPCThreadState::self()->getCallingPid();
-    const char* ssid = IPCThreadState::self()->getCallingSid();
-    if (!has_permission(callingUid, permission, spid, ssid)) {
-        ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
-        return false;
-    }
-    if (!is_granted_to(callingUid, getEffectiveUid(targetUid))) {
-        ALOGW("uid %d not granted to act for %d", callingUid, targetUid);
-        return false;
-    }
-    return true;
-}
-
-/**
- * Check if the caller of the current binder method has the required
- * permission and the target uid is the caller or the caller is system.
- */
-bool KeyStoreService::checkBinderPermissionSelfOrSystem(perm_t permission, int32_t targetUid) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    pid_t spid = IPCThreadState::self()->getCallingPid();
-    const char* ssid = IPCThreadState::self()->getCallingSid();
-    if (!has_permission(callingUid, permission, spid, ssid)) {
-        ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
-        return false;
-    }
-    return getEffectiveUid(targetUid) == callingUid || callingUid == AID_SYSTEM;
-}
-
-/**
- * Check if the caller of the current binder method has the required
- * permission or the target of the operation is the caller's uid. This is
- * for operation where the permission is only for cross-uid activity and all
- * uids are allowed to act on their own (ie: clearing all entries for a
- * given uid).
- */
-bool KeyStoreService::checkBinderPermissionOrSelfTarget(perm_t permission, int32_t targetUid) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (getEffectiveUid(targetUid) == callingUid) {
-        return true;
-    } else {
-        return checkBinderPermission(permission, targetUid);
-    }
-}
-
-/**
- * Helper method to check that the caller has the required permission as
- * well as the keystore is in the unlocked state if checkUnlocked is true.
- *
- * Returns NO_ERROR on success, PERMISSION_DENIED on a permission error and
- * otherwise the state of keystore when not unlocked and checkUnlocked is
- * true.
- */
-KeyStoreServiceReturnCode
-KeyStoreService::checkBinderPermissionAndKeystoreState(perm_t permission, int32_t targetUid,
-                                                       bool checkUnlocked) {
-    if (!checkBinderPermission(permission, targetUid)) {
-        return ResponseCode::PERMISSION_DENIED;
-    }
-    State state = mKeyStore->getState(get_user_id(getEffectiveUid(targetUid)));
-    if (checkUnlocked && !isKeystoreUnlocked(state)) {
-        // All State values coincide with ResponseCodes
-        return static_cast<ResponseCode>(state);
-    }
-
-    return ResponseCode::NO_ERROR;
-}
-
-bool KeyStoreService::isKeystoreUnlocked(State state) {
-    switch (state) {
-    case ::STATE_NO_ERROR:
-        return true;
-    case ::STATE_UNINITIALIZED:
-    case ::STATE_LOCKED:
-        return false;
-    }
-    return false;
-}
-
-/**
- * Check that all KeyParameters provided by the application are allowed. Any parameter that keystore
- * adds itself should be disallowed here.
- */
-bool KeyStoreService::checkAllowedOperationParams(const hidl_vec<KeyParameter>& params) {
-    for (size_t i = 0; i < params.size(); ++i) {
-        switch (params[i].tag) {
-        case Tag::ATTESTATION_APPLICATION_ID:
-        case Tag::RESET_SINCE_ID_ROTATION:
-            return false;
-        default:
-            break;
-        }
-    }
-    return true;
-}
-
-Status KeyStoreService::onKeyguardVisibilityChanged(bool isShowing, int32_t userId,
-                                                    int32_t* _aidl_return) {
-    if (isShowing) {
-        if (!checkBinderPermission(P_LOCK, UID_SELF)) {
-            LOG(WARNING) << "onKeyguardVisibilityChanged called with isShowing == true but "
-                            "without LOCK permission";
-            return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-        }
-    } else {
-        if (!checkBinderPermission(P_UNLOCK, UID_SELF)) {
-            LOG(WARNING) << "onKeyguardVisibilityChanged called with isShowing == false but "
-                            "without UNLOCK permission";
-            return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-        }
-    }
-    mKeyStore->getEnforcementPolicy().set_device_locked(isShowing, userId);
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-}  // namespace keystore
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
deleted file mode 100644
index 5fdddb9..0000000
--- a/keystore/key_store_service.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2016 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_KEYSTORE_SERVICE_H_
-#define KEYSTORE_KEYSTORE_SERVICE_H_
-
-#include <android/security/keystore/BnKeystoreService.h>
-
-#include "auth_token_table.h"
-#include "confirmation_manager.h"
-
-#include "KeyStore.h"
-#include "keystore_keymaster_enforcement.h"
-#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>
-
-#include <mutex>
-
-namespace keystore {
-
-// Class provides implementation for generated BnKeystoreService.h based on
-// gen/aidl/android/security/BnKeystoreService.h generated from
-// 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::keystore::BnKeystoreService {
-  public:
-    explicit KeyStoreService(sp<KeyStore> keyStore) : mKeyStore(keyStore) {}
-    virtual ~KeyStoreService() = default;
-
-    void binderDied(const android::wp<android::IBinder>& who);
-
-    ::android::binder::Status getState(int32_t userId, int32_t* _aidl_return) override;
-    ::android::binder::Status get(const ::android::String16& name, int32_t uid,
-                                  ::std::vector<uint8_t>* _aidl_return) override;
-    ::android::binder::Status insert(const ::android::String16& name,
-                                     const ::std::vector<uint8_t>& item, int32_t uid, int32_t flags,
-                                     int32_t* _aidl_return) override;
-    ::android::binder::Status del(const ::android::String16& name, int32_t uid,
-                                  int32_t* _aidl_return) override;
-    ::android::binder::Status exist(const ::android::String16& name, int32_t uid,
-                                    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 onUserPasswordChanged(int32_t userId,
-                                                    const ::android::String16& newPassword,
-                                                    int32_t* _aidl_return) override;
-    ::android::binder::Status lock(int32_t userId, int32_t* _aidl_return) override;
-    ::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 grant(const ::android::String16& name, int32_t granteeUid,
-                                    ::android::String16* _aidl_return) override;
-    ::android::binder::Status ungrant(const ::android::String16& name, int32_t granteeUid,
-                                      int32_t* _aidl_return) override;
-    ::android::binder::Status getmtime(const ::android::String16& name, int32_t uid,
-                                       int64_t* _aidl_return) override;
-    ::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 ::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
-    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,
-              int32_t* _aidl_return) override;
-    ::android::binder::Status
-    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, int32_t* _aidl_return) override;
-    ::android::binder::Status
-    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, int32_t* _aidl_return) override;
-    ::android::binder::Status
-    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>& input, const ::std::vector<uint8_t>& signature,
-           const ::std::vector<uint8_t>& entropy, 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 getTokensForCredstore(
-        int64_t challenge, int64_t secureUserId, int32_t authTokenMaxAge,
-        const ::android::sp<::android::security::keystore::ICredstoreTokenCallback>& cb) 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::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, int32_t* _aidl_return) override;
-
-    ::android::binder::Status presentConfirmationPrompt(
-        const ::android::sp<::android::IBinder>& listener, const ::android::String16& promptText,
-        const ::std::vector<uint8_t>& extraData, const ::android::String16& locale,
-        int32_t uiOptionsAsFlags, int32_t* _aidl_return) override;
-    ::android::binder::Status
-    cancelConfirmationPrompt(const ::android::sp<::android::IBinder>& listener,
-                             int32_t* _aidl_return) override;
-    ::android::binder::Status isConfirmationPromptSupported(bool* _aidl_return) override;
-
-    ::android::binder::Status onKeyguardVisibilityChanged(bool isShowing, int32_t userId,
-                                                          int32_t* _aidl_return) override;
-
-  private:
-    static const int32_t UID_SELF = -1;
-
-    /**
-     * Get the effective target uid for a binder operation that takes an
-     * optional uid as the target.
-     */
-    uid_t getEffectiveUid(int32_t targetUid);
-
-    /**
-     * Check if the caller of the current binder method has the required
-     * permission and if acting on other uids the grants to do so.
-     */
-    bool checkBinderPermission(perm_t permission, int32_t targetUid = UID_SELF);
-
-    /**
-     * Check if the caller of the current binder method has the required
-     * permission and the target uid is the caller or the caller is system.
-     */
-    bool checkBinderPermissionSelfOrSystem(perm_t permission, int32_t targetUid);
-
-    /**
-     * Check if the caller of the current binder method has the required
-     * permission or the target of the operation is the caller's uid. This is
-     * for operation where the permission is only for cross-uid activity and all
-     * uids are allowed to act on their own (ie: clearing all entries for a
-     * given uid).
-     */
-    bool checkBinderPermissionOrSelfTarget(perm_t permission, int32_t targetUid);
-
-    /**
-     * Helper method to check that the caller has the required permission as
-     * well as the keystore is in the unlocked state if checkUnlocked is true.
-     *
-     * Returns NO_ERROR on success, PERMISSION_DENIED on a permission error and
-     * otherwise the state of keystore when not unlocked and checkUnlocked is
-     * true.
-     */
-    KeyStoreServiceReturnCode checkBinderPermissionAndKeystoreState(perm_t permission,
-                                                                    int32_t targetUid = -1,
-                                                                    bool checkUnlocked = true);
-
-    bool isKeystoreUnlocked(State state);
-
-    /**
-     * Check that all keymaster_key_param_t's provided by the application are
-     * allowed. Any parameter that keystore adds itself should be disallowed here.
-     */
-    bool checkAllowedOperationParams(const hidl_vec<KeyParameter>& params);
-
-    void addLegacyBeginParams(const android::String16& name, AuthorizationSet* params);
-
-    KeyStoreServiceReturnCode doLegacySignVerify(const android::String16& name,
-                                                 const hidl_vec<uint8_t>& data,
-                                                 hidl_vec<uint8_t>* out,
-                                                 const hidl_vec<uint8_t>& signature,
-                                                 KeyPurpose purpose);
-
-    /**
-     * Adds a Confirmation Token to the key parameters if needed.
-     */
-    void appendConfirmationTokenIfNeeded(const KeyCharacteristics& keyCharacteristics,
-                                         std::vector<KeyParameter>* params);
-
-    sp<KeyStore> mKeyStore;
-};
-
-};  // namespace keystore
-
-#endif  // KEYSTORE_KEYSTORE_SERVICE_H_
diff --git a/keystore/keyblob_utils.cpp b/keystore/keyblob_utils.cpp
deleted file mode 100644
index 6c2fac9..0000000
--- a/keystore/keyblob_utils.cpp
+++ /dev/null
@@ -1,65 +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.
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <keystore/keystore.h>
-
-/**
- * When a key is being migrated from a software keymaster implementation
- * to a hardware keymaster implementation, the first 4 bytes of the key_blob
- * given to the hardware implementation will be equal to SOFT_KEY_MAGIC.
- * The hardware implementation should import these PKCS#8 format keys which
- * are encoded like this:
- *
- * 4-byte SOFT_KEY_MAGIC
- *
- * 4-byte 32-bit integer big endian for public_key_length. This may be zero
- *     length which indicates the public key should be derived from the
- *     private key.
- *
- * public_key_length bytes of public key (may be empty)
- *
- * 4-byte 32-bit integer big endian for private_key_length
- *
- * private_key_length bytes of private key
- */
-static const uint8_t SOFT_KEY_MAGIC[] = { 'P', 'K', '#', '8' };
-
-size_t get_softkey_header_size() {
-    return sizeof(SOFT_KEY_MAGIC);
-}
-
-uint8_t* add_softkey_header(uint8_t* key_blob, size_t key_blob_length) {
-    if (key_blob_length < sizeof(SOFT_KEY_MAGIC)) {
-        return nullptr;
-    }
-
-    memcpy(key_blob, SOFT_KEY_MAGIC, sizeof(SOFT_KEY_MAGIC));
-
-    return key_blob + sizeof(SOFT_KEY_MAGIC);
-}
-
-bool is_softkey(const uint8_t* key_blob, const size_t key_blob_length) {
-    if (key_blob_length < sizeof(SOFT_KEY_MAGIC)) {
-        return false;
-    }
-
-    return !memcmp(key_blob, SOFT_KEY_MAGIC, sizeof(SOFT_KEY_MAGIC));
-}
diff --git a/keystore/keymaster_enforcement.cpp b/keystore/keymaster_enforcement.cpp
deleted file mode 100644
index a17cd94..0000000
--- a/keystore/keymaster_enforcement.cpp
+++ /dev/null
@@ -1,555 +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.
- */
-
-#define LOG_TAG "keystore"
-
-#include "keymaster_enforcement.h"
-
-#include <assert.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <string.h>
-
-#include <openssl/evp.h>
-
-#include <hardware/hw_auth_token.h>
-#include <log/log.h>
-
-#include <list>
-
-#include <keystore/keystore_hidl_support.h>
-
-namespace keystore {
-
-bool is_public_key_algorithm(const AuthorizationSet& auth_set) {
-    auto algorithm = auth_set.GetTagValue(TAG_ALGORITHM);
-    return algorithm.isOk() &&
-           (algorithm.value() == Algorithm::RSA || algorithm.value() == Algorithm::EC);
-}
-
-static ErrorCode authorized_purpose(const KeyPurpose purpose, const AuthorizationSet& auth_set) {
-    switch (purpose) {
-    case KeyPurpose::VERIFY:
-    case KeyPurpose::ENCRYPT:
-    case KeyPurpose::SIGN:
-    case KeyPurpose::DECRYPT:
-        if (auth_set.Contains(TAG_PURPOSE, purpose)) return ErrorCode::OK;
-        return ErrorCode::INCOMPATIBLE_PURPOSE;
-
-    default:
-        return ErrorCode::UNSUPPORTED_PURPOSE;
-    }
-}
-
-inline bool is_origination_purpose(KeyPurpose purpose) {
-    return purpose == KeyPurpose::ENCRYPT || purpose == KeyPurpose::SIGN;
-}
-
-inline bool is_usage_purpose(KeyPurpose purpose) {
-    return purpose == KeyPurpose::DECRYPT || purpose == KeyPurpose::VERIFY;
-}
-
-KeymasterEnforcement::KeymasterEnforcement(uint32_t max_access_time_map_size,
-                                           uint32_t max_access_count_map_size)
-    : access_time_map_(max_access_time_map_size), access_count_map_(max_access_count_map_size) {}
-
-KeymasterEnforcement::~KeymasterEnforcement() {
-}
-
-ErrorCode KeymasterEnforcement::AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid,
-                                                   const AuthorizationSet& auth_set,
-                                                   const AuthorizationSet& operation_params,
-                                                   const HardwareAuthToken& auth_token,
-                                                   uint64_t op_handle, bool is_begin_operation) {
-    if (is_public_key_algorithm(auth_set)) {
-        switch (purpose) {
-        case KeyPurpose::ENCRYPT:
-        case KeyPurpose::VERIFY:
-            /* Public key operations are always authorized. */
-            return ErrorCode::OK;
-
-        case KeyPurpose::DECRYPT:
-        case KeyPurpose::SIGN:
-            break;
-
-        case KeyPurpose::WRAP_KEY:
-            return ErrorCode::INCOMPATIBLE_PURPOSE;
-        };
-    };
-
-    if (is_begin_operation)
-        return AuthorizeBegin(purpose, keyid, auth_set, operation_params, auth_token);
-    else
-        return AuthorizeUpdateOrFinish(auth_set, auth_token, op_handle);
-}
-
-// For update and finish the only thing to check is user authentication, and then only if it's not
-// timeout-based.
-ErrorCode KeymasterEnforcement::AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
-                                                        const HardwareAuthToken& auth_token,
-                                                        uint64_t op_handle) {
-    int auth_type_index = -1;
-    for (size_t pos = 0; pos < auth_set.size(); ++pos) {
-        switch (auth_set[pos].tag) {
-        case Tag::NO_AUTH_REQUIRED:
-        case Tag::AUTH_TIMEOUT:
-            // If no auth is required or if auth is timeout-based, we have nothing to check.
-            return ErrorCode::OK;
-
-        case Tag::USER_AUTH_TYPE:
-            auth_type_index = pos;
-            break;
-
-        default:
-            break;
-        }
-    }
-
-    // Note that at this point we should be able to assume that authentication is required, because
-    // authentication is required if KM_TAG_NO_AUTH_REQUIRED is absent.  However, there are legacy
-    // keys which have no authentication-related tags, so we assume that absence is equivalent to
-    // presence of KM_TAG_NO_AUTH_REQUIRED.
-    //
-    // So, if we found KM_TAG_USER_AUTH_TYPE or if we find KM_TAG_USER_SECURE_ID then authentication
-    // is required.  If we find neither, then we assume authentication is not required and return
-    // success.
-    bool authentication_required = (auth_type_index != -1);
-    for (auto& param : auth_set) {
-        auto user_secure_id = authorizationValue(TAG_USER_SECURE_ID, param);
-        if (user_secure_id.isOk()) {
-            authentication_required = true;
-            int auth_timeout_index = -1;
-            if (auth_token.mac.size() &&
-                AuthTokenMatches(auth_set, auth_token, user_secure_id.value(), auth_type_index,
-                                 auth_timeout_index, op_handle, false /* is_begin_operation */))
-                return ErrorCode::OK;
-        }
-    }
-
-    if (authentication_required) return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
-
-    return ErrorCode::OK;
-}
-
-ErrorCode KeymasterEnforcement::AuthorizeBegin(const KeyPurpose purpose, const km_id_t keyid,
-                                               const AuthorizationSet& auth_set,
-                                               const AuthorizationSet& operation_params,
-                                               NullOr<const HardwareAuthToken&> auth_token) {
-    // Find some entries that may be needed to handle KM_TAG_USER_SECURE_ID
-    int auth_timeout_index = -1;
-    int auth_type_index = -1;
-    int no_auth_required_index = -1;
-    for (size_t pos = 0; pos < auth_set.size(); ++pos) {
-        switch (auth_set[pos].tag) {
-        case Tag::AUTH_TIMEOUT:
-            auth_timeout_index = pos;
-            break;
-        case Tag::USER_AUTH_TYPE:
-            auth_type_index = pos;
-            break;
-        case Tag::NO_AUTH_REQUIRED:
-            no_auth_required_index = pos;
-            break;
-        default:
-            break;
-        }
-    }
-
-    ErrorCode error = authorized_purpose(purpose, auth_set);
-    if (error != ErrorCode::OK) return error;
-
-    // If successful, and if key has a min time between ops, this will be set to the time limit
-    uint32_t min_ops_timeout = UINT32_MAX;
-
-    bool update_access_count = false;
-    bool caller_nonce_authorized_by_key = false;
-    bool authentication_required = false;
-    bool auth_token_matched = false;
-    bool unlocked_device_required = false;
-    int32_t user_id = -1;
-
-    for (auto& param : auth_set) {
-
-        // KM_TAG_PADDING_OLD and KM_TAG_DIGEST_OLD aren't actually members of the enum, so we can't
-        // switch on them.  There's nothing to validate for them, though, so just ignore them.
-        if (int32_t(param.tag) == KM_TAG_PADDING_OLD || int32_t(param.tag) == KM_TAG_DIGEST_OLD)
-            continue;
-
-        switch (param.tag) {
-
-        case Tag::ACTIVE_DATETIME: {
-            auto date = authorizationValue(TAG_ACTIVE_DATETIME, param);
-            if (date.isOk() && !activation_date_valid(date.value()))
-                return ErrorCode::KEY_NOT_YET_VALID;
-            break;
-        }
-        case Tag::ORIGINATION_EXPIRE_DATETIME: {
-            auto date = authorizationValue(TAG_ORIGINATION_EXPIRE_DATETIME, param);
-            if (is_origination_purpose(purpose) && date.isOk() &&
-                expiration_date_passed(date.value()))
-                return ErrorCode::KEY_EXPIRED;
-            break;
-        }
-        case Tag::USAGE_EXPIRE_DATETIME: {
-            auto date = authorizationValue(TAG_USAGE_EXPIRE_DATETIME, param);
-            if (is_usage_purpose(purpose) && date.isOk() && expiration_date_passed(date.value()))
-                return ErrorCode::KEY_EXPIRED;
-            break;
-        }
-        case Tag::MIN_SECONDS_BETWEEN_OPS: {
-            auto min_ops_timeout = authorizationValue(TAG_MIN_SECONDS_BETWEEN_OPS, param);
-            if (min_ops_timeout.isOk() && !MinTimeBetweenOpsPassed(min_ops_timeout.value(), keyid))
-                return ErrorCode::KEY_RATE_LIMIT_EXCEEDED;
-            break;
-        }
-        case Tag::MAX_USES_PER_BOOT: {
-            auto max_users = authorizationValue(TAG_MAX_USES_PER_BOOT, param);
-            update_access_count = true;
-            if (max_users.isOk() && !MaxUsesPerBootNotExceeded(keyid, max_users.value()))
-                return ErrorCode::KEY_MAX_OPS_EXCEEDED;
-            break;
-        }
-        case Tag::USER_SECURE_ID:
-            if (no_auth_required_index != -1) {
-                // Key has both KM_TAG_USER_SECURE_ID and KM_TAG_NO_AUTH_REQUIRED
-                return ErrorCode::INVALID_KEY_BLOB;
-            }
-
-            if (auth_timeout_index != -1) {
-                auto secure_id = authorizationValue(TAG_USER_SECURE_ID, param);
-                authentication_required = true;
-                if (secure_id.isOk() && auth_token.isOk() &&
-                    AuthTokenMatches(auth_set, auth_token.value(), secure_id.value(),
-                                     auth_type_index, auth_timeout_index, 0 /* op_handle */,
-                                     true /* is_begin_operation */))
-                    auth_token_matched = true;
-            }
-            break;
-
-        case Tag::USER_ID:
-            user_id = authorizationValue(TAG_USER_ID, param).value();
-            break;
-
-        case Tag::CALLER_NONCE:
-            caller_nonce_authorized_by_key = true;
-            break;
-
-        case Tag::UNLOCKED_DEVICE_REQUIRED:
-            unlocked_device_required = true;
-            break;
-
-        /* Tags should never be in key auths. */
-        case Tag::INVALID:
-        case Tag::ROOT_OF_TRUST:
-        case Tag::APPLICATION_DATA:
-        case Tag::ATTESTATION_CHALLENGE:
-        case Tag::ATTESTATION_APPLICATION_ID:
-        case Tag::ATTESTATION_ID_BRAND:
-        case Tag::ATTESTATION_ID_DEVICE:
-        case Tag::ATTESTATION_ID_PRODUCT:
-        case Tag::ATTESTATION_ID_SERIAL:
-        case Tag::ATTESTATION_ID_IMEI:
-        case Tag::ATTESTATION_ID_MEID:
-        case Tag::ATTESTATION_ID_MANUFACTURER:
-        case Tag::ATTESTATION_ID_MODEL:
-            return ErrorCode::INVALID_KEY_BLOB;
-
-        /* Tags used for cryptographic parameters in keygen.  Nothing to enforce. */
-        case Tag::PURPOSE:
-        case Tag::ALGORITHM:
-        case Tag::KEY_SIZE:
-        case Tag::BLOCK_MODE:
-        case Tag::DIGEST:
-        case Tag::MAC_LENGTH:
-        case Tag::PADDING:
-        case Tag::NONCE:
-        case Tag::MIN_MAC_LENGTH:
-        case Tag::EC_CURVE:
-
-        /* Tags not used for operations. */
-        case Tag::BLOB_USAGE_REQUIREMENTS:
-
-        /* Algorithm specific parameters not used for access control. */
-        case Tag::RSA_PUBLIC_EXPONENT:
-
-        /* Informational tags. */
-        case Tag::CREATION_DATETIME:
-        case Tag::ORIGIN:
-        case Tag::ROLLBACK_RESISTANCE:
-
-        /* Tags handled when KM_TAG_USER_SECURE_ID is handled */
-        case Tag::NO_AUTH_REQUIRED:
-        case Tag::USER_AUTH_TYPE:
-        case Tag::AUTH_TIMEOUT:
-
-        /* Tag to provide data to operations. */
-        case Tag::ASSOCIATED_DATA:
-
-        /* Tags that are implicitly verified by secure side */
-        case Tag::APPLICATION_ID:
-        case Tag::BOOT_PATCHLEVEL:
-        case Tag::OS_PATCHLEVEL:
-        case Tag::OS_VERSION:
-        case Tag::TRUSTED_USER_PRESENCE_REQUIRED:
-        case Tag::VENDOR_PATCHLEVEL:
-
-        /* TODO(swillden): Handle these */
-        case Tag::INCLUDE_UNIQUE_ID:
-        case Tag::UNIQUE_ID:
-        case Tag::RESET_SINCE_ID_ROTATION:
-        case Tag::ALLOW_WHILE_ON_BODY:
-        case Tag::HARDWARE_TYPE:
-        case Tag::TRUSTED_CONFIRMATION_REQUIRED:
-        case Tag::CONFIRMATION_TOKEN:
-            break;
-
-        case Tag::BOOTLOADER_ONLY:
-            return ErrorCode::INVALID_KEY_BLOB;
-        }
-    }
-
-    if (unlocked_device_required && is_device_locked(user_id)) {
-        switch (purpose) {
-        case KeyPurpose::ENCRYPT:
-        case KeyPurpose::VERIFY:
-            /* These are okay */
-            break;
-        case KeyPurpose::DECRYPT:
-        case KeyPurpose::SIGN:
-        case KeyPurpose::WRAP_KEY:
-            return ErrorCode::DEVICE_LOCKED;
-        };
-    }
-
-    if (authentication_required && !auth_token_matched) {
-        ALOGE("Auth required but no matching auth token found");
-        return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
-    }
-
-    if (!caller_nonce_authorized_by_key && is_origination_purpose(purpose) &&
-        operation_params.Contains(Tag::NONCE))
-        return ErrorCode::CALLER_NONCE_PROHIBITED;
-
-    if (min_ops_timeout != UINT32_MAX) {
-        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_.IncrementKeyAccessCount(keyid)) {
-            ALOGE("Usage count-limited keys table full, until reboot.");
-            return ErrorCode::TOO_MANY_OPERATIONS;
-        }
-    }
-
-    return ErrorCode::OK;
-}
-
-class EvpMdCtx {
-  public:
-    EvpMdCtx() { EVP_MD_CTX_init(&ctx_); }
-    ~EvpMdCtx() { EVP_MD_CTX_cleanup(&ctx_); }
-
-    EVP_MD_CTX* get() { return &ctx_; }
-
-  private:
-    EVP_MD_CTX ctx_;
-};
-
-/* static */
-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 keyid;
-    }
-
-    return {};
-}
-
-bool KeymasterEnforcement::MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid) {
-    uint32_t last_access_time;
-    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) {
-    uint32_t key_access_count;
-    if (!access_count_map_.KeyAccessCount(keyid, &key_access_count)) return true;
-    return key_access_count < max_uses;
-}
-
-template <typename IntType, uint32_t byteOrder> struct choose_hton;
-
-template <typename IntType> struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> {
-    inline static IntType hton(const IntType& value) {
-        IntType result = 0;
-        const unsigned char* inbytes = reinterpret_cast<const unsigned char*>(&value);
-        unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result);
-        for (int i = sizeof(IntType) - 1; i >= 0; --i) {
-            *(outbytes++) = inbytes[i];
-        }
-        return result;
-    }
-};
-
-template <typename IntType> struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> {
-    inline static IntType hton(const IntType& value) { return value; }
-};
-
-template <typename IntType> inline IntType hton(const IntType& value) {
-    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
-}
-
-template <typename IntType> inline IntType ntoh(const IntType& value) {
-    // same operation and hton
-    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
-}
-
-bool KeymasterEnforcement::AuthTokenMatches(const AuthorizationSet& auth_set,
-                                            const HardwareAuthToken& auth_token,
-                                            const uint64_t user_secure_id,
-                                            const int auth_type_index, const int auth_timeout_index,
-                                            const uint64_t op_handle,
-                                            bool is_begin_operation) const {
-    assert(auth_type_index < static_cast<int>(auth_set.size()));
-    assert(auth_timeout_index < static_cast<int>(auth_set.size()));
-
-    if (!ValidateTokenSignature(auth_token)) {
-        ALOGE("Auth token signature invalid");
-        return false;
-    }
-
-    if (auth_timeout_index == -1 && op_handle && op_handle != auth_token.challenge) {
-        ALOGE("Auth token has the challenge %" PRIu64 ", need %" PRIu64, auth_token.challenge,
-              op_handle);
-        return false;
-    }
-
-    if (user_secure_id != auth_token.userId && user_secure_id != auth_token.authenticatorId) {
-        ALOGI("Auth token SIDs %" PRIu64 " and %" PRIu64 " do not match key SID %" PRIu64,
-              auth_token.userId, auth_token.authenticatorId, user_secure_id);
-        return false;
-    }
-
-    if (auth_type_index < 0 || auth_type_index > static_cast<int>(auth_set.size())) {
-        ALOGE("Auth required but no auth type found");
-        return false;
-    }
-
-    assert(auth_set[auth_type_index].tag == TAG_USER_AUTH_TYPE);
-    auto key_auth_type_mask = authorizationValue(TAG_USER_AUTH_TYPE, auth_set[auth_type_index]);
-    if (!key_auth_type_mask.isOk()) return false;
-
-    if ((uint32_t(key_auth_type_mask.value()) & auth_token.authenticatorType) == 0) {
-        ALOGE("Key requires match of auth type mask 0%uo, but token contained 0%uo",
-              key_auth_type_mask.value(), auth_token.authenticatorType);
-        return false;
-    }
-
-    if (auth_timeout_index != -1 && is_begin_operation) {
-        assert(auth_set[auth_timeout_index].tag == TAG_AUTH_TIMEOUT);
-        auto auth_token_timeout =
-            authorizationValue(TAG_AUTH_TIMEOUT, auth_set[auth_timeout_index]);
-        if (!auth_token_timeout.isOk()) return false;
-
-        if (auth_token_timed_out(auth_token, auth_token_timeout.value())) {
-            ALOGE("Auth token has timed out");
-            return false;
-        }
-    }
-
-    // Survived the whole gauntlet.  We have authentage!
-    return true;
-}
-
-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;
-            return true;
-        }
-    return false;
-}
-
-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;
-            return true;
-        }
-
-        // Expire entry if possible.
-        assert(current_time >= iter->access_time);
-        if (current_time - iter->access_time >= iter->timeout)
-            iter = last_access_list_.erase(iter);
-        else
-            ++iter;
-    }
-
-    if (last_access_list_.size() >= max_size_) return false;
-
-    AccessTime new_entry;
-    new_entry.keyid = keyid;
-    new_entry.access_time = current_time;
-    new_entry.timeout = timeout;
-    last_access_list_.push_front(new_entry);
-    return true;
-}
-
-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;
-            return true;
-        }
-    return false;
-}
-
-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
-            // uint32_t, and as soon as entry.access_count reaches the specified maximum value
-            // operation requests will be rejected and access_count won't be incremented any more.
-            // And, besides, UINT64_MAX is huge.  But we ensure that it doesn't wrap anyway, out of
-            // an abundance of caution.
-            if (entry.access_count < UINT64_MAX) ++entry.access_count;
-            return true;
-        }
-
-    if (access_count_list_.size() >= max_size_) return false;
-
-    AccessCount new_entry;
-    new_entry.keyid = keyid;
-    new_entry.access_count = 1;
-    access_count_list_.push_front(new_entry);
-    return true;
-}
-}; /* namespace keystore */
diff --git a/keystore/keymaster_enforcement.h b/keystore/keymaster_enforcement.h
deleted file mode 100644
index 9bfb225..0000000
--- a/keystore/keymaster_enforcement.h
+++ /dev/null
@@ -1,213 +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.
- */
-
-#ifndef KEYSTORE_KEYMASTER_ENFORCEMENT_H
-#define KEYSTORE_KEYMASTER_ENFORCEMENT_H
-
-#include <stdio.h>
-
-#include <keystore/keymaster_types.h>
-
-#include <list>
-#include <mutex>
-#include <optional>
-
-namespace keystore {
-
-typedef uint64_t km_id_t;
-
-class KeymasterEnforcementContext {
-  public:
-    virtual ~KeymasterEnforcementContext() {}
-    /*
-     * Get current time.
-     */
-};
-
-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:
-    /**
-     * Construct a KeymasterEnforcement.
-     */
-    KeymasterEnforcement(uint32_t max_access_time_map_size, uint32_t max_access_count_map_size);
-    virtual ~KeymasterEnforcement();
-
-    /**
-     * Iterates through the authorization set and returns the corresponding keymaster error. Will
-     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
-     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
-     */
-    ErrorCode AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid,
-                                 const AuthorizationSet& auth_set,
-                                 const AuthorizationSet& operation_params,
-                                 const HardwareAuthToken& auth_token, uint64_t op_handle,
-                                 bool is_begin_operation);
-
-    /**
-     * Iterates through the authorization set and returns the corresponding keymaster error. Will
-     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
-     * the given operation params. Used for encrypt, decrypt sign, and verify.
-     */
-    ErrorCode AuthorizeBegin(const KeyPurpose purpose, const km_id_t keyid,
-                             const AuthorizationSet& auth_set,
-                             const AuthorizationSet& operation_params,
-                             NullOr<const HardwareAuthToken&> auth_token);
-
-    /**
-     * Iterates through the authorization set and returns the corresponding keymaster error. Will
-     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
-     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
-     */
-    ErrorCode AuthorizeUpdate(const AuthorizationSet& auth_set, const HardwareAuthToken& auth_token,
-                              uint64_t op_handle) {
-        return AuthorizeUpdateOrFinish(auth_set, auth_token, op_handle);
-    }
-
-    /**
-     * Iterates through the authorization set and returns the corresponding keymaster error. Will
-     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
-     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
-     */
-    ErrorCode AuthorizeFinish(const AuthorizationSet& auth_set, const HardwareAuthToken& auth_token,
-                              uint64_t op_handle) {
-        return AuthorizeUpdateOrFinish(auth_set, auth_token, op_handle);
-    }
-
-    /**
-     * Creates a key ID for use in subsequent calls to AuthorizeOperation.  Clients needn't use this
-     * method of creating key IDs, as long as they use something consistent and unique.  This method
-     * hashes the key blob.
-     *
-     * Returns false if an error in the crypto library prevents creation of an ID.
-     */
-    static std::optional<km_id_t> CreateKeyId(const hidl_vec<uint8_t>& key_blob);
-
-    //
-    // Methods that must be implemented by subclasses
-    //
-    // The time-related methods address the fact that different enforcement contexts may have
-    // different time-related capabilities.  In particular:
-    //
-    // - They may or may not be able to check dates against real-world clocks.
-    //
-    // - They may or may not be able to check timestampls against authentication trustlets (minters
-    //   of hw_auth_token_t structs).
-    //
-    // - They must have some time source for relative times, but may not be able to provide more
-    //   than reliability and monotonicity.
-
-    /*
-     * Returns true if the specified activation date has passed, or if activation cannot be
-     * enforced.
-     */
-    virtual bool activation_date_valid(uint64_t activation_date) const = 0;
-
-    /*
-     * Returns true if the specified expiration date has passed.  Returns false if it has not, or if
-     * expiration cannot be enforced.
-     */
-    virtual bool expiration_date_passed(uint64_t expiration_date) const = 0;
-
-    /*
-     * Returns true if the specified auth_token is older than the specified timeout.
-     */
-    virtual bool auth_token_timed_out(const HardwareAuthToken& token, uint32_t timeout) const = 0;
-
-    /*
-     * Get current time in seconds from some starting point.  This value is used to compute relative
-     * times between events.  It must be monotonically increasing, and must not skip or lag.  It
-     * need not have any relation to any external time standard (other than the duration of
-     * "second").
-     *
-     * On POSIX systems, it's recommented to use clock_gettime(CLOCK_MONOTONIC, ...) to implement
-     * this method.
-     */
-    virtual uint32_t get_current_time() const = 0;
-
-    /*
-     * Returns true if the specified auth_token has a valid signature, or if signature validation is
-     * not available.
-     */
-    virtual bool ValidateTokenSignature(const HardwareAuthToken& token) const = 0;
-
-    /*
-     * Returns true if the device screen is currently locked for the specified user.
-     */
-    virtual bool is_device_locked(int32_t userId) const = 0;
-
-  private:
-    ErrorCode AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
-                                      const HardwareAuthToken& auth_token, uint64_t op_handle);
-
-    bool MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid);
-    bool MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses);
-    bool AuthTokenMatches(const AuthorizationSet& auth_set, const HardwareAuthToken& auth_token,
-                          const uint64_t user_secure_id, const int auth_type_index,
-                          const int auth_timeout_index, const uint64_t op_handle,
-                          bool is_begin_operation) const;
-
-    AccessTimeMap access_time_map_;
-    AccessCountMap access_count_map_;
-};
-
-}; /* namespace keystore */
-
-#endif  // KEYSTORE_KEYMASTER_ENFORCEMENT_H
diff --git a/keystore/keymaster_worker.cpp b/keystore/keymaster_worker.cpp
deleted file mode 100644
index cbb184c..0000000
--- a/keystore/keymaster_worker.cpp
+++ /dev/null
@@ -1,1144 +0,0 @@
-/*
-**
-** 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 <log/log_event_list.h>
-
-#include <private/android_logger.h>
-
-#include "KeyStore.h"
-#include "keymaster_enforcement.h"
-
-#include "key_creation_log_handler.h"
-#include "keystore_utils.h"
-
-#include <chrono>
-
-namespace keystore {
-
-using namespace std::chrono;
-
-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_);
-    terminate_ = true;
-    pending_requests_cond_var_.notify_all();
-    pending_requests_cond_var_.wait(lock, [this] { return !running_; });
-}
-void Worker::addRequest(WorkerTask request) {
-    std::unique_lock<std::mutex> lock(pending_requests_mutex_);
-    bool start_thread = !running_;
-    running_ = true;
-    pending_requests_.push(std::move(request));
-    lock.unlock();
-    pending_requests_cond_var_.notify_all();
-    if (start_thread) {
-        auto worker = std::thread([this] {
-            std::unique_lock<std::mutex> lock(pending_requests_mutex_);
-            while (running_) {
-                // Wait for 30s if the request queue is empty, then kill die.
-                // Die immediately if termiate_ was set which happens in the destructor.
-                auto status = pending_requests_cond_var_.wait_for(
-                    lock, 30s, [this]() { return !pending_requests_.empty() || terminate_; });
-                if (status && !terminate_) {
-                    auto request = std::move(pending_requests_.front());
-                    lock.unlock();
-                    request();
-                    lock.lock();
-                    pending_requests_.pop();
-                } else {
-                    running_ = false;
-                }
-                pending_requests_cond_var_.notify_all();
-            }
-        });
-        worker.detach();
-    }
-}
-
-KeymasterWorker::KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore,
-                                 SecurityLevel internalSecurityLevel)
-    : keymasterDevice_(std::move(keymasterDevice)), operationMap_(keyStore), keyStore_(keyStore),
-      internalSecurityLevel_(internalSecurityLevel) {
-    // make sure that hal version is cached.
-    if (keymasterDevice_) keymasterDevice_->halVersion();
-}
-
-void KeymasterWorker::logIfKeymasterVendorError(ErrorCode ec) const {
-    keymasterDevice_->logIfKeymasterVendorError(ec);
-}
-
-void KeymasterWorker::deleteOldKeyOnUpgrade(const LockedKeyBlobEntry& blobfile, Blob keyBlob) {
-    // if we got the blob successfully, we try and delete it from the keymaster device
-    auto& dev = keymasterDevice_;
-    uid_t uid = blobfile->uid();
-    const auto& alias = blobfile->alias();
-
-    if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
-        auto ret = KS_HANDLE_HIDL_ERROR(dev, 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()) {
-            android_log_event_list(SEC_TAG_KEY_DESTROYED)
-                << int32_t(success) << alias << int32_t(uid) << LOG_ID_SECURITY;
-        }
-        if (!success) {
-            LOG(ERROR) << "Keymaster delete for key " << alias << " of uid " << uid << " failed";
-        }
-    }
-}
-
-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) {
-        dev->logIfKeymasterVendorError(ret);
-        error = ret;
-        if (!error.isOk()) {
-            if (error == ErrorCode::INVALID_KEY_BLOB) {
-                log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
-            }
-            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;
-        }
-
-        deleteOldKeyOnUpgrade(lockedEntry, std::move(blob));
-        blob = std::move(newBlob);
-    };
-
-    KeyStoreServiceReturnCode error2;
-    error2 = KS_HANDLE_HIDL_ERROR(dev, 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) {
-        dev->logIfKeymasterVendorError(ret);
-        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, 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, 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,
-                                                 ResponseCode reason_for_abort) {
-    auto op = operationMap_.removeOperation(token, false /* wasOpSuccessful */,
-                                            static_cast<int32_t>(reason_for_abort));
-    if (op) {
-        keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
-        return KS_HANDLE_HIDL_ERROR(keymasterDevice_, 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, ResponseCode::PRUNED);
-    keyStore_->removeOperationDevice(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, 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) {
-            dev->logIfKeymasterVendorError(ret);
-            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, 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, 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, rc.getErrorCode());
-            keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
-            KS_HANDLE_HIDL_ERROR(keymasterDevice_, 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) {
-            op->device->logIfKeymasterVendorError(ret);
-            result.resultCode = ret;
-            if (result.resultCode.isOk()) {
-                result.inputConsumed = inputConsumed;
-                result.outParams = outParams;
-                result.data = output;
-            }
-        };
-
-        rc = KS_HANDLE_HIDL_ERROR(op->device,
-                                  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(), rc.getErrorCode());
-            keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
-            if (!finished)
-                KS_HANDLE_HIDL_ERROR(keymasterDevice_, 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, 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) {
-            op->device->logIfKeymasterVendorError(ret);
-            result.resultCode = ret;
-            if (result.resultCode.isOk()) {
-                result.outParams = outParams;
-                result.data = output;
-            }
-        };
-
-        rc = KS_HANDLE_HIDL_ERROR(op->device, 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, ResponseCode::ABORT_CALLED));
-    });
-}
-
-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_,
-            keymasterDevice_->verifyAuthorization(
-                challenge, params, token, [&](ErrorCode ret, const VerificationToken& vToken) {
-                    keymasterDevice_->logIfKeymasterVendorError(ret);
-                    error = ret;
-                    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_, 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([&] {
-            logKeystoreKeyCreationEvent(keyParams, false /*wasCreationSuccessful*/,
-                                        rc.getErrorCode());
-        });
-
-        KeyCharacteristics outCharacteristics;
-        KeyStoreServiceReturnCode error;
-        auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
-                           const KeyCharacteristics& keyCharacteristics) {
-            keymasterDevice_->logIfKeymasterVendorError(ret);
-            error = ret;
-            if (!error.isOk()) {
-                return;
-            }
-            consider_fallback = false;
-            outCharacteristics = keyCharacteristics;
-
-            Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
-            keyBlob.setSecurityLevel(internalSecurityLevel_);
-            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_,
-                                  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();
-        logKeystoreKeyCreationEvent(keyParams, true /*wasCreationSuccessful*/,
-                                    error.getErrorCode());
-
-        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;
-
-        KeyStoreServiceReturnCode error;
-        Finalize logOnFail([&] {
-            logKeystoreKeyCreationEvent(keyParams, false /*wasCreationSuccessful*/,
-                                        error.getErrorCode());
-        });
-
-        KeyCharacteristics outCharacteristics;
-        auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
-                           const KeyCharacteristics& keyCharacteristics) {
-            keymasterDevice_->logIfKeymasterVendorError(ret);
-            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(internalSecurityLevel_);
-            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_, 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();
-        logKeystoreKeyCreationEvent(keyParams, true /*wasCreationSuccessful*/,
-                                    error.getErrorCode());
-
-        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);
-
-        KeyCharacteristics outCharacteristics;
-        KeyStoreServiceReturnCode error;
-
-        auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
-                          const KeyCharacteristics& keyCharacteristics) {
-            keymasterDevice_->logIfKeymasterVendorError(ret);
-            error = ret;
-            if (!error.isOk()) {
-                return;
-            }
-            outCharacteristics = keyCharacteristics;
-
-            Blob keyBlob(hidlKeyBlob.data(), hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
-            keyBlob.setSecurityLevel(internalSecurityLevel_);
-            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_, 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_,
-                                      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) {
-            keymasterDevice_->logIfKeymasterVendorError(ret);
-            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_,
-            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_,
-                                      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::deleteKey(hidl_vec<uint8_t> keyBlob, deleteKey_cb _hidl_cb) {
-    addRequest(&Keymaster::deleteKey, std::move(_hidl_cb), std::move(keyBlob));
-}
-
-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, ResponseCode::BINDER_DIED);
-            keyStore_->removeOperationDevice(token);
-        }
-    });
-}
-
-}  // namespace keystore
diff --git a/keystore/keymaster_worker.h b/keystore/keymaster_worker.h
deleted file mode 100644
index fbd52b4..0000000
--- a/keystore/keymaster_worker.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
-**
-** 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_1/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/keymaster_types.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_1::support::Keymaster;
-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;
-    bool terminate_ = 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_;
-
-    /**
-     * Models the security level of this worker internal to KeyStore.
-     *
-     * When the device has only a software Keymaster, KeyStore will set it on the TEE slot and
-     * instantiate a new in-process software Keymaster. In that case there is a mismatch between the
-     * security level used by KeyStore and what is reported from the HAL. This represents the level
-     * used internally by KeyStore.
-     *
-     * This value is used to associate blobs to the corresponding Keymaster backend. It does not
-     * indicate an actual Keymaster HAL security level and should never be exposed to users.
-     */
-    SecurityLevel internalSecurityLevel_;
-
-    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...>{});
-        });
-    }
-
-    void deleteOldKeyOnUpgrade(const LockedKeyBlobEntry& blobfile, Blob keyBlob);
-    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, ResponseCode reason_for_abort);
-
-    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,
-                    SecurityLevel internalSecurityLevel);
-
-    void logIfKeymasterVendorError(ErrorCode ec) const;
-
-    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 deleteKey_cb = MakeKeymasterWorkerCB_t<Return<ErrorCode>>;
-    void deleteKey(hidl_vec<uint8_t> keyBlob, deleteKey_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.rc b/keystore/keystore.rc
deleted file mode 100644
index 132039a..0000000
--- a/keystore/keystore.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service keystore /system/bin/keystore /data/misc/keystore
-    class main
-    user keystore
-    group keystore drmrpc readproc log
-    writepid /dev/cpuset/foreground/tasks
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.cpp b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
deleted file mode 100644
index 823ca58..0000000
--- a/keystore/keystore_aidl_hidl_marshalling_utils.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-**
-** Copyright 2016, 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_aidl_hidl_marshalling_utils.h"
-
-#include <keystore/ExportResult.h>
-#include <keystore/KeyCharacteristics.h>
-#include <keystore/KeymasterBlob.h>
-#include <keystore/KeymasterCertificateChain.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) {
-
-    ssize_t length = in.readInt32();
-    if (length <= 0) {
-        return {};
-    }
-
-    const void* buf = in.readInplace(length);
-    if (!buf) return {};
-
-    return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length));
-}
-
-android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out) {
-    int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max()));
-
-    auto rc = out->writeInt32(size);
-    if (rc != ::android::OK) return rc;
-
-    if (!size) return ::android::OK;
-
-    return out->write(blob.data(), size);
-}
-
-android::status_t writeKeymasterBlob(const ::std::vector<int32_t>& blob, android::Parcel* out) {
-
-    int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max()));
-
-    auto rc = out->writeInt32(size);
-    if (rc != ::android::OK) return rc;
-
-    if (!size) return ::android::OK;
-
-    return out->write(blob.data(), size);
-}
-
-NullOr<KeyParameter> readKeyParameterFromParcel(const android::Parcel& in) {
-    // Method must be in sync with KeymasterArgument.java
-    if (in.readInt32() == 0) {
-        return {};
-    }
-    KeyParameter result;
-
-    Tag tag = static_cast<Tag>(in.readInt32());
-    result.tag = tag;
-    switch (typeFromTag(tag)) {
-    case TagType::ENUM:
-    case TagType::ENUM_REP:
-    case TagType::UINT:
-    case TagType::UINT_REP:
-        result.f.integer = in.readInt32();
-        break;
-    case TagType::ULONG:
-    case TagType::ULONG_REP:
-    case TagType::DATE:
-        result.f.longInteger = in.readInt64();
-        break;
-    case TagType::BOOL:
-        result.f.boolValue = true;
-        break;
-    case TagType::BIGNUM:
-    case TagType::BYTES:
-        result.blob = readKeymasterBlob(in);  // byte array
-        break;
-    default:
-        ALOGE("Unsupported KeyParameter tag %d", tag);
-        return {};
-    }
-    return result;
-}
-
-android::status_t writeKeyParameterToParcel(const KeyParameter& param, android::Parcel* out) {
-    // Method must be in sync with with KeymasterArgument.java
-    // Presence flag must be written by caller.
-
-    auto tag = param.tag;
-    auto rc = out->writeInt32(uint32_t(tag));
-    if (rc != ::android::OK) return rc;
-    switch (typeFromTag(param.tag)) {
-    case TagType::ENUM:
-    case TagType::ENUM_REP:
-    case TagType::UINT:
-    case TagType::UINT_REP:
-        rc = out->writeInt32(param.f.integer);
-        break;
-    case TagType::ULONG:
-    case TagType::ULONG_REP:
-    case TagType::DATE:
-        rc = out->writeInt64(param.f.longInteger);
-        break;
-    case TagType::BOOL:
-        // nothing to do here presence indicates true
-        break;
-    case TagType::BIGNUM:
-    case TagType::BYTES:
-        rc = writeKeymasterBlob(param.blob, out);
-        break;
-    default:
-        ALOGE("Failed to write KeyParameter: Unsupported tag %d", param.tag);
-        rc = android::BAD_VALUE;
-        break;
-    }
-    return rc;
-}
-
-hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in) {
-
-    ssize_t length = in.readInt32();  // -1 for null
-    size_t ulength = (size_t)length;
-    if (length < 0) {
-        ulength = 0;
-    }
-    hidl_vec<KeyParameter> result;
-    result.resize(ulength);
-    for (size_t i = 0; i < ulength; ++i) {
-        auto param = readKeyParameterFromParcel(in);
-        if (!param.isOk()) {
-            ALOGE("Error reading KeyParameter from parcel");
-            return {};
-        }
-        result[i] = param.value();
-    }
-    return result;
-}
-
-android::status_t writeParamSetToParcel(const hidl_vec<KeyParameter>& params,
-                                        android::Parcel* out) {
-    int32_t size = int32_t(std::min<size_t>(params.size(), std::numeric_limits<int32_t>::max()));
-
-    auto rc = out->writeInt32(size);
-    if (rc != ::android::OK) return rc;
-    for (int32_t i = 0; i < size; ++i) {
-        rc = out->writeInt32(1);  // writeTypedObject presence flag.
-        if (rc != ::android::OK) return rc;
-        rc = writeKeyParameterToParcel(params[i], out);
-        if (rc != ::android::OK) return rc;
-    }
-    return rc;
-}
-
-hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in) {
-    hidl_vec<hidl_vec<uint8_t>> result;
-
-    ssize_t count = in.readInt32();
-    size_t ucount = count;
-    if (count <= 0) {
-        return result;
-    }
-
-    result.resize(ucount);
-
-    for (size_t i = 0; i < ucount; ++i) {
-        result[i] = readKeymasterBlob(in);
-    }
-    return result;
-};
-
-android::status_t writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>>& certs,
-                                                android::Parcel* out) {
-    int32_t count = int32_t(std::min<size_t>(certs.size(), std::numeric_limits<int32_t>::max()));
-    auto rc = out->writeInt32(count);
-
-    for (int32_t i = 0; i < count; ++i) {
-        rc = writeKeymasterBlob(certs[i], out);
-        if (rc != ::android::OK) return rc;
-    }
-    return rc;
-}
-
-};  // namespace keystore
-
-// Implementation for  keystore parcelables.
-// TODO: split implementation into separate classes
-namespace android {
-namespace security {
-namespace keymaster {
-
-using ::android::status_t;
-using ::keystore::ErrorCode;
-
-ExportResult::ExportResult() : resultCode() {}
-
-ExportResult::~ExportResult() {}
-
-status_t ExportResult::readFromParcel(const Parcel* inn) {
-    const Parcel& in = *inn;
-    resultCode = ErrorCode(in.readInt32());
-    exportData = keystore::readKeymasterBlob(in);
-    return OK;
-}
-
-status_t ExportResult::writeToParcel(Parcel* out) const {
-    out->writeInt32(resultCode.getErrorCode());
-    return keystore::writeKeymasterBlob(exportData, out);
-}
-
-status_t KeyCharacteristics::readFromParcel(const Parcel* in) {
-    softwareEnforced.readFromParcel(in);
-    return hardwareEnforced.readFromParcel(in);
-}
-
-status_t KeyCharacteristics::writeToParcel(Parcel* out) const {
-    softwareEnforced.writeToParcel(out);
-    return hardwareEnforced.writeToParcel(out);
-}
-
-status_t KeymasterBlob::readFromParcel(const Parcel* in) {
-    data_ = keystore::readKeymasterBlob(*in);
-    return OK;
-}
-
-status_t KeymasterBlob::writeToParcel(Parcel* out) const {
-    return keystore::writeKeymasterBlob(data_, out);
-}
-
-status_t KeymasterCertificateChain::readFromParcel(const Parcel* in) {
-    chain = keystore::readCertificateChainFromParcel(*in);
-    return OK;
-}
-
-status_t KeymasterCertificateChain::writeToParcel(Parcel* out) const {
-    return keystore::writeCertificateChainToParcel(chain, out);
-}
-
-}  // namespace keymaster
-}  // namespace security
-
-}  // namespace android
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.h b/keystore/keystore_aidl_hidl_marshalling_utils.h
deleted file mode 100644
index ea72197..0000000
--- a/keystore/keystore_aidl_hidl_marshalling_utils.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-**
-** Copyright 2016, 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_KEYSTORE_AIDL_HIDL_MARSHALLING_UTILS_H_
-#define KEYSTORE_KEYSTORE_AIDL_HIDL_MARSHALLING_UTILS_H_
-
-#include <utility>
-
-#include <binder/Parcel.h>
-
-#include <keystore/keymaster_types.h>
-
-namespace keystore {
-
-template <typename Fn, typename... Args>
-inline auto nullable(Fn fn, const android::Parcel& in, Args&&... args)
-    -> NullOr<decltype(fn(in, std::forward<Args>(args)...))> {
-    if (in.readInt32() != 1) {
-        return {};
-    }
-
-    return fn(in, std::forward<Args>(args)...);
-}
-template <typename Fn, typename Arg>
-inline android::status_t nullable(Fn fn, const NullOr<Arg>& arg, android::Parcel* out) {
-    if (!arg.isOk()) {
-        return out->writeInt32(0);
-    }
-    auto rc = out->writeInt32(1);
-    if (rc != ::android::OK) return rc;
-
-    return fn(arg.value(), out);
-}
-template <typename Fn, typename Arg>
-inline android::status_t nullable(Fn fn, Arg&& arg, android::Parcel* out) {
-    auto rc = out->writeInt32(1);
-    if (rc != ::android::OK) return rc;
-
-    return fn(std::forward<Arg>(arg), out);
-}
-
-inline android::status_t nullable(android::Parcel* out) {
-    return out->writeInt32(0);
-}
-
-/**
- * makes a copy only if inPlace is false
- */
-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);
-android::status_t writeBlobAsByteArray(const NullOr<const hidl_vec<uint8_t>&>& blob,
-                                       android::Parcel* out);
-
-NullOr<KeyParameter> readKeyParameterFromParcel(const android::Parcel& in);
-android::status_t writeKeyParameterToParcel(const KeyParameter& param, android::Parcel* out);
-
-hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in);
-android::status_t writeParamSetToParcel(const hidl_vec<KeyParameter>& params, android::Parcel* out);
-
-hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in);
-}
-
-#endif  // KEYSTORE_KEYSTORE_AIDL_HIDL_MARSHALLING_UTILS_H_
diff --git a/keystore/keystore_cli.cpp b/keystore/keystore_cli.cpp
deleted file mode 100644
index 428a9bc..0000000
--- a/keystore/keystore_cli.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2009 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 <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-#include <vector>
-
-#include <android/security/keystore/IKeystoreService.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <keystore/keystore.h>
-
-using namespace android;
-using namespace keystore;
-using android::security::keystore::IKeystoreService;
-
-static const char* responses[] = {
-    nullptr,
-    /* [NO_ERROR]           = */ "No error",
-    /* [LOCKED]             = */ "Locked",
-    /* [UNINITIALIZED]      = */ "Uninitialized",
-    /* [SYSTEM_ERROR]       = */ "System error",
-    /* [PROTOCOL_ERROR]     = */ "Protocol error",
-    /* [PERMISSION_DENIED]  = */ "Permission denied",
-    /* [KEY_NOT_FOUND]      = */ "Key not found",
-    /* [VALUE_CORRUPTED]    = */ "Value corrupted",
-    /* [UNDEFINED_ACTION]   = */ "Undefined action",
-    /* [WRONG_PASSWORD]     = */ "Wrong password (last chance)",
-    /* [WRONG_PASSWORD + 1] = */ "Wrong password (2 tries left)",
-    /* [WRONG_PASSWORD + 2] = */ "Wrong password (3 tries left)",
-    /* [WRONG_PASSWORD + 3] = */ "Wrong password (4 tries left)",
-};
-
-#define SINGLE_ARG_INT_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
-                return 1; \
-            } \
-            int32_t ret = -1; \
-            service->cmd(String16(argv[2]), &ret); \
-            if (ret < 0) { \
-                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
-                return 1; \
-            } else { \
-                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-#define SINGLE_INT_ARG_INT_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
-                return 1; \
-            } \
-            int32_t ret = -1; \
-            service->cmd(atoi(argv[2]), &ret); \
-            if (ret < 0) { \
-                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
-                return 1; \
-            } else { \
-                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-#define SINGLE_ARG_PLUS_UID_INT_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name> <uid>\n", argv[0]); \
-                return 1; \
-            } \
-            int uid = -1; \
-            if (argc > 3) { \
-                uid = atoi(argv[3]); \
-                fprintf(stderr, "Running as uid %d\n", uid); \
-            } \
-            int32_t ret = -1; \
-            service->cmd(String16(argv[2]), uid, &ret); \
-            if (ret < 0) { \
-                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
-                return 1; \
-            } else { \
-                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-#define SINGLE_ARG_PLUS_UID_DATA_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name> <uid>\n", argv[0]); \
-                return 1; \
-            } \
-            std::vector<uint8_t> data; \
-            int uid = -1; \
-            if (argc > 3) { \
-                uid = atoi(argv[3]); \
-                fprintf(stderr, "Running as uid %d\n", uid); \
-            } \
-            ::android::binder::Status ret = service->cmd(String16(argv[2]), uid, &data); \
-            if (!ret.isOk()) { \
-                fprintf(stderr, "Exception code: %d\n", ret.exceptionCode()); \
-                return 1; \
-            } else { \
-                fwrite(&data[0], data.size(), 1, stdout); \
-                fflush(stdout); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-#define STRING_ARG_DATA_STDIN_INT_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
-                return 1; \
-            } \
-            uint8_t* data; \
-            size_t dataSize; \
-            read_input(&data, &dataSize); \
-            int32_t ret = -1; \
-            service->cmd(String16(argv[2]), data, dataSize, &ret); \
-            if (ret < 0) { \
-                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
-                return 1; \
-            } else { \
-                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-#define SINGLE_ARG_DATA_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
-                return 1; \
-            } \
-            std::vector<uint8_t> data; \
-            ::android::binder::Status ret = service->cmd(String16(argv[2]), &data); \
-            if (!ret.isOk()) { \
-                fprintf(stderr, "Exception code: %d\n", ret.exceptionCode()); \
-                return 1; \
-            } else { \
-                fwrite(&data[0], data.size(), 1, stdout); \
-                fflush(stdout); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-static int list(const sp<IKeystoreService>& service, const String16& name, int uid) {
-    std::vector<String16> matches;
-    ::android::binder::Status ret = service->list(name, uid, &matches);
-
-    if (!ret.isOk()) {
-        fprintf(stderr, "list: exception (%d)\n", ret.exceptionCode());
-        return 1;
-    } else {
-        std::vector<String16>::const_iterator it = matches.begin();
-        for (; it != matches.end(); ++it) {
-            printf("%s\n", String8(*it).string());
-        }
-        return 0;
-    }
-}
-
-int main(int argc, char* argv[])
-{
-    if (argc < 2) {
-        fprintf(stderr, "Usage: %s action [parameter ...]\n", argv[0]);
-        return 1;
-    }
-
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-
-    if (service == nullptr) {
-        fprintf(stderr, "%s: error: could not connect to keystore service\n", argv[0]);
-        return 1;
-    }
-
-    /*
-     * All the commands should return a value
-     */
-
-    SINGLE_INT_ARG_INT_RETURN(getState);
-
-    SINGLE_ARG_PLUS_UID_DATA_RETURN(get);
-
-    // TODO: insert
-
-    SINGLE_ARG_PLUS_UID_INT_RETURN(del);
-
-    SINGLE_ARG_PLUS_UID_INT_RETURN(exist);
-
-    if (strcmp(argv[1], "list") == 0) {
-        return list(service, argc < 3 ? String16("") : String16(argv[2]),
-                argc < 4 ? -1 : atoi(argv[3]));
-    }
-
-    // TODO: notifyUserPasswordChanged
-
-    SINGLE_INT_ARG_INT_RETURN(lock);
-
-    // TODO: unlock
-
-    SINGLE_INT_ARG_INT_RETURN(isEmpty);
-
-    // TODO: generate
-
-    // TODO: grant
-
-    // TODO: ungrant
-
-    // TODO: getmtime
-
-    fprintf(stderr, "%s: unknown command: %s\n", argv[0], argv[1]);
-    return 1;
-}
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index 4f69eb0..6e45ee2 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -15,6 +15,8 @@
 #include <chrono>
 #include <cstdio>
 #include <future>
+#include <iomanip>
+#include <iostream>
 #include <memory>
 #include <string>
 #include <vector>
@@ -24,38 +26,56 @@
 #include <base/strings/string_number_conversions.h>
 #include <base/strings/string_split.h>
 #include <base/strings/string_util.h>
-#include <base/strings/utf_string_conversions.h>
-#include <base/threading/platform_thread.h>
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore_client_impl.h>
 
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <android/security/BnConfirmationPromptCallback.h>
-#include <android/security/keystore/IKeystoreService.h>
+#include <aidl/android/security/apc/BnConfirmationCallback.h>
+#include <aidl/android/security/apc/IProtectedConfirmation.h>
+#include <aidl/android/system/keystore2/IKeystoreService.h>
+#include <aidl/android/system/keystore2/ResponseCode.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <keymint_support/authorization_set.h>
 
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
+#include <openssl/evp.h>
+#include <openssl/mem.h>
+#include <openssl/x509.h>
 
-//#include <keystore/keystore.h>
+#include "keystore_client.pb.h"
+
+namespace apc = ::aidl::android::security::apc;
+namespace keymint = ::aidl::android::hardware::security::keymint;
+namespace ks2 = ::aidl::android::system::keystore2;
 
 using base::CommandLine;
-using keystore::KeystoreClient;
-
-using android::sp;
-using android::String16;
-using android::security::keystore::IKeystoreService;
-using base::CommandLine;
-using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
+using keystore::EncryptedData;
 
 namespace {
-using namespace keystore;
 
 struct TestCase {
     std::string name;
     bool required_for_brillo_pts;
-    AuthorizationSet parameters;
+    keymint::AuthorizationSet parameters;
 };
 
+constexpr const char keystore2_service_name[] = "android.system.keystore2";
+
+int unwrapError(const ndk::ScopedAStatus& status) {
+    if (status.isOk()) return 0;
+    if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+        return status.getServiceSpecificError();
+    } else {
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+}
+
+ks2::KeyDescriptor keyDescriptor(const std::string& alias) {
+    return {
+        .domain = ks2::Domain::APP,
+        .nspace = -1,  // ignored - should be -1.
+        .alias = alias,
+        .blob = {},
+    };
+}
+
 void PrintUsageAndExit() {
     printf("Usage: keystore_client_v2 <command> [options]\n");
     printf("Commands: brillo-platform-test [--prefix=<test_name_prefix>] [--test_for_0_3]\n"
@@ -78,52 +98,487 @@
     exit(1);
 }
 
-std::unique_ptr<KeystoreClient> CreateKeystoreInstance() {
-    return std::unique_ptr<KeystoreClient>(
-        static_cast<KeystoreClient*>(new keystore::KeystoreClientImpl));
+std::shared_ptr<ks2::IKeystoreService> CreateKeystoreInstance() {
+    ::ndk::SpAIBinder keystoreBinder(AServiceManager_checkService(keystore2_service_name));
+    auto result = ks2::IKeystoreService::fromBinder(keystoreBinder);
+    if (result) return result;
+    std::cerr << "Unable to connect to Keystore.";
+    exit(-1);
 }
 
-void PrintTags(const AuthorizationSet& parameters) {
-    for (auto iter = parameters.begin(); iter != parameters.end(); ++iter) {
-        auto tag_str = toString(iter->tag);
-        printf("  %s\n", tag_str.c_str());
+std::shared_ptr<ks2::IKeystoreSecurityLevel>
+GetSecurityLevelInterface(std::shared_ptr<ks2::IKeystoreService> keystore,
+                          keymint::SecurityLevel securitylevel) {
+    std::shared_ptr<ks2::IKeystoreSecurityLevel> sec_level;
+    auto rc = keystore->getSecurityLevel(securitylevel, &sec_level);
+    if (rc.isOk()) return sec_level;
+    std::cerr << "Unable to get security level interface from Keystore: " << rc.getDescription();
+    exit(-1);
+}
+
+bool isHardwareEnforced(const ks2::Authorization& a) {
+    return !(a.securityLevel == keymint::SecurityLevel::SOFTWARE ||
+             a.securityLevel == keymint::SecurityLevel::KEYSTORE);
+}
+
+void PrintTags(const std::vector<ks2::Authorization>& characteristics, bool printHardwareEnforced) {
+    for (const auto& a : characteristics) {
+        if (isHardwareEnforced(a) == printHardwareEnforced) {
+            std::cout << toString(a.keyParameter.tag) << "\n";
+        }
     }
 }
 
-void PrintKeyCharacteristics(const AuthorizationSet& hardware_enforced_characteristics,
-                             const AuthorizationSet& software_enforced_characteristics) {
+void PrintKeyCharacteristics(const std::vector<ks2::Authorization>& characteristics) {
     printf("Hardware:\n");
-    PrintTags(hardware_enforced_characteristics);
+    PrintTags(characteristics, true /* printHardwareEnforced */);
     printf("Software:\n");
-    PrintTags(software_enforced_characteristics);
+    PrintTags(characteristics, false /* printHardwareEnforced */);
 }
 
-bool TestKey(const std::string& name, bool required, const AuthorizationSet& parameters) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    AuthorizationSet hardware_enforced_characteristics;
-    AuthorizationSet software_enforced_characteristics;
-    auto result =
-        keystore->generateKey("tmp", parameters, 0 /*flags*/, &hardware_enforced_characteristics,
-                              &software_enforced_characteristics);
+const char kEncryptSuffix[] = "_ENC";
+const char kAuthenticateSuffix[] = "_AUTH";
+constexpr uint32_t kAESKeySize = 256;      // bits
+constexpr uint32_t kHMACKeySize = 256;     // bits
+constexpr uint32_t kHMACOutputSize = 256;  // bits
+
+bool verifyEncryptionKeyAttributes(const std::vector<ks2::Authorization> authorizations) {
+    bool verified = true;
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::ALGORITHM &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::algorithm>(
+                           keymint::Algorithm::AES);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::KEY_SIZE &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
+                           kAESKeySize);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::BLOCK_MODE &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::blockMode>(
+                           keymint::BlockMode::CBC);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::PADDING &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::paddingMode>(
+                           keymint::PaddingMode::PKCS7);
+        });
+
+    return verified;
+}
+
+bool verifyAuthenticationKeyAttributes(const std::vector<ks2::Authorization> authorizations) {
+    bool verified = true;
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::ALGORITHM &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::algorithm>(
+                           keymint::Algorithm::HMAC);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::KEY_SIZE &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
+                           kHMACKeySize);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::MIN_MAC_LENGTH &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
+                           kHMACOutputSize);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::DIGEST &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::digest>(
+                           keymint::Digest::SHA_2_256);
+        });
+    return verified;
+}
+
+std::variant<int, ks2::KeyEntryResponse>
+loadOrCreateAndVerifyEncryptionKey(const std::string& name, keymint::SecurityLevel securityLevel,
+                                   bool create) {
+    auto keystore = CreateKeystoreInstance();
+
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    bool foundKey = true;
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        auto error = unwrapError(rc);
+        if (ks2::ResponseCode(error) == ks2::ResponseCode::KEY_NOT_FOUND && create) {
+            foundKey = false;
+        } else {
+            std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
+            return error;
+        }
+    }
+
+    if (!foundKey) {
+        auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
+        auto params = keymint::AuthorizationSetBuilder()
+                          .AesEncryptionKey(kAESKeySize)
+                          .Padding(keymint::PaddingMode::PKCS7)
+                          .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC)
+                          .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
+
+        ks2::KeyMetadata keyMetadata;
+
+        rc = sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */,
+                                    params.vector_data(), 0 /* flags */, {} /* entropy */,
+                                    &keyMetadata);
+        if (!rc.isOk()) {
+            std::cerr << "Failed to generate key: " << rc.getDescription() << std::endl;
+            return unwrapError(rc);
+        }
+
+        rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+        if (!rc.isOk()) {
+            std::cerr << "Failed to get key entry (second try): " << rc.getDescription()
+                      << std::endl;
+            return unwrapError(rc);
+        }
+    }
+
+    if (!verifyEncryptionKeyAttributes(keyEntryResponse.metadata.authorizations)) {
+        std::cerr << "Key has wrong set of parameters." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::INVALID_ARGUMENT);
+    }
+
+    return keyEntryResponse;
+}
+
+std::variant<int, ks2::KeyEntryResponse>
+loadOrCreateAndVerifyAuthenticationKey(const std::string& name,
+                                       keymint::SecurityLevel securityLevel, bool create) {
+    auto keystore = CreateKeystoreInstance();
+
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    bool foundKey = true;
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        auto error = unwrapError(rc);
+        if (ks2::ResponseCode(error) == ks2::ResponseCode::KEY_NOT_FOUND && create) {
+            foundKey = false;
+        } else {
+            std::cerr << "Failed to get HMAC key entry: " << rc.getDescription() << std::endl;
+            return error;
+        }
+    }
+
+    if (!foundKey) {
+        auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
+        auto params = keymint::AuthorizationSetBuilder()
+                          .HmacKey(kHMACKeySize)
+                          .Digest(keymint::Digest::SHA_2_256)
+                          .Authorization(keymint::TAG_MIN_MAC_LENGTH, kHMACOutputSize)
+                          .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
+
+        ks2::KeyMetadata keyMetadata;
+
+        rc = sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */,
+                                    params.vector_data(), 0 /* flags */, {} /* entropy */,
+                                    &keyMetadata);
+        if (!rc.isOk()) {
+            std::cerr << "Failed to generate HMAC key: " << rc.getDescription() << std::endl;
+            return unwrapError(rc);
+        }
+
+        rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+        if (!rc.isOk()) {
+            std::cerr << "Failed to get HMAC key entry (second try): " << rc.getDescription()
+                      << std::endl;
+            return unwrapError(rc);
+        }
+    }
+
+    if (!verifyAuthenticationKeyAttributes(keyEntryResponse.metadata.authorizations)) {
+        std::cerr << "Key has wrong set of parameters." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::INVALID_ARGUMENT);
+    }
+
+    return keyEntryResponse;
+}
+
+std::variant<int, std::vector<uint8_t>>
+encryptWithAuthentication(const std::string& name, const std::vector<uint8_t>& data,
+                          keymint::SecurityLevel securityLevel) {
+    // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random
+    // IV. The authentication algorithm is HMAC-SHA256 and is computed over the
+    // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM
+    // because hardware support for GCM is not mandatory for all Brillo devices.
+    std::string encryption_key_name = name + kEncryptSuffix;
+    auto encryption_key_result =
+        loadOrCreateAndVerifyEncryptionKey(encryption_key_name, securityLevel, true /* create */);
+    if (auto error = std::get_if<int>(&encryption_key_result)) {
+        return *error;
+    }
+    auto encryption_key = std::get<ks2::KeyEntryResponse>(encryption_key_result);
+
+    std::string authentication_key_name = name + kAuthenticateSuffix;
+    auto authentication_key_result = loadOrCreateAndVerifyAuthenticationKey(
+        authentication_key_name, securityLevel, true /* create */);
+    if (auto error = std::get_if<int>(&authentication_key_result)) {
+        return *error;
+    }
+    auto authentication_key = std::get<ks2::KeyEntryResponse>(authentication_key_result);
+
+    ks2::CreateOperationResponse encOperationResponse;
+    auto encrypt_params = keymint::AuthorizationSetBuilder()
+                              .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::ENCRYPT)
+                              .Padding(keymint::PaddingMode::PKCS7)
+                              .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
+
+    auto rc = encryption_key.iSecurityLevel->createOperation(
+        encryption_key.metadata.key, encrypt_params.vector_data(), false /* forced */,
+        &encOperationResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to begin encryption operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    std::optional<std::vector<uint8_t>> optCiphertext;
+
+    rc = encOperationResponse.iOperation->finish(data, {}, &optCiphertext);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    std::vector<uint8_t> initVector;
+    if (auto params = encOperationResponse.parameters) {
+        for (auto& p : params->keyParameter) {
+            if (auto iv = keymint::authorizationValue(keymint::TAG_NONCE, p)) {
+                initVector = std::move(iv->get());
+                break;
+            }
+        }
+        if (initVector.empty()) {
+            std::cerr << "Encryption operation did not return an IV." << std::endl;
+            return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+        }
+    }
+
+    if (!optCiphertext) {
+        std::cerr << "Encryption succeeded but no ciphertext returned." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    auto ciphertext = std::move(*optCiphertext);
+    auto toBeSigned = initVector;
+    toBeSigned.insert(toBeSigned.end(), ciphertext.begin(), ciphertext.end());
+
+    ks2::CreateOperationResponse signOperationResponse;
+    auto sign_params = keymint::AuthorizationSetBuilder()
+                           .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::SIGN)
+                           .Digest(keymint::Digest::SHA_2_256)
+                           .Authorization(keymint::TAG_MAC_LENGTH, kHMACOutputSize);
+
+    rc = authentication_key.iSecurityLevel->createOperation(
+        authentication_key.metadata.key, sign_params.vector_data(), false /* forced */,
+        &signOperationResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to begin signing operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    std::optional<std::vector<uint8_t>> optMac;
+
+    rc = signOperationResponse.iOperation->finish(toBeSigned, {}, &optMac);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    if (!optMac) {
+        std::cerr << "Signing succeeded but no MAC returned." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    auto mac = std::move(*optMac);
+
+    EncryptedData protobuf;
+    protobuf.set_init_vector(initVector.data(), initVector.size());
+    protobuf.set_authentication_data(mac.data(), mac.size());
+    protobuf.set_encrypted_data(ciphertext.data(), ciphertext.size());
+    std::string resultString;
+    if (!protobuf.SerializeToString(&resultString)) {
+        std::cerr << "Encrypt: Failed to serialize EncryptedData protobuf.";
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    std::vector<uint8_t> result(reinterpret_cast<const uint8_t*>(resultString.data()),
+                                reinterpret_cast<const uint8_t*>(resultString.data()) +
+                                    resultString.size());
+    return result;
+}
+
+std::variant<int, std::vector<uint8_t>>
+decryptWithAuthentication(const std::string& name, const std::vector<uint8_t>& data) {
+
+    // Decode encrypted data
+    EncryptedData protobuf;
+    if (!protobuf.ParseFromArray(data.data(), data.size())) {
+        std::cerr << "Decrypt: Failed to parse EncryptedData protobuf." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    // Load encryption and authentication keys.
+    std::string encryption_key_name = name + kEncryptSuffix;
+    auto encryption_key_result = loadOrCreateAndVerifyEncryptionKey(
+        encryption_key_name, keymint::SecurityLevel::KEYSTORE /* ignored */, false /* create */);
+    if (auto error = std::get_if<int>(&encryption_key_result)) {
+        return *error;
+    }
+    auto encryption_key = std::get<ks2::KeyEntryResponse>(encryption_key_result);
+
+    std::string authentication_key_name = name + kAuthenticateSuffix;
+    auto authentication_key_result = loadOrCreateAndVerifyAuthenticationKey(
+        authentication_key_name, keymint::SecurityLevel::KEYSTORE /* ignored */,
+        false /* create */);
+    if (auto error = std::get_if<int>(&authentication_key_result)) {
+        return *error;
+    }
+    auto authentication_key = std::get<ks2::KeyEntryResponse>(authentication_key_result);
+
+    // Begin authentication operation
+    ks2::CreateOperationResponse signOperationResponse;
+    auto sign_params = keymint::AuthorizationSetBuilder()
+                           .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::VERIFY)
+                           .Digest(keymint::Digest::SHA_2_256)
+                           .Authorization(keymint::TAG_MAC_LENGTH, kHMACOutputSize);
+
+    auto rc = authentication_key.iSecurityLevel->createOperation(
+        authentication_key.metadata.key, sign_params.vector_data(), false /* forced */,
+        &signOperationResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to begin verify operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    const uint8_t* p = reinterpret_cast<const uint8_t*>(protobuf.init_vector().data());
+    std::vector<uint8_t> toBeVerified(p, p + protobuf.init_vector().size());
+
+    p = reinterpret_cast<const uint8_t*>(protobuf.encrypted_data().data());
+    toBeVerified.insert(toBeVerified.end(), p, p + protobuf.encrypted_data().size());
+
+    p = reinterpret_cast<const uint8_t*>(protobuf.authentication_data().data());
+    std::vector<uint8_t> signature(p, p + protobuf.authentication_data().size());
+
+    std::optional<std::vector<uint8_t>> optOut;
+    rc = signOperationResponse.iOperation->finish(toBeVerified, signature, &optOut);
+    if (!rc.isOk()) {
+        std::cerr << "Decrypt: HMAC verification failed: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    // Begin decryption operation
+    ks2::CreateOperationResponse encOperationResponse;
+    auto encrypt_params = keymint::AuthorizationSetBuilder()
+                              .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::DECRYPT)
+                              .Authorization(keymint::TAG_NONCE, protobuf.init_vector().data(),
+                                             protobuf.init_vector().size())
+                              .Padding(keymint::PaddingMode::PKCS7)
+                              .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
+
+    rc = encryption_key.iSecurityLevel->createOperation(encryption_key.metadata.key,
+                                                        encrypt_params.vector_data(),
+                                                        false /* forced */, &encOperationResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to begin encryption operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    std::optional<std::vector<uint8_t>> optPlaintext;
+
+    p = reinterpret_cast<const uint8_t*>(protobuf.encrypted_data().data());
+    std::vector<uint8_t> cyphertext(p, p + protobuf.encrypted_data().size());
+
+    rc = encOperationResponse.iOperation->finish(cyphertext, {}, &optPlaintext);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    if (!optPlaintext) {
+        std::cerr << "Decryption succeeded but no plaintext returned." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    return *optPlaintext;
+}
+
+bool TestKey(const std::string& name, bool required,
+             const std::vector<keymint::KeyParameter>& parameters) {
+    auto keystore = CreateKeystoreInstance();
+    auto sec_level =
+        GetSecurityLevelInterface(keystore, keymint::SecurityLevel::TRUSTED_ENVIRONMENT);
+
+    ks2::KeyDescriptor keyDescriptor = {
+        .domain = ks2::Domain::APP,
+        .nspace = -1,
+        .alias = "tmp",
+        .blob = {},
+    };
+
+    ks2::KeyMetadata keyMetadata;
+
+    auto rc = sec_level->generateKey(keyDescriptor, {} /* attestationKey */, parameters,
+                                     0 /* flags */, {} /* entropy */, &keyMetadata);
     const char kBoldRedAbort[] = "\033[1;31mABORT\033[0m";
-    if (!result.isOk()) {
-        LOG(ERROR) << "Failed to generate key: " << result;
+    if (!rc.isOk()) {
+        LOG(ERROR) << "Failed to generate key: " << rc.getDescription();
         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
         return false;
     }
-    result = keystore->deleteKey("tmp");
-    if (!result.isOk()) {
-        LOG(ERROR) << "Failed to delete key: " << result;
+
+    rc = keystore->deleteKey(keyDescriptor);
+    if (!rc.isOk()) {
+        LOG(ERROR) << "Failed to delete key: " << rc.getDescription();
         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
         return false;
     }
     printf("===============================================================\n");
     printf("%s Key Characteristics:\n", name.c_str());
-    PrintKeyCharacteristics(hardware_enforced_characteristics, software_enforced_characteristics);
-    bool hardware_backed = (hardware_enforced_characteristics.size() > 0);
-    if (software_enforced_characteristics.GetTagCount(TAG_ALGORITHM) > 0 ||
-        software_enforced_characteristics.GetTagCount(TAG_KEY_SIZE) > 0 ||
-        software_enforced_characteristics.GetTagCount(TAG_RSA_PUBLIC_EXPONENT) > 0) {
+    PrintKeyCharacteristics(keyMetadata.authorizations);
+    bool hardware_backed = std::any_of(keyMetadata.authorizations.begin(),
+                                       keyMetadata.authorizations.end(), isHardwareEnforced);
+    if (std::any_of(keyMetadata.authorizations.begin(), keyMetadata.authorizations.end(),
+                    [&](const auto& a) {
+                        return !isHardwareEnforced(a) &&
+                               (a.keyParameter.tag == keymint::Tag::ALGORITHM ||
+                                a.keyParameter.tag == keymint::Tag::KEY_SIZE ||
+                                a.keyParameter.tag == keymint::Tag::RSA_PUBLIC_EXPONENT);
+                    })) {
         VLOG(1) << "Hardware-backed key but required characteristics enforced in software.";
         hardware_backed = false;
     }
@@ -137,60 +592,64 @@
     return (hardware_backed || !required);
 }
 
-AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) {
-    AuthorizationSetBuilder parameters;
+keymint::AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) {
+    keymint::AuthorizationSetBuilder parameters;
     parameters.RsaSigningKey(key_size, 65537)
-        .Digest(Digest::SHA_2_256)
-        .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
-        .Padding(PaddingMode::RSA_PSS)
-        .Authorization(TAG_NO_AUTH_REQUIRED);
+        .Digest(keymint::Digest::SHA_2_256)
+        .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
+        .Padding(keymint::PaddingMode::RSA_PSS)
+        .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     if (!sha256_only) {
-        parameters.Digest(Digest::SHA_2_224).Digest(Digest::SHA_2_384).Digest(Digest::SHA_2_512);
+        parameters.Digest(keymint::Digest::SHA_2_224)
+            .Digest(keymint::Digest::SHA_2_384)
+            .Digest(keymint::Digest::SHA_2_512);
     }
     return std::move(parameters);
 }
 
-AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
-    AuthorizationSetBuilder parameters;
+keymint::AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
+    keymint::AuthorizationSetBuilder parameters;
     parameters.RsaEncryptionKey(key_size, 65537)
-        .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
-        .Padding(PaddingMode::RSA_OAEP)
-        .Authorization(TAG_NO_AUTH_REQUIRED);
+        .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
+        .Padding(keymint::PaddingMode::RSA_OAEP)
+        .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     return std::move(parameters);
 }
 
-AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) {
-    AuthorizationSetBuilder parameters;
+keymint::AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) {
+    keymint::AuthorizationSetBuilder parameters;
     parameters.EcdsaSigningKey(key_size)
-        .Digest(Digest::SHA_2_256)
-        .Authorization(TAG_NO_AUTH_REQUIRED);
+        .Digest(keymint::Digest::SHA_2_256)
+        .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     if (!sha256_only) {
-        parameters.Digest(Digest::SHA_2_224).Digest(Digest::SHA_2_384).Digest(Digest::SHA_2_512);
+        parameters.Digest(keymint::Digest::SHA_2_224)
+            .Digest(keymint::Digest::SHA_2_384)
+            .Digest(keymint::Digest::SHA_2_512);
     }
     return std::move(parameters);
 }
 
-AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
-    AuthorizationSetBuilder parameters;
-    parameters.AesEncryptionKey(key_size).Authorization(TAG_NO_AUTH_REQUIRED);
+keymint::AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
+    keymint::AuthorizationSetBuilder parameters;
+    parameters.AesEncryptionKey(key_size).Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     if (with_gcm_mode) {
-        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
-            .Authorization(TAG_MIN_MAC_LENGTH, 128);
+        parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::GCM)
+            .Authorization(keymint::TAG_MIN_MAC_LENGTH, 128);
     } else {
-        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
-        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
-        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CTR);
-        parameters.Padding(PaddingMode::NONE);
+        parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::ECB);
+        parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
+        parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CTR);
+        parameters.Padding(keymint::PaddingMode::NONE);
     }
     return std::move(parameters);
 }
 
-AuthorizationSet GetHMACParameters(uint32_t key_size, Digest digest) {
-    AuthorizationSetBuilder parameters;
+keymint::AuthorizationSet GetHMACParameters(uint32_t key_size, keymint::Digest digest) {
+    keymint::AuthorizationSetBuilder parameters;
     parameters.HmacKey(key_size)
         .Digest(digest)
-        .Authorization(TAG_MIN_MAC_LENGTH, 224)
-        .Authorization(TAG_NO_AUTH_REQUIRED);
+        .Authorization(keymint::TAG_MIN_MAC_LENGTH, 224)
+        .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     return std::move(parameters);
 }
 
@@ -212,12 +671,12 @@
         {"AES-256", true, GetAESParameters(256, false)},
         {"AES-128-GCM", false, GetAESParameters(128, true)},
         {"AES-256-GCM", false, GetAESParameters(256, true)},
-        {"HMAC-SHA256-16", true, GetHMACParameters(16, Digest::SHA_2_256)},
-        {"HMAC-SHA256-32", true, GetHMACParameters(32, Digest::SHA_2_256)},
-        {"HMAC-SHA256-64", false, GetHMACParameters(64, Digest::SHA_2_256)},
-        {"HMAC-SHA224-32", false, GetHMACParameters(32, Digest::SHA_2_224)},
-        {"HMAC-SHA384-32", false, GetHMACParameters(32, Digest::SHA_2_384)},
-        {"HMAC-SHA512-32", false, GetHMACParameters(32, Digest::SHA_2_512)},
+        {"HMAC-SHA256-16", true, GetHMACParameters(16, keymint::Digest::SHA_2_256)},
+        {"HMAC-SHA256-32", true, GetHMACParameters(32, keymint::Digest::SHA_2_256)},
+        {"HMAC-SHA256-64", false, GetHMACParameters(64, keymint::Digest::SHA_2_256)},
+        {"HMAC-SHA224-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_224)},
+        {"HMAC-SHA384-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_384)},
+        {"HMAC-SHA512-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_512)},
     };
     return std::vector<TestCase>(&test_cases[0], &test_cases[arraysize(test_cases)]);
 }
@@ -243,7 +702,8 @@
             continue;
         }
         ++test_count;
-        if (!TestKey(test_case.name, test_case.required_for_brillo_pts, test_case.parameters)) {
+        if (!TestKey(test_case.name, test_case.required_for_brillo_pts,
+                     test_case.parameters.vector_data())) {
             VLOG(1) << "Test failed: " << test_case.name;
             ++fail_count;
         }
@@ -262,248 +722,274 @@
     return 0;
 }
 
-std::string ReadFile(const std::string& filename) {
+std::vector<uint8_t> ReadFile(const std::string& filename) {
     std::string content;
     base::FilePath path(filename);
     if (!base::ReadFileToString(path, &content)) {
         printf("Failed to read file: %s\n", filename.c_str());
         exit(1);
     }
-    return content;
+    std::vector<uint8_t> buffer(reinterpret_cast<const uint8_t*>(content.data()),
+                                reinterpret_cast<const uint8_t*>(content.data()) + content.size());
+    return buffer;
 }
 
-void WriteFile(const std::string& filename, const std::string& content) {
+void WriteFile(const std::string& filename, const std::vector<uint8_t>& content) {
     base::FilePath path(filename);
     int size = content.size();
-    if (base::WriteFile(path, content.data(), size) != size) {
+    if (base::WriteFile(path, reinterpret_cast<const char*>(content.data()), size) != size) {
         printf("Failed to write file: %s\n", filename.c_str());
         exit(1);
     }
 }
 
-int AddEntropy(const std::string& input, int32_t flags) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    int32_t result = keystore->addRandomNumberGeneratorEntropy(input, flags).getErrorCode();
-    printf("AddEntropy: %d\n", result);
-    return result;
-}
-
 // 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;
+int GenerateKey(const std::string& name, keymint::SecurityLevel securityLevel, bool auth_bound) {
+    auto keystore = CreateKeystoreInstance();
+    auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
+    keymint::AuthorizationSetBuilder params;
     params.RsaSigningKey(2048, 65537)
-        .Digest(Digest::SHA_2_224)
-        .Digest(Digest::SHA_2_256)
-        .Digest(Digest::SHA_2_384)
-        .Digest(Digest::SHA_2_512)
-        .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
-        .Padding(PaddingMode::RSA_PSS);
+        .Digest(keymint::Digest::SHA_2_224)
+        .Digest(keymint::Digest::SHA_2_256)
+        .Digest(keymint::Digest::SHA_2_384)
+        .Digest(keymint::Digest::SHA_2_512)
+        .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
+        .Padding(keymint::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);
+        params.Authorization(keymint::TAG_USER_SECURE_ID, 0);
     } else {
-        params.Authorization(TAG_NO_AUTH_REQUIRED);
+        params.Authorization(keymint::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", result.getErrorCode());
-    if (result.isOk()) {
-        PrintKeyCharacteristics(hardware_enforced_characteristics,
-                                software_enforced_characteristics);
+
+    ks2::KeyMetadata keyMetadata;
+
+    auto rc =
+        sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */, params.vector_data(),
+                               0 /* flags */, {} /* entropy */, &keyMetadata);
+
+    if (rc.isOk()) {
+        std::cerr << "GenerateKey failed: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    return result.getErrorCode();
+    std::cout << "GenerateKey: success" << std::endl;
+    PrintKeyCharacteristics(keyMetadata.authorizations);
+    return 0;
 }
 
 int GetCharacteristics(const std::string& name) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    AuthorizationSet hardware_enforced_characteristics;
-    AuthorizationSet software_enforced_characteristics;
-    auto result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics,
-                                                  &software_enforced_characteristics);
-    printf("GetCharacteristics: %d\n", result.getErrorCode());
-    if (result.isOk()) {
-        PrintKeyCharacteristics(hardware_enforced_characteristics,
-                                software_enforced_characteristics);
+    auto keystore = CreateKeystoreInstance();
+
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    return result.getErrorCode();
+
+    std::cout << "GetCharacteristics: success" << std::endl;
+    PrintKeyCharacteristics(keyEntryResponse.metadata.authorizations);
+    return 0;
 }
 
 int ExportKey(const std::string& name) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    std::string data;
-    int32_t result = keystore->exportKey(KeyFormat::X509, name, &data).getErrorCode();
-    printf("ExportKey: %d (%zu)\n", result, data.size());
-    return result;
+    auto keystore = CreateKeystoreInstance();
+
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    if (auto cert = keyEntryResponse.metadata.certificate) {
+        std::cout << "ExportKey: Got certificate of length (" << cert->size() << ")" << std::endl;
+    } else {
+        std::cout << "ExportKey: Key entry does not have a public component.\n";
+        std::cout << "Possibly a symmetric key?" << std::endl;
+    }
+    return 0;
 }
 
 int DeleteKey(const std::string& name) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    int32_t result = keystore->deleteKey(name).getErrorCode();
-    printf("DeleteKey: %d\n", result);
-    return result;
-}
+    auto keystore = CreateKeystoreInstance();
 
-int DeleteAllKeys() {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    int32_t result = keystore->deleteAllKeys().getErrorCode();
-    printf("DeleteAllKeys: %d\n", result);
-    return result;
+    auto rc = keystore->deleteKey(keyDescriptor(name));
+    if (!rc.isOk()) {
+        std::cerr << "Failed to delete key: " << rc.getDescription();
+        return unwrapError(rc);
+    }
+    std::cout << "Successfully deleted key." << std::endl;
+    return 0;
 }
 
 int DoesKeyExist(const std::string& name) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    printf("DoesKeyExist: %s\n", keystore->doesKeyExist(name) ? "yes" : "no");
+    auto keystore = CreateKeystoreInstance();
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    bool keyExists = true;
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        auto responseCode = unwrapError(rc);
+        if (ks2::ResponseCode(responseCode) == ks2::ResponseCode::KEY_NOT_FOUND) {
+            keyExists = false;
+        } else {
+            std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
+            return unwrapError(rc);
+        }
+    }
+    std::cout << "DoesKeyExists: " << (keyExists ? "yes" : "no") << std::endl;
     return 0;
 }
 
-int List(const std::string& prefix) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    std::vector<std::string> key_list;
-    if (!keystore->listKeys(prefix, &key_list)) {
-        printf("ListKeys failed.\n");
-        return 1;
+int List() {
+    auto keystore = CreateKeystoreInstance();
+    std::vector<ks2::KeyDescriptor> key_list;
+    auto rc = keystore->listEntries(ks2::Domain::APP, -1 /* nspace ignored */, &key_list);
+    if (!rc.isOk()) {
+        std::cerr << "ListKeys failed: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    printf("Keys:\n");
-    for (const auto& key_name : key_list) {
-        printf("  %s\n", key_name.c_str());
-    }
-    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());
+    std::cout << "Keys:\n";
+    for (const auto& key : key_list) {
+        std::cout << "  "
+                  << (key.alias ? *key.alias : "Whoopsi - no alias, this should not happen.")
+                  << std::endl;
     }
     return 0;
 }
 
 int SignAndVerify(const std::string& name) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    AuthorizationSetBuilder sign_params;
-    sign_params.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
-    sign_params.Digest(Digest::SHA_2_256);
-    AuthorizationSet output_params;
-    uint64_t handle;
-    auto result =
-        keystore->beginOperation(KeyPurpose::SIGN, name, sign_params, &output_params, &handle);
-    if (!result.isOk()) {
-        printf("Sign: BeginOperation failed: %d\n", result.getErrorCode());
-        return result.getErrorCode();
+    auto keystore = CreateKeystoreInstance();
+    auto sign_params = keymint::AuthorizationSetBuilder()
+                           .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::SIGN)
+                           .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
+                           .Digest(keymint::Digest::SHA_2_256);
+
+    keymint::AuthorizationSet output_params;
+
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    AuthorizationSet empty_params;
-    std::string output_data;
-    result = keystore->finishOperation(handle, empty_params, "data_to_sign",
-                                       std::string() /*signature_to_verify*/, &output_params,
-                                       &output_data);
-    if (!result.isOk()) {
-        printf("Sign: FinishOperation failed: %d\n", result.getErrorCode());
-        return result.getErrorCode();
+
+    ks2::CreateOperationResponse operationResponse;
+
+    rc = keyEntryResponse.iSecurityLevel->createOperation(keyEntryResponse.metadata.key,
+                                                          sign_params.vector_data(),
+                                                          false /* forced */, &operationResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to create operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    printf("Sign: %zu bytes.\n", output_data.size());
-    // We have a signature, now verify it.
-    std::string signature_to_verify = output_data;
-    output_data.clear();
-    result =
-        keystore->beginOperation(KeyPurpose::VERIFY, name, sign_params, &output_params, &handle);
-    result = keystore->finishOperation(handle, empty_params, "data_to_sign", signature_to_verify,
-                                       &output_params, &output_data);
-    if (result == ErrorCode::VERIFICATION_FAILED) {
-        printf("Verify: Failed to verify signature.\n");
-        return result.getErrorCode();
+
+    const std::vector<uint8_t> data_to_sign{0x64, 0x61, 0x74, 0x61, 0x5f, 0x74,
+                                            0x6f, 0x5f, 0x73, 0x69, 0x67, 0x6e};
+    std::optional<std::vector<uint8_t>> output_data;
+    rc = operationResponse.iOperation->finish(data_to_sign, {}, &output_data);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to finalize operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    if (!result.isOk()) {
-        printf("Verify: FinishOperation failed: %d\n", result.getErrorCode());
-        return result.getErrorCode();
+
+    if (!output_data) {
+        std::cerr << "Odd signing succeeded but no signature was returned." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
     }
-    printf("Verify: OK\n");
+    auto signature = std::move(*output_data);
+
+    std::cout << "Sign: " << signature.size() << " bytes." << std::endl;
+
+    if (auto cert = keyEntryResponse.metadata.certificate) {
+        const uint8_t* p = cert->data();
+        bssl::UniquePtr<X509> decoded_cert(d2i_X509(nullptr, &p, (long)cert->size()));
+        bssl::UniquePtr<EVP_PKEY> decoded_pkey(X509_get_pubkey(decoded_cert.get()));
+        bssl::UniquePtr<EVP_MD_CTX> ctx(EVP_MD_CTX_new());
+        if (!ctx) {
+            std::cerr << "Failed to created EVP_MD context. << std::endl";
+            return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+        }
+
+        if (!EVP_DigestVerifyInit(ctx.get(), nullptr, EVP_sha256(), nullptr, decoded_pkey.get()) ||
+            !EVP_DigestVerifyUpdate(ctx.get(), data_to_sign.data(), data_to_sign.size()) ||
+            EVP_DigestVerifyFinal(ctx.get(), signature.data(), signature.size()) != 1) {
+            std::cerr << "Failed to verify signature." << std::endl;
+            return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+        }
+    } else {
+        std::cerr << "No public key to check signature against." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    std::cout << "Verify: OK" << std::endl;
     return 0;
 }
 
 int Encrypt(const std::string& key_name, const std::string& input_filename,
-            const std::string& output_filename, int32_t flags) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    std::string input = ReadFile(input_filename);
-    std::string output;
-    if (!keystore->encryptWithAuthentication(key_name, input, flags, &output)) {
-        printf("EncryptWithAuthentication failed.\n");
-        return 1;
+            const std::string& output_filename, keymint::SecurityLevel securityLevel) {
+    auto input = ReadFile(input_filename);
+    auto result = encryptWithAuthentication(key_name, input, securityLevel);
+    if (auto error = std::get_if<int>(&result)) {
+        std::cerr << "EncryptWithAuthentication failed." << std::endl;
+        return *error;
     }
-    WriteFile(output_filename, output);
+    WriteFile(output_filename, std::get<std::vector<uint8_t>>(result));
     return 0;
 }
 
 int Decrypt(const std::string& key_name, const std::string& input_filename,
             const std::string& output_filename) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    std::string input = ReadFile(input_filename);
-    std::string output;
-    if (!keystore->decryptWithAuthentication(key_name, input, &output)) {
-        printf("DecryptWithAuthentication failed.\n");
-        return 1;
+    auto input = ReadFile(input_filename);
+    auto result = decryptWithAuthentication(key_name, input);
+    if (auto error = std::get_if<int>(&result)) {
+        std::cerr << "DecryptWithAuthentication failed." << std::endl;
+        return *error;
     }
-    WriteFile(output_filename, output);
+    WriteFile(output_filename, std::get<std::vector<uint8_t>>(result));
     return 0;
 }
 
-uint32_t securityLevelOption2Flags(const CommandLine& cmd) {
+keymint::SecurityLevel securityLevelOption2SecurlityLevel(const CommandLine& cmd) {
     if (cmd.HasSwitch("seclevel")) {
         auto str = cmd.GetSwitchValueASCII("seclevel");
         if (str == "strongbox") {
-            return KEYSTORE_FLAG_STRONGBOX;
-        } else if (str == "software") {
-            return KEYSTORE_FLAG_FALLBACK;
+            return keymint::SecurityLevel::STRONGBOX;
+        } else if (str == "tee") {
+            return keymint::SecurityLevel::TRUSTED_ENVIRONMENT;
         }
+        std::cerr << "Unknown Security level: " << str << std::endl;
+        std::cerr << "Supported security levels: \"strongbox\" or \"tee\" (default)" << std::endl;
     }
-    return KEYSTORE_FLAG_NONE;
+    return keymint::SecurityLevel::TRUSTED_ENVIRONMENT;
 }
 
 class ConfirmationListener
-    : public android::security::BnConfirmationPromptCallback,
-      public std::promise<std::tuple<ConfirmationResponseCode, std::vector<uint8_t>>> {
+    : public apc::BnConfirmationCallback,
+      public std::promise<std::tuple<apc::ResponseCode, std::optional<std::vector<uint8_t>>>> {
   public:
     ConfirmationListener() {}
 
-    virtual ::android::binder::Status
-    onConfirmationPromptCompleted(int32_t result,
-                                  const ::std::vector<uint8_t>& dataThatWasConfirmed) override {
-        this->set_value({static_cast<ConfirmationResponseCode>(result), dataThatWasConfirmed});
-        return ::android::binder::Status::ok();
-    }
+    virtual ::ndk::ScopedAStatus
+    onCompleted(::aidl::android::security::apc::ResponseCode result,
+                const std::optional<std::vector<uint8_t>>& dataConfirmed) override {
+        this->set_value({result, dataConfirmed});
+        return ::ndk::ScopedAStatus::ok();
+    };
 };
 
 int Confirmation(const std::string& promptText, const std::string& extraDataHex,
                  const std::string& locale, const std::string& uiOptionsStr,
                  const std::string& cancelAfter) {
-    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) {
-        printf("error: could not connect to keystore service.\n");
+    ::ndk::SpAIBinder apcBinder(AServiceManager_getService("android.security.apc"));
+    auto apcService = apc::IProtectedConfirmation::fromBinder(apcBinder);
+    if (!apcService) {
+        std::cerr << "Error: could not connect to apc service." << std::endl;
         return 1;
     }
 
@@ -537,44 +1023,28 @@
         return 1;
     }
 
-    String16 promptText16(promptText.data(), promptText.size());
-    String16 locale16(locale.data(), locale.size());
-
-    sp<ConfirmationListener> listener = new ConfirmationListener();
+    auto listener = std::make_shared<ConfirmationListener>();
 
     auto future = listener->get_future();
-    int32_t aidl_return;
-    android::binder::Status status = service->presentConfirmationPrompt(
-        listener, promptText16, extraData, locale16, uiOptionsAsFlags, &aidl_return);
-    if (!status.isOk()) {
-        printf("Presenting confirmation prompt failed with binder status '%s'.\n",
-               status.toString8().c_str());
+    auto rc = apcService->presentPrompt(listener, promptText, extraData, locale, uiOptionsAsFlags);
+
+    if (!rc.isOk()) {
+        std::cerr << "Presenting confirmation prompt failed: " << rc.getDescription() << std::endl;
         return 1;
     }
-    ConfirmationResponseCode responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
-    if (responseCode != ConfirmationResponseCode::OK) {
-        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");
+
+    std::cerr << "Waiting for prompt to complete - use Ctrl+C to abort..." << std::endl;
 
     if (cancelAfterValue > 0.0) {
-        printf("Sleeping %.1f seconds before canceling prompt...\n", cancelAfterValue);
+        std::cerr << "Sleeping " << cancelAfterValue << " seconds before canceling prompt..."
+                  << std::endl;
         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);
+            rc = apcService->cancelPrompt(listener);
+            if (!rc.isOk()) {
+                std::cerr << "Canceling confirmation prompt failed: " << rc.getDescription()
+                          << std::endl;
                 return 1;
             }
         }
@@ -582,27 +1052,28 @@
 
     future.wait();
 
-    auto [rc, dataThatWasConfirmed] = future.get();
+    auto [responseCode, dataThatWasConfirmed] = future.get();
 
-    printf("Confirmation prompt completed\n"
-           "responseCode = %d\n",
-           rc);
-    printf("dataThatWasConfirmed[%zd] = {", dataThatWasConfirmed.size());
+    std::cerr << "Confirmation prompt completed\n"
+              << "responseCode = " << toString(responseCode);
     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");
+    if (dataThatWasConfirmed) {
+        std::cerr << "dataThatWasConfirmed[" << dataThatWasConfirmed->size() << "] = {";
+        for (uint8_t element : *dataThatWasConfirmed) {
+            if (hasPrinted) {
+                std::cerr << ", ";
+            }
+            if (newLineCountDown == 0) {
+                std::cerr << "\n  ";
+                newLineCountDown = 32;
+            }
+            std::cerr << "0x" << std::hex << std::setw(2) << std::setfill('0') << (unsigned)element;
 
+            hasPrinted = true;
+        }
+    }
+    std::cerr << std::endl;
     return 0;
 }
 
@@ -613,7 +1084,7 @@
     CommandLine* command_line = CommandLine::ForCurrentProcess();
     CommandLine::StringVector args = command_line->GetArgs();
 
-    android::ProcessState::self()->startThreadPool();
+    ABinderProcess_startThreadPool();
 
     if (args.empty()) {
         PrintUsageAndExit();
@@ -623,12 +1094,9 @@
                                   command_line->HasSwitch("test_for_0_3"));
     } else if (args[0] == "list-brillo-tests") {
         return ListTestCases();
-    } else if (args[0] == "add-entropy") {
-        return AddEntropy(command_line->GetSwitchValueASCII("input"),
-                          securityLevelOption2Flags(*command_line));
     } else if (args[0] == "generate") {
         return GenerateKey(command_line->GetSwitchValueASCII("name"),
-                           securityLevelOption2Flags(*command_line),
+                           securityLevelOption2SecurlityLevel(*command_line),
                            command_line->HasSwitch("auth_bound"));
     } else if (args[0] == "get-chars") {
         return GetCharacteristics(command_line->GetSwitchValueASCII("name"));
@@ -636,20 +1104,17 @@
         return ExportKey(command_line->GetSwitchValueASCII("name"));
     } else if (args[0] == "delete") {
         return DeleteKey(command_line->GetSwitchValueASCII("name"));
-    } else if (args[0] == "delete-all") {
-        return DeleteAllKeys();
     } else if (args[0] == "exists") {
         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();
+        return List();
     } else if (args[0] == "sign-verify") {
         return SignAndVerify(command_line->GetSwitchValueASCII("name"));
     } else if (args[0] == "encrypt") {
-        return Encrypt(
-            command_line->GetSwitchValueASCII("name"), command_line->GetSwitchValueASCII("in"),
-            command_line->GetSwitchValueASCII("out"), securityLevelOption2Flags(*command_line));
+        return Encrypt(command_line->GetSwitchValueASCII("name"),
+                       command_line->GetSwitchValueASCII("in"),
+                       command_line->GetSwitchValueASCII("out"),
+                       securityLevelOption2SecurlityLevel(*command_line));
     } else if (args[0] == "decrypt") {
         return Decrypt(command_line->GetSwitchValueASCII("name"),
                        command_line->GetSwitchValueASCII("in"),
diff --git a/keystore/keystore_client_impl.cpp b/keystore/keystore_client_impl.cpp
deleted file mode 100644
index f888683..0000000
--- a/keystore/keystore_client_impl.cpp
+++ /dev/null
@@ -1,629 +0,0 @@
-// Copyright 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.
-
-#define LOG_TAG "keystore_client"
-
-#include "keystore/keystore_client_impl.h"
-
-#include <future>
-#include <optional>
-#include <string>
-#include <vector>
-
-#include <android/security/keystore/IKeystoreService.h>
-#include <binder/IBinder.h>
-#include <binder/IInterface.h>
-#include <binder/IServiceManager.h>
-#include <keystore/keystore.h>
-#include <log/log.h>
-#include <utils/String16.h>
-#include <utils/String8.h>
-
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore_hidl_support.h>
-#include <keystore/keystore_promises.h>
-
-#include "keystore_client.pb.h"
-
-namespace {
-
-// Use the UID of the current process.
-const int kDefaultUID = -1;
-const char kEncryptSuffix[] = "_ENC";
-const char kAuthenticateSuffix[] = "_AUTH";
-constexpr uint32_t kAESKeySize = 256;      // bits
-constexpr uint32_t kHMACKeySize = 256;     // bits
-constexpr uint32_t kHMACOutputSize = 256;  // bits
-
-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;
-using keystore::KeyStoreServiceReturnCode;
-}  // namespace
-
-namespace keystore {
-
-KeystoreClientImpl::KeystoreClientImpl() {
-    service_manager_ = android::defaultServiceManager();
-    keystore_binder_ = service_manager_->getService(String16("android.security.keystore"));
-    keystore_ =
-        android::interface_cast<android::security::keystore::IKeystoreService>(keystore_binder_);
-}
-
-bool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name,
-                                                   const std::string& data, int32_t flags,
-                                                   std::string* encrypted_data) {
-    // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random
-    // IV. The authentication algorithm is HMAC-SHA256 and is computed over the
-    // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM
-    // because hardware support for GCM is not mandatory for all Brillo devices.
-    std::string encryption_key_name = key_name + kEncryptSuffix;
-    if (!createOrVerifyEncryptionKey(encryption_key_name, flags)) {
-        return false;
-    }
-    std::string authentication_key_name = key_name + kAuthenticateSuffix;
-    if (!createOrVerifyAuthenticationKey(authentication_key_name, flags)) {
-        return false;
-    }
-    AuthorizationSetBuilder encrypt_params;
-    encrypt_params.Padding(PaddingMode::PKCS7);
-    encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
-    AuthorizationSet output_params;
-    std::string raw_encrypted_data;
-    if (!oneShotOperation(KeyPurpose::ENCRYPT, encryption_key_name, encrypt_params, data,
-                          std::string(), /* signature_to_verify */
-                          &output_params, &raw_encrypted_data)) {
-        ALOGE("Encrypt: AES operation failed.");
-        return false;
-    }
-    auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
-    if (!init_vector_blob.isOk()) {
-        ALOGE("Encrypt: Missing initialization vector.");
-        return false;
-    }
-    std::string init_vector = hidlVec2String(init_vector_blob.value());
-
-    AuthorizationSetBuilder authenticate_params;
-    authenticate_params.Digest(Digest::SHA_2_256);
-    authenticate_params.Authorization(TAG_MAC_LENGTH, kHMACOutputSize);
-    std::string raw_authentication_data;
-    if (!oneShotOperation(KeyPurpose::SIGN, authentication_key_name, authenticate_params,
-                          init_vector + raw_encrypted_data, std::string(), /* signature_to_verify */
-                          &output_params, &raw_authentication_data)) {
-        ALOGE("Encrypt: HMAC operation failed.");
-        return false;
-    }
-    EncryptedData protobuf;
-    protobuf.set_init_vector(init_vector);
-    protobuf.set_authentication_data(raw_authentication_data);
-    protobuf.set_encrypted_data(raw_encrypted_data);
-    if (!protobuf.SerializeToString(encrypted_data)) {
-        ALOGE("Encrypt: Failed to serialize EncryptedData protobuf.");
-        return false;
-    }
-    return true;
-}
-
-bool KeystoreClientImpl::decryptWithAuthentication(const std::string& key_name,
-                                                   const std::string& encrypted_data,
-                                                   std::string* data) {
-    EncryptedData protobuf;
-    if (!protobuf.ParseFromString(encrypted_data)) {
-        ALOGE("Decrypt: Failed to parse EncryptedData protobuf.");
-    }
-    // Verify authentication before attempting decryption.
-    std::string authentication_key_name = key_name + kAuthenticateSuffix;
-    AuthorizationSetBuilder authenticate_params;
-    authenticate_params.Digest(Digest::SHA_2_256);
-    AuthorizationSet output_params;
-    std::string output_data;
-    if (!oneShotOperation(KeyPurpose::VERIFY, authentication_key_name, authenticate_params,
-                          protobuf.init_vector() + protobuf.encrypted_data(),
-                          protobuf.authentication_data(), &output_params, &output_data)) {
-        ALOGE("Decrypt: HMAC operation failed.");
-        return false;
-    }
-    std::string encryption_key_name = key_name + kEncryptSuffix;
-    AuthorizationSetBuilder encrypt_params;
-    encrypt_params.Padding(PaddingMode::PKCS7);
-    encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
-    encrypt_params.Authorization(TAG_NONCE, protobuf.init_vector().data(),
-                                 protobuf.init_vector().size());
-    if (!oneShotOperation(KeyPurpose::DECRYPT, encryption_key_name, encrypt_params,
-                          protobuf.encrypted_data(), std::string(), /* signature_to_verify */
-                          &output_params, data)) {
-        ALOGE("Decrypt: AES operation failed.");
-        return false;
-    }
-    return true;
-}
-
-bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name,
-                                          const AuthorizationSet& input_parameters,
-                                          const std::string& input_data,
-                                          const std::string& signature_to_verify,
-                                          AuthorizationSet* output_parameters,
-                                          std::string* output_data) {
-    uint64_t handle;
-    auto result = beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
-    if (!result.isOk()) {
-        ALOGE("BeginOperation failed: %d", result.getErrorCode());
-        return false;
-    }
-    AuthorizationSet empty_params;
-    AuthorizationSet ignored_params;
-    result = finishOperation(handle, empty_params, input_data, signature_to_verify, &ignored_params,
-                             output_data);
-    if (!result.isOk()) {
-        ALOGE("FinishOperation failed: %d", result.getErrorCode());
-        return false;
-    }
-    return true;
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy, int32_t flags) {
-    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;
-
-    KeyStoreNativeReturnCode rc(error_code);
-    if (!rc.isOk()) return rc;
-
-    auto result = future.get();
-
-    return KeyStoreNativeReturnCode(result.response_code());
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::generateKey(const std::string& key_name, const AuthorizationSet& key_parameters,
-                                int32_t flags, AuthorizationSet* hardware_enforced_characteristics,
-                                AuthorizationSet* software_enforced_characteristics) {
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t error_code;
-    android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
-    auto future = promise->get_future();
-    auto binder_result = keystore_->generateKey(
-        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(km_response.response_code());
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::getKeyCharacteristics(const std::string& key_name,
-                                          AuthorizationSet* hardware_enforced_characteristics,
-                                          AuthorizationSet* software_enforced_characteristics) {
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t error_code;
-    android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
-    auto future = promise->get_future();
-    auto binder_result = keystore_->getKeyCharacteristics(
-        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(km_response.response_code());
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::importKey(const std::string& key_name, const AuthorizationSet& key_parameters,
-                              KeyFormat key_format, const std::string& key_data,
-                              AuthorizationSet* hardware_enforced_characteristics,
-                              AuthorizationSet* software_enforced_characteristics) {
-    String16 key_name16(key_name.data(), key_name.size());
-    auto hidlKeyData = blob2hidlVec(key_data);
-    int32_t error_code;
-    android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
-    auto future = promise->get_future();
-    auto binder_result = keystore_->importKey(
-        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(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());
-    int32_t error_code;
-    android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise);
-    auto future = promise->get_future();
-    auto binder_result = keystore_->exportKey(
-        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;
-}
-
-KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t result;
-    auto binder_result = keystore_->del(key_name16, kDefaultUID, &result);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    return KeyStoreNativeReturnCode(result);
-}
-
-KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
-    int32_t result;
-    auto binder_result = keystore_->clear_uid(kDefaultUID, &result);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    return KeyStoreNativeReturnCode(result);
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
-                                   const AuthorizationSet& input_parameters,
-                                   AuthorizationSet* output_parameters, uint64_t* handle) {
-    android::sp<android::IBinder> token(new android::BBinder);
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t error_code;
-    android::sp<OperationResultPromise> promise(new OperationResultPromise{});
-    auto future = promise->get_future();
-    auto binder_result = keystore_->begin(
-        promise, token, key_name16, (int)purpose, true /*pruneable*/,
-        android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
-        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;
-        if (result.outParams.size()) {
-            *output_parameters = result.outParams;
-        }
-    }
-    return result.resultCode;
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::updateOperation(uint64_t handle, const AuthorizationSet& input_parameters,
-                                    const std::string& input_data, size_t* num_input_bytes_consumed,
-                                    AuthorizationSet* output_parameters, std::string* output_data) {
-    if (active_operations_.count(handle) == 0) {
-        return ErrorCode::INVALID_OPERATION_HANDLE;
-    }
-    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(
-        promise, active_operations_[handle],
-        android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
-        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;
-        if (result.outParams.size()) {
-            *output_parameters = result.outParams;
-        }
-        // TODO verify that append should not be assign
-        output_data->append(hidlVec2String(result.data));
-    }
-    return result.resultCode;
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::finishOperation(uint64_t handle, const AuthorizationSet& input_parameters,
-                                    const std::string& input_data,
-                                    const std::string& signature_to_verify,
-                                    AuthorizationSet* output_parameters, std::string* output_data) {
-    if (active_operations_.count(handle) == 0) {
-        return ErrorCode::INVALID_OPERATION_HANDLE;
-    }
-    int32_t error_code;
-    auto hidlSignature = blob2hidlVec(signature_to_verify);
-    auto hidlInput = blob2hidlVec(input_data);
-    android::sp<OperationResultPromise> promise(new OperationResultPromise{});
-    auto future = promise->get_future();
-    auto binder_result = keystore_->finish(
-        promise, active_operations_[handle],
-        android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
-        (std::vector<uint8_t>)hidlInput, (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;
-        }
-        // TODO verify that append should not be assign
-        output_data->append(hidlVec2String(result.data));
-        active_operations_.erase(handle);
-    }
-    return result.resultCode;
-}
-
-KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
-    if (active_operations_.count(handle) == 0) {
-        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(promise, active_operations_[handle], &result);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    KeyStoreNativeReturnCode rc(result);
-    if (!rc.isOk()) return rc;
-    rc = KeyStoreNativeReturnCode(future.get().response_code());
-    if (rc.isOk()) {
-        active_operations_.erase(handle);
-    }
-    return rc;
-}
-
-bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t result;
-    auto binder_result = keystore_->exist(key_name16, kDefaultUID, &result);
-    if (!binder_result.isOk()) return false;  // binder error
-    return result == static_cast<int32_t>(ResponseCode::NO_ERROR);
-}
-
-bool KeystoreClientImpl::listKeys(const std::string& prefix,
-                                  std::vector<std::string>* key_name_list) {
-    return listKeysOfUid(prefix, kDefaultUID, key_name_list);
-}
-
-bool KeystoreClientImpl::listKeysOfUid(const std::string& prefix, int uid,
-                                       std::vector<std::string>* key_name_list) {
-    String16 prefix16(prefix.data(), prefix.size());
-    std::vector<::android::String16> matches;
-    auto binder_result = keystore_->list(prefix16, uid, &matches);
-    if (!binder_result.isOk()) return false;
-
-    for (const auto& match : matches) {
-        android::String8 key_name(match);
-        key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
-    }
-    return true;
-}
-
-std::optional<std::vector<uint8_t>> KeystoreClientImpl::getKey(const std::string& alias, int uid) {
-    String16 alias16(alias.data(), alias.size());
-    std::vector<uint8_t> output;
-    auto binder_result = keystore_->get(alias16, uid, &output);
-    if (!binder_result.isOk()) return std::nullopt;
-    return output;
-}
-
-uint64_t KeystoreClientImpl::getNextVirtualHandle() {
-    return next_virtual_handle_++;
-}
-
-bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name, int32_t flags) {
-    bool key_exists = doesKeyExist(key_name);
-    if (key_exists) {
-        bool verified = false;
-        if (!verifyEncryptionKeyAttributes(key_name, &verified)) {
-            return false;
-        }
-        if (!verified) {
-            auto result = deleteKey(key_name);
-            if (!result.isOk()) {
-                ALOGE("Failed to delete invalid encryption key: %d", result.getErrorCode());
-                return false;
-            }
-            key_exists = false;
-        }
-    }
-    if (!key_exists) {
-        AuthorizationSetBuilder key_parameters;
-        key_parameters.AesEncryptionKey(kAESKeySize)
-            .Padding(PaddingMode::PKCS7)
-            .Authorization(TAG_BLOCK_MODE, BlockMode::CBC)
-            .Authorization(TAG_NO_AUTH_REQUIRED);
-        AuthorizationSet hardware_enforced_characteristics;
-        AuthorizationSet software_enforced_characteristics;
-        auto result =
-            generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
-                        &software_enforced_characteristics);
-        if (!result.isOk()) {
-            ALOGE("Failed to generate encryption key: %d", result.getErrorCode());
-            return false;
-        }
-        if (hardware_enforced_characteristics.size() == 0) {
-            ALOGW("WARNING: Encryption key is not hardware-backed.");
-        }
-    }
-    return true;
-}
-
-bool KeystoreClientImpl::createOrVerifyAuthenticationKey(const std::string& key_name,
-                                                         int32_t flags) {
-    bool key_exists = doesKeyExist(key_name);
-    if (key_exists) {
-        bool verified = false;
-        if (!verifyAuthenticationKeyAttributes(key_name, &verified)) {
-            return false;
-        }
-        if (!verified) {
-            auto result = deleteKey(key_name);
-            if (!result.isOk()) {
-                ALOGE("Failed to delete invalid authentication key: %d", result.getErrorCode());
-                return false;
-            }
-            key_exists = false;
-        }
-    }
-    if (!key_exists) {
-        AuthorizationSetBuilder key_parameters;
-        key_parameters.HmacKey(kHMACKeySize)
-            .Digest(Digest::SHA_2_256)
-            .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
-            .Authorization(TAG_NO_AUTH_REQUIRED);
-        AuthorizationSet hardware_enforced_characteristics;
-        AuthorizationSet software_enforced_characteristics;
-        auto result =
-            generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
-                        &software_enforced_characteristics);
-        if (!result.isOk()) {
-            ALOGE("Failed to generate authentication key: %d", result.getErrorCode());
-            return false;
-        }
-        if (hardware_enforced_characteristics.size() == 0) {
-            ALOGW("WARNING: Authentication key is not hardware-backed.");
-        }
-    }
-    return true;
-}
-
-bool KeystoreClientImpl::verifyEncryptionKeyAttributes(const std::string& key_name,
-                                                       bool* verified) {
-    AuthorizationSet hardware_enforced_characteristics;
-    AuthorizationSet software_enforced_characteristics;
-    auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
-                                        &software_enforced_characteristics);
-    if (!result.isOk()) {
-        ALOGE("Failed to query encryption key: %d", result.getErrorCode());
-        return false;
-    }
-    *verified = true;
-    auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
-                              software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
-    if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
-        ALOGW("Found encryption key with invalid algorithm.");
-        *verified = false;
-    }
-    auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
-                             software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
-    if (!key_size.isOk() || key_size.value() != kAESKeySize) {
-        ALOGW("Found encryption key with invalid size.");
-        *verified = false;
-    }
-    auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
-                               software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
-    if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
-        ALOGW("Found encryption key with invalid block mode.");
-        *verified = false;
-    }
-    auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
-                                 software_enforced_characteristics.GetTagValue(TAG_PADDING));
-    if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
-        ALOGW("Found encryption key with invalid padding mode.");
-        *verified = false;
-    }
-    if (hardware_enforced_characteristics.size() == 0) {
-        ALOGW("WARNING: Encryption key is not hardware-backed.");
-    }
-    return true;
-}
-
-bool KeystoreClientImpl::verifyAuthenticationKeyAttributes(const std::string& key_name,
-                                                           bool* verified) {
-    AuthorizationSet hardware_enforced_characteristics;
-    AuthorizationSet software_enforced_characteristics;
-    auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
-                                        &software_enforced_characteristics);
-    if (!result.isOk()) {
-        ALOGE("Failed to query authentication key: %d", result.getErrorCode());
-        return false;
-    }
-    *verified = true;
-    auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
-                              software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
-    if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC) {
-        ALOGW("Found authentication key with invalid algorithm.");
-        *verified = false;
-    }
-    auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
-                             software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
-    if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
-        ALOGW("Found authentication key with invalid size.");
-        *verified = false;
-    }
-    auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
-                             software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
-    if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
-        ALOGW("Found authentication key with invalid minimum mac size.");
-        *verified = false;
-    }
-    auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
-                           software_enforced_characteristics.GetTagValue(TAG_DIGEST));
-    if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
-        ALOGW("Found authentication key with invalid digest list.");
-        *verified = false;
-    }
-    if (hardware_enforced_characteristics.size() == 0) {
-        ALOGW("WARNING: Authentication key is not hardware-backed.");
-    }
-    return true;
-}
-
-}  // namespace keystore
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
deleted file mode 100644
index 02c2139..0000000
--- a/keystore/keystore_main.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2009 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 "keystore"
-
-#include <android-base/logging.h>
-#include <android/hidl/manager/1.2/IServiceManager.h>
-#include <android/security/keystore/IKeystoreService.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <keymasterV4_1/Keymaster3.h>
-#include <keymasterV4_1/Keymaster4.h>
-#include <utils/StrongPointer.h>
-
-#include <keystore/keystore_hidl_support.h>
-#include <keystore/keystore_return_types.h>
-
-#include "KeyStore.h"
-#include "key_store_service.h"
-#include "legacy_keymaster_device_wrapper.h"
-#include "permissions.h"
-
-/* KeyStore is a secured storage for key-value pairs. In this implementation,
- * each file stores one key-value pair. Keys are encoded in file names, and
- * values are encrypted with checksums. The encryption key is protected by a
- * user-defined password. To keep things simple, buffers are always larger than
- * the maximum space we needed, so boundary checks on buffers are omitted. */
-
-using ::android::sp;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::keymaster::V4_0::ErrorCode;
-using ::android::hardware::keymaster::V4_0::HmacSharingParameters;
-using ::android::hardware::keymaster::V4_0::SecurityLevel;
-using ::android::hidl::manager::V1_2::IServiceManager;
-
-using ::keystore::keymaster::support::Keymaster;
-using ::keystore::keymaster::support::Keymaster3;
-using ::keystore::keymaster::support::Keymaster4;
-
-using keystore::KeymasterDevices;
-
-template <typename Wrapper>
-KeymasterDevices enumerateKeymasterDevices(IServiceManager* serviceManager) {
-    KeymasterDevices result;
-    serviceManager->listManifestByInterface(
-        Wrapper::WrappedIKeymasterDevice::descriptor, [&](const hidl_vec<hidl_string>& names) {
-            auto try_get_device = [&](const auto& name, bool fail_silent) {
-                auto device = Wrapper::WrappedIKeymasterDevice::getService(name);
-                if (fail_silent && !device) return;
-                CHECK(device) << "Failed to get service for \""
-                              << Wrapper::WrappedIKeymasterDevice::descriptor
-                              << "\" with interface name \"" << name << "\"";
-
-                sp<Keymaster> kmDevice(new Wrapper(device, name));
-                auto halVersion = kmDevice->halVersion();
-                SecurityLevel securityLevel = halVersion.securityLevel;
-                LOG(INFO) << "found " << Wrapper::WrappedIKeymasterDevice::descriptor
-                          << " with interface name " << name << " and seclevel "
-                          << toString(securityLevel);
-                CHECK(static_cast<uint32_t>(securityLevel) < result.size())
-                    << "Security level of \"" << Wrapper::WrappedIKeymasterDevice::descriptor
-                    << "\" with interface name \"" << name << "\" out of range";
-                auto& deviceSlot = result[securityLevel];
-                if (deviceSlot) {
-                    if (!fail_silent) {
-                        LOG(WARNING) << "Implementation of \""
-                                     << Wrapper::WrappedIKeymasterDevice::descriptor
-                                     << "\" with interface name \"" << name
-                                     << "\" and security level: " << toString(securityLevel)
-                                     << " Masked by other implementation of Keymaster";
-                    }
-                } else {
-                    deviceSlot = kmDevice;
-                }
-            };
-            bool has_default = false;
-            for (auto& n : names) {
-                try_get_device(n, false);
-                if (n == "default") has_default = true;
-            }
-            // Make sure that we always check the default device. If we enumerate only what is
-            // known to hwservicemanager, we miss a possible passthrough HAL.
-            if (!has_default) {
-                try_get_device("default", true /* fail_silent */);
-            }
-        });
-    return result;
-}
-
-KeymasterDevices initializeKeymasters() {
-    auto serviceManager = IServiceManager::getService();
-    CHECK(serviceManager.get()) << "Failed to get ServiceManager";
-    auto result = enumerateKeymasterDevices<Keymaster4>(serviceManager.get());
-    auto softKeymaster = result[SecurityLevel::SOFTWARE];
-    if (!result[SecurityLevel::TRUSTED_ENVIRONMENT]) {
-        result = enumerateKeymasterDevices<Keymaster3>(serviceManager.get());
-    }
-    if (softKeymaster) result[SecurityLevel::SOFTWARE] = softKeymaster;
-    if (result[SecurityLevel::SOFTWARE] && !result[SecurityLevel::TRUSTED_ENVIRONMENT]) {
-        LOG(WARNING) << "No secure Keymaster implementation found, but device offers insecure"
-                        " Keymaster HAL. Using as default.";
-        result[SecurityLevel::TRUSTED_ENVIRONMENT] = result[SecurityLevel::SOFTWARE];
-        result[SecurityLevel::SOFTWARE] = nullptr;
-    }
-    if (!result[SecurityLevel::SOFTWARE]) {
-        auto fbdev = android::keystore::makeSoftwareKeymasterDevice();
-        CHECK(fbdev.get()) << "Unable to create Software Keymaster Device";
-        result[SecurityLevel::SOFTWARE] = new Keymaster3(fbdev, "Software");
-    }
-    return result;
-}
-
-int main(int argc, char* argv[]) {
-    using android::hardware::hidl_string;
-    CHECK(argc >= 2) << "A directory must be specified!";
-    CHECK(chdir(argv[1]) != -1) << "chdir: " << argv[1] << ": " << strerror(errno);
-
-    auto kmDevices = initializeKeymasters();
-
-    CHECK(kmDevices[SecurityLevel::SOFTWARE]) << "Missing software Keymaster device";
-    CHECK(kmDevices[SecurityLevel::TRUSTED_ENVIRONMENT])
-        << "Error no viable keymaster device found";
-
-    CHECK(configure_selinux() != -1) << "Failed to configure SELinux.";
-
-    auto halVersion = kmDevices[SecurityLevel::TRUSTED_ENVIRONMENT]->halVersion();
-
-    // If the hardware is keymaster 2.0 or higher we will not allow the fallback device for import
-    // or generation of keys. The fallback device is only used for legacy keys present on the
-    // device.
-    SecurityLevel minimalAllowedSecurityLevelForNewKeys =
-        halVersion.majorVersion >= 2 ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE;
-
-    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);
-    service->setRequestingSid(true);
-    android::status_t ret = sm->addService(android::String16("android.security.keystore"), service);
-    CHECK(ret == android::OK) << "Couldn't register binder service!";
-
-    /*
-     * This thread is just going to process Binder transactions.
-     */
-    android::IPCThreadState::self()->joinThreadPool();
-    return 1;
-}
diff --git a/keystore/legacy_keymaster_device_wrapper.cpp b/keystore/legacy_keymaster_device_wrapper.cpp
deleted file mode 100644
index 052f394..0000000
--- a/keystore/legacy_keymaster_device_wrapper.cpp
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- **
- ** Copyright 2016, 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 "android.hardware.keymaster@3.0-impl"
-
-#include "legacy_keymaster_device_wrapper.h"
-
-#include <log/log.h>
-
-#include <hardware/keymaster2.h>
-#include <hardware/keymaster_defs.h>
-#include <keymaster/keymaster_configuration.h>
-#include <keymaster/soft_keymaster_device.h>
-
-namespace android {
-namespace keystore {
-
-using ::keymaster::SoftKeymasterDevice;
-
-LegacyKeymasterDeviceWrapper::LegacyKeymasterDeviceWrapper(keymaster2_device_t* dev)
-    : keymaster_device_(dev) {}
-
-LegacyKeymasterDeviceWrapper::~LegacyKeymasterDeviceWrapper() {
-    if (keymaster_device_) keymaster_device_->common.close(&keymaster_device_->common);
-}
-
-static inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) {
-    return keymaster_tag_get_type(tag);
-}
-
-/**
- * legacy_enum_conversion converts enums from hidl to keymaster and back. Currently, this is just a
- * cast to make the compiler happy. One of two thigs should happen though:
- * TODO The keymaster enums should become aliases for the hidl generated enums so that we have a
- *      single point of truth. Then this cast function can go away.
- */
-inline static keymaster_tag_t legacy_enum_conversion(const Tag value) {
-    return keymaster_tag_t(value);
-}
-inline static Tag legacy_enum_conversion(const keymaster_tag_t value) {
-    return Tag(value);
-}
-inline static keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) {
-    return keymaster_purpose_t(value);
-}
-inline static keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) {
-    return keymaster_key_format_t(value);
-}
-inline static ErrorCode legacy_enum_conversion(const keymaster_error_t value) {
-    return ErrorCode(value);
-}
-
-class KmParamSet : public keymaster_key_param_set_t {
-  public:
-    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) {
-            auto tag = legacy_enum_conversion(keyParams[i].tag);
-            switch (typeFromTag(tag)) {
-            case KM_ENUM:
-            case KM_ENUM_REP:
-                params[i] = keymaster_param_enum(tag, keyParams[i].f.integer);
-                break;
-            case KM_UINT:
-            case KM_UINT_REP:
-                params[i] = keymaster_param_int(tag, keyParams[i].f.integer);
-                break;
-            case KM_ULONG:
-            case KM_ULONG_REP:
-                params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger);
-                break;
-            case KM_DATE:
-                params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime);
-                break;
-            case KM_BOOL:
-                if (keyParams[i].f.boolValue)
-                    params[i] = keymaster_param_bool(tag);
-                else
-                    params[i].tag = KM_TAG_INVALID;
-                break;
-            case KM_BIGNUM:
-            case KM_BYTES:
-                params[i] =
-                    keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size());
-                break;
-            case KM_INVALID:
-            default:
-                params[i].tag = KM_TAG_INVALID;
-                /* just skip */
-                break;
-            }
-        }
-    }
-    KmParamSet(KmParamSet&& other) noexcept
-        : keymaster_key_param_set_t{other.params, other.length} {
-        other.length = 0;
-        other.params = nullptr;
-    }
-    KmParamSet(const KmParamSet&) = delete;
-    ~KmParamSet() { delete[] params; }
-};
-
-inline static KmParamSet hidlParams2KmParamSet(const hidl_vec<KeyParameter>& params) {
-    return KmParamSet(params);
-}
-
-inline static keymaster_blob_t hidlVec2KmBlob(const hidl_vec<uint8_t>& blob) {
-    /* hidl unmarshals funny pointers if the the blob is empty */
-    if (blob.size()) return {&blob[0], blob.size()};
-    return {};
-}
-
-inline static keymaster_key_blob_t hidlVec2KmKeyBlob(const hidl_vec<uint8_t>& blob) {
-    /* hidl unmarshals funny pointers if the the blob is empty */
-    if (blob.size()) return {&blob[0], blob.size()};
-    return {};
-}
-
-inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_key_blob_t& blob) {
-    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) {
-    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>>
-kmCertChain2Hidl(const keymaster_cert_chain_t* cert_chain) {
-    hidl_vec<hidl_vec<uint8_t>> result;
-    if (!cert_chain || cert_chain->entry_count == 0 || !cert_chain->entries) return result;
-
-    result.resize(cert_chain->entry_count);
-    for (size_t i = 0; i < cert_chain->entry_count; ++i) {
-        auto& entry = cert_chain->entries[i];
-        result[i] = kmBlob2hidlVec(entry);
-    }
-
-    return result;
-}
-
-static inline hidl_vec<KeyParameter> kmParamSet2Hidl(const keymaster_key_param_set_t& set) {
-    hidl_vec<KeyParameter> result;
-    if (set.length == 0 || set.params == nullptr) return result;
-
-    result.resize(set.length);
-    keymaster_key_param_t* params = set.params;
-    for (size_t i = 0; i < set.length; ++i) {
-        auto tag = params[i].tag;
-        result[i].tag = legacy_enum_conversion(tag);
-        switch (typeFromTag(tag)) {
-        case KM_ENUM:
-        case KM_ENUM_REP:
-            result[i].f.integer = params[i].enumerated;
-            break;
-        case KM_UINT:
-        case KM_UINT_REP:
-            result[i].f.integer = params[i].integer;
-            break;
-        case KM_ULONG:
-        case KM_ULONG_REP:
-            result[i].f.longInteger = params[i].long_integer;
-            break;
-        case KM_DATE:
-            result[i].f.dateTime = params[i].date_time;
-            break;
-        case KM_BOOL:
-            result[i].f.boolValue = params[i].boolean;
-            break;
-        case KM_BIGNUM:
-        case KM_BYTES:
-            result[i].blob = kmBlob2hidlVec(params[i].blob);
-            break;
-        case KM_INVALID:
-        default:
-            params[i].tag = KM_TAG_INVALID;
-            /* just skip */
-            break;
-        }
-    }
-    return result;
-}
-
-// Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
-Return<void> LegacyKeymasterDeviceWrapper::getHardwareFeatures(getHardwareFeatures_cb _hidl_cb) {
-    _hidl_cb(false, false, false, false, false, "Fallback Device", "Google Android Security");
-    return Void();
-}
-
-Return<ErrorCode> LegacyKeymasterDeviceWrapper::addRngEntropy(const hidl_vec<uint8_t>& data) {
-    return legacy_enum_conversion(
-        keymaster_device_->add_rng_entropy(keymaster_device_, &data[0], data.size()));
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::generateKey(const hidl_vec<KeyParameter>& keyParams,
-                                                       generateKey_cb _hidl_cb) {
-    // result variables for the wire
-    KeyCharacteristics resultCharacteristics;
-    hidl_vec<uint8_t> resultKeyBlob;
-
-    // result variables the backend understands
-    keymaster_key_blob_t key_blob{nullptr, 0};
-    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
-
-    // convert the parameter set to something our backend understands
-    auto kmParams = hidlParams2KmParamSet(keyParams);
-
-    auto rc = keymaster_device_->generate_key(keymaster_device_, &kmParams, &key_blob,
-                                              &key_characteristics);
-
-    if (rc == KM_ERROR_OK) {
-        // on success convert the result to wire format
-        resultKeyBlob = kmBlob2hidlVec(key_blob);
-        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
-        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
-    }
-
-    // send results off to the client
-    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics);
-
-    // free buffers that we are responsible for
-    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
-    keymaster_free_characteristics(&key_characteristics);
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::getKeyCharacteristics(
-    const hidl_vec<uint8_t>& keyBlob, const hidl_vec<uint8_t>& clientId,
-    const hidl_vec<uint8_t>& appData, getKeyCharacteristics_cb _hidl_cb) {
-    // result variables for the wire
-    KeyCharacteristics resultCharacteristics;
-
-    // result variables the backend understands
-    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
-
-    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
-    auto kmClientId = hidlVec2KmBlob(clientId);
-    auto kmAppData = hidlVec2KmBlob(appData);
-
-    auto rc = keymaster_device_->get_key_characteristics(
-        keymaster_device_, keyBlob.size() ? &kmKeyBlob : nullptr,
-        clientId.size() ? &kmClientId : nullptr, appData.size() ? &kmAppData : nullptr,
-        &key_characteristics);
-
-    if (rc == KM_ERROR_OK) {
-        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
-        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultCharacteristics);
-
-    keymaster_free_characteristics(&key_characteristics);
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::importKey(const hidl_vec<KeyParameter>& params,
-                                                     KeyFormat keyFormat,
-                                                     const hidl_vec<uint8_t>& keyData,
-                                                     importKey_cb _hidl_cb) {
-    // result variables for the wire
-    KeyCharacteristics resultCharacteristics;
-    hidl_vec<uint8_t> resultKeyBlob;
-
-    // result variables the backend understands
-    keymaster_key_blob_t key_blob{nullptr, 0};
-    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
-
-    auto kmParams = hidlParams2KmParamSet(params);
-    auto kmKeyData = hidlVec2KmBlob(keyData);
-
-    auto rc = keymaster_device_->import_key(keymaster_device_, &kmParams,
-                                            legacy_enum_conversion(keyFormat), &kmKeyData,
-                                            &key_blob, &key_characteristics);
-
-    if (rc == KM_ERROR_OK) {
-        // on success convert the result to wire format
-        resultKeyBlob = kmBlob2hidlVec(key_blob);
-        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
-        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics);
-
-    // free buffers that we are responsible for
-    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
-    keymaster_free_characteristics(&key_characteristics);
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::exportKey(KeyFormat exportFormat,
-                                                     const hidl_vec<uint8_t>& keyBlob,
-                                                     const hidl_vec<uint8_t>& clientId,
-                                                     const hidl_vec<uint8_t>& appData,
-                                                     exportKey_cb _hidl_cb) {
-
-    // result variables for the wire
-    hidl_vec<uint8_t> resultKeyBlob;
-
-    // result variables the backend understands
-    keymaster_blob_t out_blob = {};
-
-    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
-    auto kmClientId = hidlVec2KmBlob(clientId);
-    auto kmAppData = hidlVec2KmBlob(appData);
-
-    auto rc = keymaster_device_->export_key(keymaster_device_, legacy_enum_conversion(exportFormat),
-                                            keyBlob.size() ? &kmKeyBlob : nullptr,
-                                            clientId.size() ? &kmClientId : nullptr,
-                                            appData.size() ? &kmAppData : nullptr, &out_blob);
-
-    if (rc == KM_ERROR_OK) {
-        // on success convert the result to wire format
-        // (Can we assume that key_blob is {nullptr, 0} or a valid buffer description?)
-        resultKeyBlob = kmBlob2hidlVec(out_blob);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob);
-
-    // free buffers that we are responsible for
-    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::attestKey(const hidl_vec<uint8_t>& keyToAttest,
-                                                     const hidl_vec<KeyParameter>& attestParams,
-                                                     attestKey_cb _hidl_cb) {
-
-    hidl_vec<hidl_vec<uint8_t>> resultCertChain;
-
-    for (size_t i = 0; i < attestParams.size(); ++i) {
-        switch (attestParams[i].tag) {
-            case Tag::ATTESTATION_ID_BRAND:
-            case Tag::ATTESTATION_ID_DEVICE:
-            case Tag::ATTESTATION_ID_PRODUCT:
-            case Tag::ATTESTATION_ID_SERIAL:
-            case Tag::ATTESTATION_ID_IMEI:
-            case Tag::ATTESTATION_ID_MEID:
-            case Tag::ATTESTATION_ID_MANUFACTURER:
-            case Tag::ATTESTATION_ID_MODEL:
-                // Device id attestation may only be supported if the device is able to permanently
-                // destroy its knowledge of the ids. This device is unable to do this, so it must
-                // never perform any device id attestation.
-                _hidl_cb(ErrorCode::CANNOT_ATTEST_IDS, resultCertChain);
-                return Void();
-            default:
-                break;
-        }
-    }
-
-    keymaster_cert_chain_t cert_chain = {};
-
-    auto kmKeyToAttest = hidlVec2KmKeyBlob(keyToAttest);
-    auto kmAttestParams = hidlParams2KmParamSet(attestParams);
-
-    auto rc = keymaster_device_->attest_key(keymaster_device_, &kmKeyToAttest, &kmAttestParams,
-                                            &cert_chain);
-
-    if (rc == KM_ERROR_OK) {
-        resultCertChain = kmCertChain2Hidl(&cert_chain);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultCertChain);
-
-    keymaster_free_cert_chain(&cert_chain);
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
-                                                      const hidl_vec<KeyParameter>& upgradeParams,
-                                                      upgradeKey_cb _hidl_cb) {
-
-    // result variables for the wire
-    hidl_vec<uint8_t> resultKeyBlob;
-
-    // result variables the backend understands
-    keymaster_key_blob_t key_blob = {};
-
-    auto kmKeyBlobToUpgrade = hidlVec2KmKeyBlob(keyBlobToUpgrade);
-    auto kmUpgradeParams = hidlParams2KmParamSet(upgradeParams);
-
-    auto rc = keymaster_device_->upgrade_key(keymaster_device_, &kmKeyBlobToUpgrade,
-                                             &kmUpgradeParams, &key_blob);
-
-    if (rc == KM_ERROR_OK) {
-        // on success convert the result to wire format
-        resultKeyBlob = kmBlob2hidlVec(key_blob);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob);
-
-    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
-
-    return Void();
-}
-
-Return<ErrorCode> LegacyKeymasterDeviceWrapper::deleteKey(const hidl_vec<uint8_t>& keyBlob) {
-    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
-    return legacy_enum_conversion(keymaster_device_->delete_key(keymaster_device_, &kmKeyBlob));
-}
-
-Return<ErrorCode> LegacyKeymasterDeviceWrapper::deleteAllKeys() {
-    return legacy_enum_conversion(keymaster_device_->delete_all_keys(keymaster_device_));
-}
-
-Return<ErrorCode> LegacyKeymasterDeviceWrapper::destroyAttestationIds() {
-    return ErrorCode::UNIMPLEMENTED;
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
-                                                 const hidl_vec<KeyParameter>& inParams,
-                                                 begin_cb _hidl_cb) {
-
-    // result variables for the wire
-    hidl_vec<KeyParameter> resultParams;
-    uint64_t resultOpHandle = 0;
-
-    // result variables the backend understands
-    keymaster_key_param_set_t out_params{nullptr, 0};
-    keymaster_operation_handle_t& operation_handle = resultOpHandle;
-
-    auto kmKey = hidlVec2KmKeyBlob(key);
-    auto kmInParams = hidlParams2KmParamSet(inParams);
-
-    auto rc = keymaster_device_->begin(keymaster_device_, legacy_enum_conversion(purpose), &kmKey,
-                                       &kmInParams, &out_params, &operation_handle);
-
-    if (rc == KM_ERROR_OK) resultParams = kmParamSet2Hidl(out_params);
-
-    _hidl_cb(legacy_enum_conversion(rc), resultParams, resultOpHandle);
-
-    keymaster_free_param_set(&out_params);
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::update(uint64_t operationHandle,
-                                                  const hidl_vec<KeyParameter>& inParams,
-                                                  const hidl_vec<uint8_t>& input,
-                                                  update_cb _hidl_cb) {
-    // result variables for the wire
-    uint32_t resultConsumed = 0;
-    hidl_vec<KeyParameter> resultParams;
-    hidl_vec<uint8_t> resultBlob;
-
-    // result variables the backend understands
-    size_t consumed = 0;
-    keymaster_key_param_set_t out_params = {};
-    keymaster_blob_t out_blob = {};
-
-    auto kmInParams = hidlParams2KmParamSet(inParams);
-    auto kmInput = hidlVec2KmBlob(input);
-
-    auto rc = keymaster_device_->update(keymaster_device_, operationHandle, &kmInParams, &kmInput,
-                                        &consumed, &out_params, &out_blob);
-
-    if (rc == KM_ERROR_OK) {
-        resultConsumed = consumed;
-        resultParams = kmParamSet2Hidl(out_params);
-        resultBlob = kmBlob2hidlVec(out_blob);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultConsumed, resultParams, resultBlob);
-
-    keymaster_free_param_set(&out_params);
-    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::finish(uint64_t operationHandle,
-                                                  const hidl_vec<KeyParameter>& inParams,
-                                                  const hidl_vec<uint8_t>& input,
-                                                  const hidl_vec<uint8_t>& signature,
-                                                  finish_cb _hidl_cb) {
-    // result variables for the wire
-    hidl_vec<KeyParameter> resultParams;
-    hidl_vec<uint8_t> resultBlob;
-
-    // result variables the backend understands
-    keymaster_key_param_set_t out_params = {};
-    keymaster_blob_t out_blob = {};
-
-    auto kmInParams = hidlParams2KmParamSet(inParams);
-    auto kmInput = hidlVec2KmBlob(input);
-    auto kmSignature = hidlVec2KmBlob(signature);
-
-    auto rc = keymaster_device_->finish(keymaster_device_, operationHandle, &kmInParams, &kmInput,
-                                        &kmSignature, &out_params, &out_blob);
-
-    if (rc == KM_ERROR_OK) {
-        resultParams = kmParamSet2Hidl(out_params);
-        resultBlob = kmBlob2hidlVec(out_blob);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultParams, resultBlob);
-
-    keymaster_free_param_set(&out_params);
-    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
-
-    return Void();
-}
-
-Return<ErrorCode> LegacyKeymasterDeviceWrapper::abort(uint64_t operationHandle) {
-    return legacy_enum_conversion(keymaster_device_->abort(keymaster_device_, operationHandle));
-}
-
-sp<IKeymasterDevice> makeSoftwareKeymasterDevice() {
-    keymaster2_device_t* dev = nullptr;
-    dev = (new SoftKeymasterDevice(keymaster::KmVersion::KEYMASTER_2))->keymaster2_device();
-
-    auto kmrc = ::keymaster::ConfigureDevice(dev);
-    if (kmrc != KM_ERROR_OK) {
-        dev->common.close(&dev->common);
-        return nullptr;
-    }
-
-    return new LegacyKeymasterDeviceWrapper(dev);
-}
-
-}  // namespace keystore
-}  // namespace android
diff --git a/keystore/legacy_keymaster_device_wrapper.h b/keystore/legacy_keymaster_device_wrapper.h
deleted file mode 100644
index cd2e5a7..0000000
--- a/keystore/legacy_keymaster_device_wrapper.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- **
- ** Copyright 2016, 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 LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
-#define LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
-
-#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <hidl/Status.h>
-#include <hidl/MQDescriptor.h>
-
-struct keymaster2_device;
-typedef struct keymaster2_device keymaster2_device_t;
-
-namespace android {
-namespace keystore {
-
-using ::android::hardware::keymaster::V3_0::ErrorCode;
-using ::android::hardware::keymaster::V3_0::IKeymasterDevice;
-using ::android::hardware::keymaster::V3_0::KeyCharacteristics;
-using ::android::hardware::keymaster::V3_0::KeyFormat;
-using ::android::hardware::keymaster::V3_0::KeyParameter;
-using ::android::hardware::keymaster::V3_0::KeyPurpose;
-using ::android::hardware::keymaster::V3_0::Tag;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
-class LegacyKeymasterDeviceWrapper : public IKeymasterDevice {
-  public:
-    explicit LegacyKeymasterDeviceWrapper(keymaster2_device_t* dev);
-    virtual ~LegacyKeymasterDeviceWrapper();
-
-    // Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
-    Return<void> getHardwareFeatures(getHardwareFeatures_cb _hidl_cb);
-    Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override;
-    Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
-                             generateKey_cb _hidl_cb) override;
-    Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
-                                       const hidl_vec<uint8_t>& clientId,
-                                       const hidl_vec<uint8_t>& appData,
-                                       getKeyCharacteristics_cb _hidl_cb) override;
-    Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
-                           const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override;
-    Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
-                           const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
-                           exportKey_cb _hidl_cb) override;
-    Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
-                           const hidl_vec<KeyParameter>& attestParams,
-                           attestKey_cb _hidl_cb) override;
-    Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
-                            const hidl_vec<KeyParameter>& upgradeParams,
-                            upgradeKey_cb _hidl_cb) override;
-    Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override;
-    Return<ErrorCode> deleteAllKeys() override;
-    Return<ErrorCode> destroyAttestationIds() override;
-    Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
-                       const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) override;
-    Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
-                        const hidl_vec<uint8_t>& input, update_cb _hidl_cb) override;
-    Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
-                        const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
-                        finish_cb _hidl_cb) override;
-    Return<ErrorCode> abort(uint64_t operationHandle) override;
-
-  private:
-    keymaster2_device_t* keymaster_device_;
-};
-
-sp<IKeymasterDevice> makeSoftwareKeymasterDevice();
-
-}  // namespace keystore
-}  // namespace android
-
-#endif  // LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
deleted file mode 100644
index bd4bd5e..0000000
--- a/keystore/operation.cpp
+++ /dev/null
@@ -1,103 +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.
- */
-#define LOG_TAG "KeystoreOperation"
-
-#include "operation.h"
-#include "key_operation_log_handler.h"
-
-#include <algorithm>
-#include <android-base/logging.h>
-#include <mutex>
-
-namespace keystore {
-
-OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
-    : mDeathRecipient(deathRecipient) {}
-
-sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
-                                       const sp<Keymaster>& dev, const sp<IBinder>& appToken,
-                                       KeyCharacteristics&& characteristics,
-                                       const hidl_vec<KeyParameter>& params, bool pruneable) {
-    sp<IBinder> token = new ::android::BBinder();
-    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;
-}
-
-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 op;
-}
-
-void OperationMap::updateLru(const sp<IBinder>& token) {
-    auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
-    if (lruEntry != mLru.end()) {
-        mLru.erase(lruEntry);
-        mLru.push_back(token);
-    }
-}
-
-std::shared_ptr<Operation> OperationMap::removeOperation(const sp<IBinder>& token,
-                                                         bool wasSuccessful, int32_t responseCode) {
-    auto entry = mMap.find(token);
-    if (entry == mMap.end()) return {};
-
-    auto op = entry->second;
-    logKeystoreKeyOperationEvent(*op, wasSuccessful, responseCode);
-    mMap.erase(entry);
-
-    auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
-    if (lruEntry != mLru.end()) mLru.erase(lruEntry);
-    removeOperationTracking(token, op->appToken);
-    return op;
-}
-
-void OperationMap::removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken) {
-    auto appEntry = mAppTokenMap.find(appToken);
-    if (appEntry == mAppTokenMap.end()) {
-        ALOGE("Entry for %p contains unmapped application token %p", token.get(), appToken.get());
-        return;
-    }
-    auto tokenEntry = std::find(appEntry->second.begin(), appEntry->second.end(), token);
-    appEntry->second.erase(tokenEntry);
-    // Stop listening for death if all operations tied to the token have finished.
-    if (appEntry->second.size() == 0) {
-        appToken->unlinkToDeath(mDeathRecipient);
-        mAppTokenMap.erase(appEntry);
-    }
-}
-
-sp<IBinder> OperationMap::getOldestPruneableOperation() {
-    if (mLru.size() == 0) return {};
-
-    return {mLru.front()};
-}
-
-std::vector<sp<IBinder>> OperationMap::getOperationsForToken(const sp<IBinder>& appToken) {
-    auto appEntry = mAppTokenMap.find(appToken);
-    if (appEntry == mAppTokenMap.end()) return {};
-    return appEntry->second;
-}
-
-}  // namespace keystore
diff --git a/keystore/operation.h b/keystore/operation.h
deleted file mode 100644
index 8423db5..0000000
--- a/keystore/operation.h
+++ /dev/null
@@ -1,77 +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.
- */
-
-#ifndef KEYSTORE_OPERATION_H_
-#define KEYSTORE_OPERATION_H_
-
-#include <list>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <optional>
-#include <vector>
-
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-#include <keymasterV4_1/Keymaster.h>
-#include <utils/StrongPointer.h>
-
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore_concurrency.h>
-#include <keystore/keystore_hidl_support.h>
-
-#include "operation_struct.h"
-
-namespace keystore {
-
-using ::android::IBinder;
-using ::android::sp;
-using keymaster::support::Keymaster;
-
-/**
- * OperationMap handles the translation of uint64_t's and keymaster2_device_t's to opaque binder
- * tokens that can be used to reference that operation at a later time by applications. It also does
- * LRU tracking for operation pruning and keeps a mapping of clients to operations to allow for
- * graceful handling of application death.
- */
-
-class OperationMap {
-  public:
-    explicit OperationMap(IBinder::DeathRecipient* deathRecipient);
-    sp<IBinder> addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
-                             const sp<Keymaster>& dev, const sp<IBinder>& appToken,
-                             KeyCharacteristics&& characteristics,
-                             const hidl_vec<KeyParameter>& params, bool pruneable);
-    std::shared_ptr<Operation> getOperation(const sp<IBinder>& token);
-    std::shared_ptr<Operation> removeOperation(const sp<IBinder>& token, bool wasSuccessful,
-                                               int32_t responseCode);
-    size_t getOperationCount() const { return mMap.size(); }
-    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>, std::shared_ptr<Operation>> mMap;
-    std::list<sp<IBinder>> mLru;
-    std::map<sp<IBinder>, std::vector<sp<IBinder>>> mAppTokenMap;
-    IBinder::DeathRecipient* mDeathRecipient;
-};
-
-}  // namespace keystore
-
-#endif
diff --git a/keystore/operation_struct.h b/keystore/operation_struct.h
deleted file mode 100644
index 23e79fc..0000000
--- a/keystore/operation_struct.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef KEYSTORE_OPERATION_STRUCT_H_
-#define KEYSTORE_OPERATION_STRUCT_H_
-
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-#include <keymasterV4_1/Keymaster.h>
-#include <utils/StrongPointer.h>
-
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore_hidl_support.h>
-#include <keystore/keystore_return_types.h>
-
-#include <future>
-
-namespace keystore {
-
-using ::android::IBinder;
-using ::android::sp;
-using keymaster::support::Keymaster;
-
-struct Operation {
-    Operation() = default;
-    Operation(uint64_t handle_, uint64_t keyid_, KeyPurpose purpose_, const sp<Keymaster>& device_,
-              KeyCharacteristics&& characteristics_, sp<IBinder> appToken_,
-              const hidl_vec<KeyParameter> params_)
-        : handle(handle_), keyid(keyid_), purpose(purpose_), device(device_),
-          characteristics(characteristics_), appToken(appToken_), authToken(), verificationToken(),
-          params(params_) {}
-    Operation(Operation&&) = default;
-    Operation(const Operation&) = delete;
-
-    bool hasAuthToken() const { return authToken.mac.size() != 0; }
-
-    uint64_t handle;
-    uint64_t keyid;
-    KeyPurpose purpose;
-    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;
-};
-
-}  // namespace keystore
-
-#endif
diff --git a/keystore/permissions.cpp b/keystore/permissions.cpp
deleted file mode 100644
index 2cd42cf..0000000
--- a/keystore/permissions.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2016 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 "keystore"
-
-#include "permissions.h"
-
-#include <cutils/sockets.h>
-#include <log/log.h>
-#include <private/android_filesystem_config.h>
-
-#include <selinux/android.h>
-
-#include "keystore_utils.h"
-
-/* perm_labels associcated with keystore_key SELinux class verbs. */
-const char* perm_labels[] = {
-    "get_state",
-    "get",
-    "insert",
-    "delete",
-    "exist",
-    "list",
-    "reset",
-    "password",
-    "lock",
-    "unlock",
-    "is_empty",
-    "sign",
-    "verify",
-    "grant",
-    "duplicate",
-    "clear_uid",
-    "add_auth",
-    "user_changed",
-    "gen_unique_id",
-};
-
-struct user_euid {
-    uid_t uid;
-    uid_t euid;
-};
-
-user_euid user_euids[] = {{AID_VPN, AID_SYSTEM},
-                          {AID_WIFI, AID_SYSTEM},
-                          {AID_ROOT, AID_SYSTEM},
-
-#ifdef GRANT_ROOT_ALL_PERMISSIONS
-                          // Allow VTS tests to act on behalf of the wifi user
-                          {AID_WIFI, AID_ROOT}
-#endif
-};
-
-struct user_perm {
-    uid_t uid;
-    perm_t perms;
-};
-
-static user_perm user_perms[] = {
-    {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0))},
-    {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY)},
-    {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY)},
-    {AID_BLUETOOTH, static_cast<perm_t>(P_GET | P_INSERT | P_DELETE | P_EXIST | P_SIGN | P_VERIFY)},
-
-#ifdef GRANT_ROOT_ALL_PERMISSIONS
-    // Allow VTS tests running as root to perform all operations
-    {AID_ROOT, static_cast<perm_t>((uint32_t)(~0))},
-#else
-    {AID_ROOT, static_cast<perm_t>(P_GET)},
-#endif
-};
-
-static const perm_t DEFAULT_PERMS = static_cast<perm_t>(
-    P_GET_STATE | P_GET | P_INSERT | P_DELETE | P_EXIST | P_LIST | P_SIGN | P_VERIFY |
-    P_GEN_UNIQUE_ID /* Only privileged apps can do this, but enforcement is done by SELinux */);
-
-struct audit_data {
-    pid_t pid;
-    uid_t uid;
-    const char* sid;
-};
-
-const char* get_perm_label(perm_t perm) {
-    unsigned int index = ffs(perm);
-    if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) {
-        return perm_labels[index - 1];
-    } else {
-        ALOGE("Keystore: Failed to retrieve permission label.\n");
-        abort();
-    }
-}
-
-static int audit_callback(void* data, security_class_t /* cls */, char* buf, size_t len) {
-    struct audit_data* ad = reinterpret_cast<struct audit_data*>(data);
-    if (!ad) {
-        ALOGE("No keystore audit data");
-        return 0;
-    }
-
-    const char* sid = ad->sid ? ad->sid : "N/A";
-    snprintf(buf, len, "pid=%d uid=%d sid=%s", ad->pid, ad->uid, sid);
-    return 0;
-}
-
-static char* tctx;
-
-int configure_selinux() {
-    union selinux_callback cb;
-    cb.func_audit = audit_callback;
-    selinux_set_callback(SELINUX_CB_AUDIT, cb);
-    cb.func_log = selinux_log_callback;
-    selinux_set_callback(SELINUX_CB_LOG, cb);
-    if (getcon(&tctx) != 0) {
-        ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n");
-        return -1;
-    }
-
-    return 0;
-}
-
-static bool keystore_selinux_check_access(uid_t uid, perm_t perm, pid_t spid, const char* ssid) {
-    audit_data ad;
-    char* sctx = nullptr;
-    const char* selinux_class = "keystore_key";
-    const char* str_perm = get_perm_label(perm);
-
-    if (!str_perm) {
-        return false;
-    }
-
-    if (ssid == nullptr && getpidcon(spid, &sctx) != 0) {
-        ALOGE("SELinux: Failed to get source pid context.\n");
-        return false;
-    }
-
-    const char* use_sid = ssid ? ssid : sctx;
-
-    ad.pid = spid;
-    ad.uid = uid;
-    ad.sid = use_sid;
-
-    bool allowed = selinux_check_access(use_sid, tctx, selinux_class, str_perm,
-                                        reinterpret_cast<void*>(&ad)) == 0;
-    freecon(sctx);
-    return allowed;
-}
-
-/**
- * Returns the UID that the callingUid should act as. This is here for
- * legacy support of the WiFi and VPN systems and should be removed
- * when WiFi can operate in its own namespace.
- */
-uid_t get_keystore_euid(uid_t uid) {
-    for (size_t i = 0; i < sizeof(user_euids) / sizeof(user_euids[0]); i++) {
-        struct user_euid user = user_euids[i];
-        if (user.uid == uid) {
-            return user.euid;
-        }
-    }
-
-    return uid;
-}
-
-bool has_permission(uid_t uid, perm_t perm, pid_t spid, const char* sid) {
-    // All system users are equivalent for multi-user support.
-    if (get_app_id(uid) == AID_SYSTEM) {
-        uid = AID_SYSTEM;
-    }
-
-    if (sid == nullptr) {
-        android_errorWriteLog(0x534e4554, "121035042");
-    }
-
-    for (size_t i = 0; i < sizeof(user_perms) / sizeof(user_perms[0]); i++) {
-        struct user_perm user = user_perms[i];
-        if (user.uid == uid) {
-            return (user.perms & perm) && keystore_selinux_check_access(uid, perm, spid, sid);
-        }
-    }
-
-    return (DEFAULT_PERMS & perm) && keystore_selinux_check_access(uid, perm, spid, sid);
-}
-
-/**
- * Returns true if the callingUid is allowed to interact in the targetUid's
- * namespace.
- */
-bool is_granted_to(uid_t callingUid, uid_t targetUid) {
-    if (callingUid == targetUid) {
-        return true;
-    }
-    for (size_t i = 0; i < sizeof(user_euids) / sizeof(user_euids[0]); i++) {
-        struct user_euid user = user_euids[i];
-        if (user.euid == callingUid && user.uid == targetUid) {
-            return true;
-        }
-    }
-
-    return false;
-}
diff --git a/keystore/permissions.h b/keystore/permissions.h
deleted file mode 100644
index 1dd0089..0000000
--- a/keystore/permissions.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2016 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_PERMISSIONS_H_
-#define KEYSTORE_PERMISSIONS_H_
-
-#include <unistd.h>
-
-/* Here are the permissions, actions, users, and the main function. */
-enum perm_t {
-    P_GET_STATE = 1 << 0,
-    P_GET = 1 << 1,
-    P_INSERT = 1 << 2,
-    P_DELETE = 1 << 3,
-    P_EXIST = 1 << 4,
-    P_LIST = 1 << 5,
-    P_RESET = 1 << 6,
-    P_PASSWORD = 1 << 7,
-    P_LOCK = 1 << 8,
-    P_UNLOCK = 1 << 9,
-    P_IS_EMPTY = 1 << 10,
-    P_SIGN = 1 << 11,
-    P_VERIFY = 1 << 12,
-    P_GRANT = 1 << 13,
-    P_DUPLICATE = 1 << 14,
-    P_CLEAR_UID = 1 << 15,
-    P_ADD_AUTH = 1 << 16,
-    P_USER_CHANGED = 1 << 17,
-    P_GEN_UNIQUE_ID = 1 << 18,
-};
-
-const char* get_perm_label(perm_t perm);
-
-/**
- * Returns the UID that the callingUid should act as. This is here for
- * legacy support of the WiFi and VPN systems and should be removed
- * when WiFi can operate in its own namespace.
- */
-uid_t get_keystore_euid(uid_t uid);
-
-/**
- * Returns true if the uid/pid/sid has a permission. Checks based on sid if available.
- *
- * sid may be null on older kernels
- */
-bool has_permission(uid_t uid, perm_t perm, pid_t spid, const char* sid);
-
-/**
- * Returns true if the callingUid is allowed to interact in the targetUid's
- * namespace.
- */
-bool is_granted_to(uid_t callingUid, uid_t targetUid);
-
-int configure_selinux();
-
-/*
- * Keystore grants.
- *
- * What are keystore grants?
- *
- * Keystore grants are a mechanism that allows an app to grant the permission to use one of its
- * keys to an other app.
- *
- * Liftime of a grant:
- *
- * A keystore grant is ephemeral in that is never persistently stored. When the keystore process
- * exits, all grants are lost. Also, grants can be explicitly revoked by the granter by invoking
- * the ungrant operation.
- *
- * What happens when a grant is created?
- *
- * The grant operation expects a valid key alias and the uid of the grantee, i.e., the app that
- * shall be allowed to use the key denoted by the alias. It then makes an entry in the grant store
- * which generates a new alias of the form <alias>_KEYSTOREGRANT_<random_grant_no_>. This grant
- * alias is returned to the caller which can pass the new alias to the grantee. For every grantee,
- * the grant store keeps a set of grants, an entry of which holds the following information:
- *  - the owner of the key by uid, aka granter uid,
- *  - the original alias of the granted key, and
- *  - the random grant number.
- * (See "grant_store.h:class Grant")
- *
- * What happens when a grant is used?
- *
- * Upon any keystore operation that expects an alias, the alias and the caller's uid are used
- * to retrieve a key file. If that fails some operations try to retrieve a key file indirectly
- * through a grant. These operations include:
- *  - attestKey
- *  - begin
- *  - exportKey
- *  - get
- *  - getKeyCharacteristics
- *  - del
- *  - exist
- *  - getmtime
- * Operations that DO NOT follow the grant indirection are:
- *  - import
- *  - generate
- *  - grant
- *  - ungrant
- * Especially, the latter two mean that neither can a grantee transitively grant a granted key
- * to a third, nor can they relinquish access to the key or revoke access to the key by a third.
- */
-
-#endif  // KEYSTORE_PERMISSIONS_H_
diff --git a/keystore/tests/Android.bp b/keystore/tests/Android.bp
index 327eb93..249cb77 100644
--- a/keystore/tests/Android.bp
+++ b/keystore/tests/Android.bp
@@ -18,10 +18,6 @@
     ],
     srcs: [
         "aaid_truncation_test.cpp",
-        "auth_token_table_test.cpp",
-        "auth_token_formatting_test.cpp",
-        "blob_test.cpp",
-        "confirmationui_rate_limiting_test.cpp",
         "verification_token_seralization_test.cpp",
         "gtest_main.cpp",
     ],
@@ -35,7 +31,6 @@
         "libhidlbase",
         "libkeymaster4support",
         "libkeymaster4_1support",
-        "libkeystore_test",
         "liblog",
         "libutils",
     ],
@@ -63,17 +58,14 @@
     ],
     name: "confirmationui_invocation_test",
     static_libs: [
-        "android.hardware.confirmationui@1.0",
         "libbase",
         "libgtest_main",
         "libutils",
         "liblog",
     ],
     shared_libs: [
-        "libbinder",
-        "libkeystore_aidl", // for IKeyStoreService.asInterface()
-        "libkeystore_binder",
-        "libkeystore_parcelables",
+        "android.security.apc-ndk_platform",
+        "libbinder_ndk",
     ],
    sanitize: {
      cfi: false,
diff --git a/keystore/tests/confirmationui_invocation_test.cpp b/keystore/tests/confirmationui_invocation_test.cpp
index f5182b5..7f8a373 100644
--- a/keystore/tests/confirmationui_invocation_test.cpp
+++ b/keystore/tests/confirmationui_invocation_test.cpp
@@ -15,11 +15,10 @@
 ** limitations under the License.
 */
 
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <android/security/BnConfirmationPromptCallback.h>
-#include <android/security/keystore/IKeystoreService.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
+#include <aidl/android/security/apc/BnConfirmationCallback.h>
+#include <aidl/android/security/apc/IProtectedConfirmation.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
 
 #include <gtest/gtest.h>
 
@@ -28,65 +27,50 @@
 #include <tuple>
 #include <vector>
 
-using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
-using android::IBinder;
-using android::IServiceManager;
-using android::sp;
-using android::String16;
-using android::security::keystore::IKeystoreService;
-
 using namespace std::literals::chrono_literals;
+namespace apc = ::aidl::android::security::apc;
 
 class ConfirmationListener
-    : public android::security::BnConfirmationPromptCallback,
-      public std::promise<std::tuple<ConfirmationResponseCode, std::vector<uint8_t>>> {
+    : public apc::BnConfirmationCallback,
+      public std::promise<std::tuple<apc::ResponseCode, std::optional<std::vector<uint8_t>>>> {
   public:
     ConfirmationListener() {}
 
-    virtual ::android::binder::Status
-    onConfirmationPromptCompleted(int32_t result,
-                                  const ::std::vector<uint8_t>& dataThatWasConfirmed) override {
-        this->set_value({static_cast<ConfirmationResponseCode>(result), dataThatWasConfirmed});
-        return ::android::binder::Status::ok();
-    }
+    virtual ::ndk::ScopedAStatus
+    onCompleted(::aidl::android::security::apc::ResponseCode result,
+                const std::optional<std::vector<uint8_t>>& dataConfirmed) override {
+        this->set_value({result, dataConfirmed});
+        return ::ndk::ScopedAStatus::ok();
+    };
 };
 
 TEST(ConfirmationInvocationTest, InvokeAndCancel) {
-    android::ProcessState::self()->startThreadPool();
+    ABinderProcess_startThreadPool();
 
-    sp<IServiceManager> sm = android::defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<IKeystoreService> service = android::interface_cast<IKeystoreService>(binder);
-    ASSERT_TRUE(service);
+    ::ndk::SpAIBinder apcBinder(AServiceManager_getService("android.security.apc"));
+    auto apcService = apc::IProtectedConfirmation::fromBinder(apcBinder);
+    ASSERT_TRUE(apcService);
 
-    String16 promptText16("Just a little test!");
-    String16 locale16("en");
+    std::string promptText("Just a little test!");
+    std::string locale("en");
     std::vector<uint8_t> extraData{0xaa, 0xff, 0x00, 0x55};
 
-    sp<ConfirmationListener> listener = new ConfirmationListener();
+    auto listener = std::make_shared<ConfirmationListener>();
 
     auto future = listener->get_future();
-    int32_t aidl_return;
 
-    android::binder::Status status = service->presentConfirmationPrompt(
-        listener, promptText16, extraData, locale16, 0, &aidl_return);
-    ASSERT_TRUE(status.isOk()) << "Presenting confirmation prompt failed with binder status '"
-                               << status.toString8().c_str() << "'.\n";
-    ConfirmationResponseCode responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
-    ASSERT_EQ(responseCode, ConfirmationResponseCode::OK)
-        << "Presenting confirmation prompt failed with response code " << aidl_return << ".\n";
+    auto rc = apcService->presentPrompt(listener, promptText, extraData, locale, 0);
+
+    ASSERT_TRUE(rc.isOk());
 
     auto fstatus = future.wait_for(2s);
     EXPECT_EQ(fstatus, std::future_status::timeout);
 
-    status = service->cancelConfirmationPrompt(listener, &aidl_return);
-    ASSERT_TRUE(status.isOk());
-
-    responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
-    ASSERT_EQ(responseCode, ConfirmationResponseCode::OK);
+    rc = apcService->cancelPrompt(listener);
+    ASSERT_TRUE(rc.isOk());
 
     future.wait();
-    auto [rc, dataThatWasConfirmed] = future.get();
+    auto [responseCode, dataThatWasConfirmed] = future.get();
 
-    ASSERT_EQ(rc, ConfirmationResponseCode::Aborted);
+    ASSERT_EQ(responseCode, apc::ResponseCode::ABORTED);
 }
diff --git a/keystore2/aidl/Android.bp b/keystore2/aidl/Android.bp
index 0db2f9d..06fdb48 100644
--- a/keystore2/aidl/Android.bp
+++ b/keystore2/aidl/Android.bp
@@ -34,6 +34,10 @@
         rust: {
             enabled: true,
         },
+        ndk: {
+            enabled: true,
+            apps_enabled: false,
+        }
     },
 }
 
@@ -72,6 +76,9 @@
         rust: {
             enabled: true,
         },
+        ndk: {
+            enabled: true,
+        }
     },
 }
 
@@ -95,7 +102,7 @@
         ndk: {
             enabled: true,
             apps_enabled: false,
-        }
+        },
     },
 }
 
@@ -113,6 +120,7 @@
         },
         ndk: {
             enabled: true,
+            apps_enabled: false,
         },
         rust: {
             enabled: true,
