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);
 }
