Merge QQ1A.191205.011 into stage-aosp-master

Bug: 144955631
Merged-In: Ie6ce8f381affe89137c911b3964412a1c16fdb80
Change-Id: I53cad5f2e532ef4e7745df6e7cd55d17504ba62b
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index c8dbf77..dcf92be 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -3,3 +3,6 @@
 
 [Builtin Hooks Options]
 clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+
+[Hook Scripts]
+aosp_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "."
diff --git a/fsverity_init/Android.bp b/fsverity_init/Android.bp
new file mode 100644
index 0000000..407849d
--- /dev/null
+++ b/fsverity_init/Android.bp
@@ -0,0 +1,18 @@
+cc_binary {
+    name: "fsverity_init",
+    srcs: [
+        "fsverity_init.cpp",
+    ],
+    static_libs: [
+        "libc++fs",
+        "libmini_keyctl_static",
+    ],
+    shared_libs: [
+        "libbase",
+        "libkeystore_binder",
+        "libkeyutils",
+        "liblog",
+        "liblogwrap",
+    ],
+    cflags: ["-Werror", "-Wall", "-Wextra"],
+}
diff --git a/fsverity_init/fsverity_init.cpp b/fsverity_init/fsverity_init.cpp
new file mode 100644
index 0000000..7052375
--- /dev/null
+++ b/fsverity_init/fsverity_init.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2019 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 "fsverity_init"
+
+#include <sys/types.h>
+
+#include <filesystem>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <keystore/keystore_client.h>
+#include <keystore/keystore_client_impl.h>
+#include <keystore/keystore_get.h>
+#include <log/log.h>
+#include <mini_keyctl_utils.h>
+#include <private/android_filesystem_config.h>
+
+bool LoadKeyToKeyring(key_serial_t keyring_id, const char* desc, const char* data, size_t size) {
+    key_serial_t key = add_key("asymmetric", desc, data, size, keyring_id);
+    if (key < 0) {
+        PLOG(ERROR) << "Failed to add key";
+        return false;
+    }
+    return true;
+}
+
+void LoadKeyFromVerifiedPartitions(key_serial_t keyring_id) {
+    const char* dir = "/product/etc/security/fsverity";
+    if (!std::filesystem::exists(dir)) {
+        LOG(ERROR) << "no such dir: " << dir;
+        return;
+    }
+    for (const auto& entry : std::filesystem::directory_iterator(dir)) {
+        if (!android::base::EndsWithIgnoreCase(entry.path().c_str(), ".der")) continue;
+        std::string content;
+        if (!android::base::ReadFileToString(entry.path(), &content)) {
+            continue;
+        }
+        if (!LoadKeyToKeyring(keyring_id, "fsv_system", content.c_str(), content.size())) {
+            LOG(ERROR) << "Failed to load key from " << entry.path();
+        }
+    }
+}
+
+std::unique_ptr<keystore::KeystoreClient> CreateKeystoreInstance() {
+    return std::unique_ptr<keystore::KeystoreClient>(
+        static_cast<keystore::KeystoreClient*>(new keystore::KeystoreClientImpl));
+}
+
+void LoadKeysFromKeystore(key_serial_t keyring_id) {
+    auto client = CreateKeystoreInstance();
+
+    std::vector<std::string> aliases;
+    if (client == nullptr || !client->listKeysOfUid("FSV_", AID_FSVERITY_CERT, &aliases)) {
+        LOG(ERROR) << "Failed to list key";
+        return;
+    }
+
+    // Always try to load all keys even if some fails to load. The rest may still
+    // be important to have.
+    for (auto& alias : aliases) {
+        auto blob = client->getKey(alias, AID_FSVERITY_CERT);
+        if (!LoadKeyToKeyring(keyring_id, "fsv_user", reinterpret_cast<char*>(blob->data()),
+                              blob->size())) {
+            LOG(ERROR) << "Failed to load key " << alias << " from keyring";
+        }
+    }
+}
+
+int main(int /*argc*/, const char** /*argv*/) {
+    key_serial_t keyring_id = android::GetKeyringId(".fs-verity");
+    if (keyring_id < 0) {
+        LOG(ERROR) << "Failed to find .fs-verity keyring id";
+        return -1;
+    }
+
+    // Requires files backed by fs-verity to be verified with a key in .fs-verity
+    // keyring.
+    if (!android::base::WriteStringToFile("1", "/proc/sys/fs/verity/require_signatures")) {
+        PLOG(ERROR) << "Failed to enforce fs-verity signature";
+    }
+
+    LoadKeyFromVerifiedPartitions(keyring_id);
+    LoadKeysFromKeystore(keyring_id);
+
+    if (!android::base::GetBoolProperty("ro.debuggable", false)) {
+        if (keyctl_restrict_keyring(keyring_id, nullptr, nullptr) < 0) {
+            PLOG(ERROR) << "Cannot restrict .fs-verity keyring";
+        }
+    }
+    return 0;
+}
diff --git a/keystore-engine/Android.bp b/keystore-engine/Android.bp
index 60f5940..6512c66 100644
--- a/keystore-engine/Android.bp
+++ b/keystore-engine/Android.bp
@@ -63,7 +63,6 @@
         "libcrypto",
         "liblog",
         "libhidlbase",
-        "libhidltransport",
         "libcutils",
         "libutils",
     ],
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
index 856194d..e3525b2 100644
--- a/keystore-engine/android_engine.cpp
+++ b/keystore-engine/android_engine.cpp
@@ -251,32 +251,11 @@
       EC_KEY_get_ex_data(ec_key, g_keystore_engine->ec_key_ex_index()));
 }
 
-struct EVP_PKEY_Delete {
-    void operator()(EVP_PKEY* p) const {
-        EVP_PKEY_free(p);
-    }
-};
-typedef std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
-
-struct RSA_Delete {
-    void operator()(RSA* p) const {
-        RSA_free(p);
-    }
-};
-typedef std::unique_ptr<RSA, RSA_Delete> Unique_RSA;
-
-struct EC_KEY_Delete {
-    void operator()(EC_KEY* ec) const {
-        EC_KEY_free(ec);
-    }
-};
-typedef std::unique_ptr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
-
 /* wrap_rsa returns an |EVP_PKEY| that contains an RSA key where the public
  * part is taken from |public_rsa| and the private operations are forwarded to
  * KeyStore and operate on the key named |key_id|. */
 static EVP_PKEY *wrap_rsa(const char *key_id, const RSA *public_rsa) {
-    Unique_RSA rsa(RSA_new_method(g_keystore_engine->engine()));
+    bssl::UniquePtr<RSA> rsa(RSA_new_method(g_keystore_engine->engine()));
     if (rsa.get() == nullptr) {
         return nullptr;
     }
@@ -298,7 +277,7 @@
         return nullptr;
     }
 
-    Unique_EVP_PKEY result(EVP_PKEY_new());
+    bssl::UniquePtr<EVP_PKEY> result(EVP_PKEY_new());
     if (result.get() == nullptr ||
         !EVP_PKEY_assign_RSA(result.get(), rsa.get())) {
         return nullptr;
@@ -312,7 +291,7 @@
  * part is taken from |public_rsa| and the private operations are forwarded to
  * KeyStore and operate on the key named |key_id|. */
 static EVP_PKEY *wrap_ecdsa(const char *key_id, const EC_KEY *public_ecdsa) {
-    Unique_EC_KEY ec(EC_KEY_new_method(g_keystore_engine->engine()));
+    bssl::UniquePtr<EC_KEY> ec(EC_KEY_new_method(g_keystore_engine->engine()));
     if (ec.get() == nullptr) {
         return nullptr;
     }
@@ -333,7 +312,7 @@
         return nullptr;
     }
 
-    Unique_EVP_PKEY result(EVP_PKEY_new());
+    bssl::UniquePtr<EVP_PKEY> result(EVP_PKEY_new());
     if (result.get() == nullptr ||
         !EVP_PKEY_assign_EC_KEY(result.get(), ec.get())) {
         return nullptr;
@@ -370,7 +349,7 @@
     }
 
     const uint8_t *inp = pubkey;
-    Unique_EVP_PKEY pkey(d2i_PUBKEY(nullptr, &inp, pubkey_len));
+    bssl::UniquePtr<EVP_PKEY> pkey(d2i_PUBKEY(nullptr, &inp, pubkey_len));
     if (pkey.get() == nullptr) {
         ALOGW("Cannot convert pubkey");
         return nullptr;
@@ -379,12 +358,12 @@
     EVP_PKEY *result;
     switch (EVP_PKEY_type(pkey->type)) {
     case EVP_PKEY_RSA: {
-        Unique_RSA public_rsa(EVP_PKEY_get1_RSA(pkey.get()));
+        bssl::UniquePtr<RSA> public_rsa(EVP_PKEY_get1_RSA(pkey.get()));
         result = wrap_rsa(key_id, public_rsa.get());
         break;
     }
     case EVP_PKEY_EC: {
-        Unique_EC_KEY public_ecdsa(EVP_PKEY_get1_EC_KEY(pkey.get()));
+        bssl::UniquePtr<EC_KEY> public_ecdsa(EVP_PKEY_get1_EC_KEY(pkey.get()));
         result = wrap_ecdsa(key_id, public_ecdsa.get());
         break;
     }
diff --git a/keystore-engine/keystore_backend_binder.cpp b/keystore-engine/keystore_backend_binder.cpp
index 9a7c63e..8b5a584 100644
--- a/keystore-engine/keystore_backend_binder.cpp
+++ b/keystore-engine/keystore_backend_binder.cpp
@@ -211,9 +211,9 @@
     promise = new OperationResultPromise();
     future = promise->get_future();
 
-    binder_result = service->finish(promise, handle, KeymasterArguments(params),
-                                    std::vector<uint8_t>() /* signature */,
-                                    std::vector<uint8_t>() /* entropy */, &error_code);
+    binder_result = service->finish(
+        promise, handle, KeymasterArguments(params), std::vector<uint8_t>() /* input */,
+        std::vector<uint8_t>() /* signature */, std::vector<uint8_t>() /* entropy */, &error_code);
 
     if (!binder_result.isOk()) {
         LOG(ERROR) << AT << "communication error while calling keystore";
diff --git a/keystore-engine/methods.h b/keystore-engine/methods.h
index da54ce2..853bc57 100644
--- a/keystore-engine/methods.h
+++ b/keystore-engine/methods.h
@@ -29,28 +29,6 @@
 extern int dsa_key_handle;
 extern int rsa_key_handle;
 
-struct DSA_Delete {
-    void operator()(DSA* p) const {
-        DSA_free(p);
-    }
-};
-typedef std::unique_ptr<DSA, struct DSA_Delete> Unique_DSA;
-
-struct EC_KEY_Delete {
-    void operator()(EC_KEY* p) const {
-        EC_KEY_free(p);
-    }
-};
-typedef std::unique_ptr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
-
-struct RSA_Delete {
-    void operator()(RSA* p) const {
-        RSA_free(p);
-    }
-};
-typedef std::unique_ptr<RSA, struct RSA_Delete> Unique_RSA;
-
-
 /* Keyhandles for ENGINE metadata */
 int keyhandle_new(void*, void*, CRYPTO_EX_DATA* ad, int idx, long, void*);
 void keyhandle_free(void *, void *ptr, CRYPTO_EX_DATA*, int, long, void*);
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 356ac1b..f3a7531 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -55,15 +55,12 @@
         "android.hardware.confirmationui@1.0",
         "android.hardware.keymaster@3.0",
         "android.hardware.keymaster@4.0",
-        "android.system.wifi.keystore@1.0",
         "libbase",
         "libbinder",
         "libcrypto",
         "libcutils",
         "libhardware",
         "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
         "libkeymaster4support",
         "libkeymaster_messages",
         "libkeymaster_portable",
@@ -76,7 +73,6 @@
         "libservices",
         "libsoftkeymasterdevice",
         "libutils",
-        "libwifikeystorehal",
     ],
     init_rc: ["keystore.rc"],
     aidl: {
@@ -110,7 +106,6 @@
         "libcrypto",
         "libcutils",
         "libhidlbase",
-        "libhwbinder",
         "libkeystore_aidl", // for IKeyStoreService.asInterface()
         "libkeystore_binder",
         "libkeystore_parcelables",
@@ -135,7 +130,6 @@
         "libchrome",
         "libutils",
         "libhidlbase",
-        "libhwbinder",
         "libkeymaster4support",
         "libkeystore_aidl",
         "libkeystore_binder",
@@ -163,7 +157,6 @@
         "libbinder",
         "libhardware",
         "libhidlbase",
-        "libhwbinder",
         "libkeymaster4support",
         "liblog",
         "libprotobuf-cpp-lite",
@@ -173,7 +166,6 @@
         "android.hardware.keymaster@4.0",
         "libbinder",
         "libhidlbase",
-        "libhwbinder",
         "libkeymaster4support",
     ],
 }
@@ -192,7 +184,6 @@
         "android.hardware.keymaster@4.0",
         "libbinder",
         "libhidlbase",
-        "libhwbinder",
         "libkeymaster4support",
         "libkeystore_aidl",
         "libkeystore_parcelables",
@@ -214,7 +205,6 @@
         "android.hardware.keymaster@4.0",
         "libbinder",
         "libhidlbase",
-        "libhwbinder",
         "libkeystore_aidl",
         "libkeystore_parcelables",
     ],
@@ -230,7 +220,6 @@
         "android.system.wifi.keystore@1.0",
         "libbase",
         "libhidlbase",
-        "libhidltransport",
         "liblog",
         "libutils",
     ],
@@ -261,7 +250,6 @@
         "libbinder",
         "libcrypto",
         "libhidlbase",
-        "libhwbinder",
         "libkeymaster4support",
         "libutils",
         "libkeystore_aidl",
@@ -270,7 +258,6 @@
     export_shared_lib_headers: [
         "android.hardware.keymaster@4.0",
         "libhidlbase",
-        "libhwbinder",
         "libkeymaster4support",
     ],
 
@@ -308,8 +295,6 @@
         "libcutils",
         "libhardware",
         "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
         "libkeystore_parcelables",
         "liblog",
         "libselinux",
diff --git a/keystore/KeyStore.cpp b/keystore/KeyStore.cpp
index d4219bd..7545397 100644
--- a/keystore/KeyStore.cpp
+++ b/keystore/KeyStore.cpp
@@ -402,11 +402,6 @@
     return updated;
 }
 
-struct BIO_Delete {
-    void operator()(BIO* p) const { BIO_free(p); }
-};
-typedef std::unique_ptr<BIO, BIO_Delete> Unique_BIO;
-
 void KeyStore::readMetaData() {
     int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
     if (in < 0) {
diff --git a/keystore/KeyStore.h b/keystore/KeyStore.h
index 69a02ae..a7fbab4 100644
--- a/keystore/KeyStore.h
+++ b/keystore/KeyStore.h
@@ -143,6 +143,23 @@
     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;
@@ -173,6 +190,9 @@
     void writeMetaData();
 
     bool upgradeKeystore();
+
+    std::mutex operationDeviceMapMutex_;
+    std::map<sp<IBinder>, std::shared_ptr<KeymasterWorker>> operationDeviceMap_;
 };
 
 }  // namespace keystore
diff --git a/keystore/binder/android/security/keystore/IKeystoreService.aidl b/keystore/binder/android/security/keystore/IKeystoreService.aidl
index 348964f..f230043 100644
--- a/keystore/binder/android/security/keystore/IKeystoreService.aidl
+++ b/keystore/binder/android/security/keystore/IKeystoreService.aidl
@@ -29,21 +29,29 @@
  * @hide
  */
 interface IKeystoreService {
+    @UnsupportedAppUsage
     int getState(int userId);
+    @UnsupportedAppUsage
     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
     String[] list(String namePrefix, int uid);
-    int reset();
     int onUserPasswordChanged(int userId, String newPassword);
     int lock(int userId);
     int unlock(int userId, String userPassword);
     int isEmpty(int userId);
     String grant(String name, int granteeUid);
+    @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);
@@ -58,7 +66,7 @@
     int begin(in IKeystoreOperationResultCallback cb, IBinder appToken, String alias, int purpose, boolean pruneable,
         in KeymasterArguments params, in byte[] entropy, int uid);
     int update(in IKeystoreOperationResultCallback cb, IBinder token, in KeymasterArguments params, in byte[] input);
-    int finish(in IKeystoreOperationResultCallback cb, IBinder token, in KeymasterArguments params, in byte[] signature,
+    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);
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index 497f304..ffdb454 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -36,21 +36,12 @@
 #include <string>
 
 #include <android-base/logging.h>
+#include <android-base/unique_fd.h>
 
 namespace {
 
 constexpr size_t kGcmIvSizeBytes = 96 / 8;
 
-template <typename T, void (*FreeFunc)(T*)> struct OpenSslObjectDeleter {
-    void operator()(T* p) { FreeFunc(p); }
-};
-
-#define DEFINE_OPENSSL_OBJECT_POINTER(name)                                                        \
-    typedef OpenSslObjectDeleter<name, name##_free> name##_Delete;                                 \
-    typedef std::unique_ptr<name, name##_Delete> name##_Ptr;
-
-DEFINE_OPENSSL_OBJECT_POINTER(EVP_CIPHER_CTX);
-
 #if defined(__clang__)
 #define OPTNONE __attribute__((optnone))
 #elif defined(__GNUC__)
@@ -91,7 +82,7 @@
     // There can be 128-bit and 256-bit keys
     const EVP_CIPHER* cipher = getAesCipherForKey(key);
 
-    EVP_CIPHER_CTX_Ptr ctx(EVP_CIPHER_CTX_new());
+    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 */);
@@ -128,7 +119,7 @@
     // There can be 128-bit and 256-bit keys
     const EVP_CIPHER* cipher = getAesCipherForKey(key);
 
-    EVP_CIPHER_CTX_Ptr ctx(EVP_CIPHER_CTX_new());
+    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 */);
@@ -142,12 +133,12 @@
     EVP_DecryptUpdate(ctx.get(), out_pos, &out_len, in, len);
     out_pos += out_len;
     if (!EVP_DecryptFinal_ex(ctx.get(), out_pos, &out_len)) {
-        ALOGD("Failed to decrypt blob; ciphertext or tag is likely corrupted");
+        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)) {
-        ALOGD("Encrypted plaintext is the wrong size, expected %zu, got %zd", len,
+        ALOGE("Encrypted plaintext is the wrong size, expected %zu, got %zd", len,
               out_pos - out_tmp.get());
         return ResponseCode::VALUE_CORRUPTED;
     }
@@ -341,22 +332,35 @@
 
     size_t fileLength = offsetof(blobv3, value) + dataLength + rawBlob->info;
 
-    int out =
-        TEMP_FAILURE_RETRY(open(filename.c_str(), O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
-    if (out < 0) {
-        ALOGW("could not open file: %s: %s", filename.c_str(), strerror(errno));
+    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;
     }
 
-    const size_t writtenBytes = writeFully(out, reinterpret_cast<uint8_t*>(rawBlob), fileLength);
-    if (close(out) != 0) {
-        return ResponseCode::SYSTEM_ERROR;
-    }
-    if (writtenBytes != fileLength) {
-        ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength);
-        unlink(filename.c_str());
-        return ResponseCode::SYSTEM_ERROR;
-    }
+    fsyncDirectory(getContainingDirectory(filename));
+
     return ResponseCode::NO_ERROR;
 }
 
@@ -401,6 +405,7 @@
     }
 
     if (fileLength == 0) {
+        LOG(ERROR) << __func__ << " VALUE_CORRUPTED file length == 0";
         return ResponseCode::VALUE_CORRUPTED;
     }
 
@@ -412,7 +417,10 @@
         if (state == STATE_UNINITIALIZED) return ResponseCode::UNINITIALIZED;
     }
 
-    if (fileLength < offsetof(blobv3, value)) return ResponseCode::VALUE_CORRUPTED;
+    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);
@@ -428,6 +436,8 @@
                     (rc == ResponseCode::VALUE_CORRUPTED)) {
                     return ResponseCode::KEY_PERMANENTLY_INVALIDATED;
                 }
+                LOG(ERROR) << __func__ << " AES_gcm_decrypt returned: " << uint32_t(rc);
+
                 return rc;
             }
         }
@@ -435,10 +445,16 @@
         blobv2& v2blob = reinterpret_cast<blobv2&>(*rawBlob);
         const size_t headerLength = offsetof(blobv2, encrypted);
         const ssize_t encryptedLength = fileLength - headerLength - v2blob.info;
-        if (encryptedLength < 0) return ResponseCode::VALUE_CORRUPTED;
+        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;
             }
 
@@ -452,6 +468,7 @@
             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;
             }
         }
@@ -462,6 +479,7 @@
     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;
     }
 
diff --git a/keystore/blob.h b/keystore/blob.h
index ce488ec..e0bd146 100644
--- a/keystore/blob.h
+++ b/keystore/blob.h
@@ -37,6 +37,7 @@
 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
diff --git a/keystore/include/keystore/keystore_client.h b/keystore/include/keystore/keystore_client.h
index d6a4807..cb27268 100644
--- a/keystore/include/keystore/keystore_client.h
+++ b/keystore/include/keystore/keystore_client.h
@@ -15,6 +15,8 @@
 #ifndef KEYSTORE_KEYSTORE_CLIENT_H_
 #define KEYSTORE_KEYSTORE_CLIENT_H_
 
+#include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -158,7 +160,7 @@
     // keymaster_error_t on failure.
     virtual KeyStoreNativeReturnCode
     finishOperation(uint64_t handle, const keystore::AuthorizationSet& input_parameters,
-                    const std::string& signature_to_verify,
+                    const std::string& input_data, const std::string& signature_to_verify,
                     keystore::AuthorizationSet* output_parameters, std::string* output_data) = 0;
 
     // Aborts the operation associated with |handle|. Returns KM_ERROR_OK on
@@ -173,6 +175,13 @@
     // caller's key store starting with |prefix|. Returns true on success.
     virtual bool listKeys(const std::string& prefix, std::vector<std::string>* key_name_list) = 0;
 
+    // Provides a |key_name_list| containing all existing key names in the
+    // caller's key store starting with |prefix|. Returns true on success.
+    virtual bool listKeysOfUid(const std::string& prefix, int uid,
+                               std::vector<std::string>* key_name_list) = 0;
+
+    virtual std::optional<std::vector<uint8_t>> getKey(const std::string& alias, int uid) = 0;
+
   private:
     DISALLOW_COPY_AND_ASSIGN(KeystoreClient);
 };
diff --git a/keystore/include/keystore/keystore_client_impl.h b/keystore/include/keystore/keystore_client_impl.h
index 0bcef98..ed8ac44 100644
--- a/keystore/include/keystore/keystore_client_impl.h
+++ b/keystore/include/keystore/keystore_client_impl.h
@@ -19,6 +19,7 @@
 
 #include <future>
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -75,12 +76,16 @@
                                              std::string* output_data) override;
     KeyStoreNativeReturnCode finishOperation(uint64_t handle,
                                              const keystore::AuthorizationSet& input_parameters,
+                                             const std::string& input_data,
                                              const std::string& signature_to_verify,
                                              keystore::AuthorizationSet* output_parameters,
                                              std::string* output_data) override;
     KeyStoreNativeReturnCode abortOperation(uint64_t handle) override;
     bool doesKeyExist(const std::string& key_name) override;
     bool listKeys(const std::string& prefix, std::vector<std::string>* key_name_list) override;
+    bool listKeysOfUid(const std::string& prefix, int uid,
+                       std::vector<std::string>* key_name_list) override;
+    std::optional<std::vector<uint8_t>> getKey(const std::string& alias, int uid) override;
 
   private:
     // Returns an available virtual operation handle.
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index e1b1a66..5adc199 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -70,11 +70,6 @@
 constexpr double kIdRotationPeriod = 30 * 24 * 60 * 60; /* Thirty days, in seconds */
 const char* kTimestampFilePath = "timestamp";
 
-struct BIGNUM_Delete {
-    void operator()(BIGNUM* p) const { BN_free(p); }
-};
-typedef std::unique_ptr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
-
 bool containsTag(const hidl_vec<KeyParameter>& params, Tag tag) {
     return params.end() !=
            std::find_if(params.begin(), params.end(),
@@ -82,7 +77,6 @@
 }
 
 #define AIDL_RETURN(rc) (*_aidl_return = KeyStoreServiceReturnCode(rc).getErrorCode(), Status::ok())
-#define KEYSTORE_SERVICE_LOCK std::lock_guard<std::mutex> keystore_lock(keystoreServiceMutex_)
 
 std::pair<KeyStoreServiceReturnCode, bool> hadFactoryResetSinceIdRotation() {
     struct stat sbuf;
@@ -123,7 +117,8 @@
     auto asn1_attestation_id_result = security::gather_attestation_application_id(callingUid);
     if (!asn1_attestation_id_result.isOk()) {
         ALOGE("failed to gather attestation_id");
-        return ErrorCode::ATTESTATION_APPLICATION_ID_MISSING;
+        // 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;
 
@@ -146,7 +141,6 @@
 }  // anonymous namespace
 
 Status KeyStoreService::getState(int32_t userId, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_GET_STATE)) {
         *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
         return Status::ok();
@@ -156,7 +150,6 @@
 }
 
 Status KeyStoreService::get(const String16& name, int32_t uid, ::std::vector<uint8_t>* item) {
-    KEYSTORE_SERVICE_LOCK;
     uid_t targetUid = getEffectiveUid(uid);
     if (!checkBinderPermission(P_GET, targetUid)) {
         // see keystore/keystore.h
@@ -186,7 +179,6 @@
 
 Status KeyStoreService::insert(const String16& name, const ::std::vector<uint8_t>& item,
                                int targetUid, int32_t flags, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     targetUid = getEffectiveUid(targetUid);
     KeyStoreServiceReturnCode result =
         checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
@@ -212,7 +204,6 @@
 }
 
 Status KeyStoreService::del(const String16& name, int targetUid, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_DELETE, targetUid)) {
         *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
@@ -233,7 +224,6 @@
 }
 
 Status KeyStoreService::exist(const String16& name, int targetUid, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_EXIST, targetUid)) {
         *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
@@ -249,7 +239,6 @@
 
 Status KeyStoreService::list(const String16& prefix, int32_t targetUid,
                              ::std::vector<::android::String16>* matches) {
-    KEYSTORE_SERVICE_LOCK;
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_LIST, targetUid)) {
         return Status::fromServiceSpecificError(
@@ -288,7 +277,6 @@
  */
 Status KeyStoreService::listUidsOfAuthBoundKeys(std::vector<std::string>* uidsOut,
                                                 int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     const int32_t callingUid = IPCThreadState::self()->getCallingUid();
     const int32_t userId = get_user_id(callingUid);
     const int32_t appId = get_app_id(callingUid);
@@ -351,22 +339,8 @@
     return Status::ok();
 }
 
-Status KeyStoreService::reset(int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
-    if (!checkBinderPermission(P_RESET)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    mKeyStore->resetUser(get_user_id(callingUid), false);
-    *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) {
-    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_PASSWORD)) {
         *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
         return Status::ok();
@@ -404,7 +378,6 @@
 }
 
 Status KeyStoreService::onUserAdded(int32_t userId, int32_t parentId, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_USER_CHANGED)) {
         *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
         return Status::ok();
@@ -430,7 +403,6 @@
 }
 
 Status KeyStoreService::onUserRemoved(int32_t userId, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_USER_CHANGED)) {
         *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
         return Status::ok();
@@ -442,7 +414,6 @@
 }
 
 Status KeyStoreService::lock(int32_t userId, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_LOCK)) {
         *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
         return Status::ok();
@@ -462,7 +433,6 @@
 }
 
 Status KeyStoreService::unlock(int32_t userId, const String16& pw, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_UNLOCK)) {
         *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
         return Status::ok();
@@ -493,7 +463,6 @@
 }
 
 Status KeyStoreService::isEmpty(int32_t userId, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_IS_EMPTY)) {
         *aidl_return = static_cast<int32_t>(false);
         return Status::ok();
@@ -505,7 +474,6 @@
 
 Status KeyStoreService::grant(const String16& name, int32_t granteeUid,
                               ::android::String16* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     auto result =
         checkBinderPermissionAndKeystoreState(P_GRANT, /*targetUid=*/-1, /*checkUnlocked=*/false);
@@ -526,7 +494,6 @@
 }
 
 Status KeyStoreService::ungrant(const String16& name, int32_t granteeUid, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     KeyStoreServiceReturnCode result =
         checkBinderPermissionAndKeystoreState(P_GRANT, /*targetUid=*/-1, /*checkUnlocked=*/false);
@@ -547,7 +514,6 @@
 }
 
 Status KeyStoreService::getmtime(const String16& name, int32_t uid, int64_t* time) {
-    KEYSTORE_SERVICE_LOCK;
     uid_t targetUid = getEffectiveUid(uid);
     if (!checkBinderPermission(P_GET, targetUid)) {
         ALOGW("permission denied for %d: getmtime", targetUid);
@@ -586,13 +552,11 @@
 }
 
 Status KeyStoreService::is_hardware_backed(const String16& keyType, int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     *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) {
-    KEYSTORE_SERVICE_LOCK;
     uid_t targetUid = getEffectiveUid(targetUid64);
     if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) {
         return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
@@ -632,7 +596,6 @@
 Status KeyStoreService::addRngEntropy(
     const ::android::sp<::android::security::keystore::IKeystoreResponseCallback>& cb,
     const ::std::vector<uint8_t>& entropy, int32_t flags, int32_t* _aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     auto device = mKeyStore->getDevice(flagsToSecurityLevel(flags));
     if (!device) {
         return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
@@ -649,7 +612,6 @@
     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) {
-    KEYSTORE_SERVICE_LOCK;
     // TODO(jbires): remove this getCallingUid call upon implementation of b/25646100
     uid_t originalUid = IPCThreadState::self()->getCallingUid();
     uid = getEffectiveUid(uid);
@@ -711,7 +673,6 @@
     const String16& name, const ::android::security::keymaster::KeymasterBlob& clientId,
     const ::android::security::keymaster::KeymasterBlob& appData, int32_t uid,
     int32_t* _aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
 
     uid_t targetUid = getEffectiveUid(uid);
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -758,7 +719,6 @@
     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) {
-    KEYSTORE_SERVICE_LOCK;
     uid = getEffectiveUid(uid);
     auto logOnScopeExit = android::base::make_scope_guard([&] {
         if (__android_log_security()) {
@@ -815,7 +775,6 @@
     const ::android::security::keymaster::KeymasterBlob& clientId,
     const ::android::security::keymaster::KeymasterBlob& appData, int32_t uid,
     int32_t* _aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
 
     uid_t targetUid = getEffectiveUid(uid);
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -851,7 +810,6 @@
                               bool pruneable, const KeymasterArguments& params,
                               const ::std::vector<uint8_t>& entropy, int32_t uid,
                               int32_t* _aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     uid_t targetUid = getEffectiveUid(uid);
     if (!is_granted_to(callingUid, targetUid)) {
@@ -888,7 +846,7 @@
                [this, cb, dev](OperationResult result_) {
                    if (result_.resultCode.isOk() ||
                        result_.resultCode == ResponseCode::OP_AUTH_NEEDED) {
-                       addOperationDevice(result_.token, dev);
+                       mKeyStore->addOperationDevice(result_.token, dev);
                    }
                    cb->onFinished(result_);
                });
@@ -900,19 +858,18 @@
                                const ::android::sp<::android::IBinder>& token,
                                const ::android::security::keymaster::KeymasterArguments& params,
                                const ::std::vector<uint8_t>& input, int32_t* _aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     if (!checkAllowedOperationParams(params.getParameters())) {
         return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
     }
 
-    auto dev = getOperationDevice(token);
+    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()) {
-            removeOperationDevice(token);
+            mKeyStore->removeOperationDevice(token);
         }
         cb->onFinished(result_);
     });
@@ -923,23 +880,21 @@
 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) {
-    KEYSTORE_SERVICE_LOCK;
     if (!checkAllowedOperationParams(params.getParameters())) {
         return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
     }
 
-    auto dev = getOperationDevice(token);
+    auto dev = mKeyStore->getOperationDevice(token);
     if (!dev) {
         return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
     }
 
-    dev->finish(token, params.getParameters(), {}, signature, entropy,
+    dev->finish(token, params.getParameters(), input, signature, entropy,
                 [this, cb, token](OperationResult result_) {
-                    if (!result_.resultCode.isOk()) {
-                        removeOperationDevice(token);
-                    }
+                    mKeyStore->removeOperationDevice(token);
                     cb->onFinished(result_);
                 });
 
@@ -949,20 +904,21 @@
 Status KeyStoreService::abort(const ::android::sp<IKeystoreResponseCallback>& cb,
                               const ::android::sp<::android::IBinder>& token,
                               int32_t* _aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
-    auto dev = getOperationDevice(token);
+    auto dev = mKeyStore->getOperationDevice(token);
     if (!dev) {
         return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
     }
 
-    dev->abort(token, [cb](KeyStoreServiceReturnCode rc) { cb->onFinished(rc); });
+    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) {
-    KEYSTORE_SERVICE_LOCK;
 
     // TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
     // receive a HardwareAuthToken, rather than an opaque byte array.
@@ -1013,7 +969,6 @@
 Status KeyStoreService::attestKey(
     const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
     const String16& name, const KeymasterArguments& params, int32_t* _aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     // check null output if method signature is updated and return ErrorCode::OUTPUT_PARAMETER_NULL
     if (!checkAllowedOperationParams(params.getParameters())) {
         return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
@@ -1073,7 +1028,6 @@
 Status KeyStoreService::attestDeviceIds(
     const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
     const KeymasterArguments& params, int32_t* _aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     // check null output if method signature is updated and return ErrorCode::OUTPUT_PARAMETER_NULL
 
     if (!checkAllowedOperationParams(params.getParameters())) {
@@ -1166,7 +1120,6 @@
 }
 
 Status KeyStoreService::onDeviceOffBody(int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     // TODO(tuckeris): add permission check.  This should be callable from ClockworkHome only.
     mKeyStore->getAuthTokenTable().onDeviceOffBody();
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
@@ -1179,7 +1132,6 @@
     const ::android::String16& wrappingKeyAlias, const ::std::vector<uint8_t>& maskingKey,
     const KeymasterArguments& params, int64_t rootSid, int64_t fingerprintSid,
     int32_t* _aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
 
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
 
@@ -1229,19 +1181,16 @@
                                                   const ::std::vector<uint8_t>& extraData,
                                                   const String16& locale, int32_t uiOptionsAsFlags,
                                                   int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     return mKeyStore->getConfirmationManager().presentConfirmationPrompt(
         listener, promptText, extraData, locale, uiOptionsAsFlags, aidl_return);
 }
 
 Status KeyStoreService::cancelConfirmationPrompt(const sp<IBinder>& listener,
                                                  int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     return mKeyStore->getConfirmationManager().cancelConfirmationPrompt(listener, aidl_return);
 }
 
 Status KeyStoreService::isConfirmationPromptSupported(bool* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     return mKeyStore->getConfirmationManager().isConfirmationPromptSupported(aidl_return);
 }
 
@@ -1359,7 +1308,6 @@
 
 Status KeyStoreService::onKeyguardVisibilityChanged(bool isShowing, int32_t userId,
                                                     int32_t* aidl_return) {
-    KEYSTORE_SERVICE_LOCK;
     mKeyStore->getEnforcementPolicy().set_device_locked(isShowing, userId);
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
 
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index 2fdc3dd..a395e6c 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -66,7 +66,6 @@
     ::android::binder::Status listUidsOfAuthBoundKeys(std::vector<::std::string>* uids,
                                                       int32_t* _aidl_return) override;
 
-    ::android::binder::Status reset(int32_t* _aidl_return) override;
     ::android::binder::Status onUserPasswordChanged(int32_t userId,
                                                     const ::android::String16& newPassword,
                                                     int32_t* _aidl_return) override;
@@ -126,8 +125,8 @@
     finish(const ::android::sp<::android::security::keystore::IKeystoreOperationResultCallback>& cb,
            const ::android::sp<::android::IBinder>& token,
            const ::android::security::keymaster::KeymasterArguments& params,
-           const ::std::vector<uint8_t>& signature, const ::std::vector<uint8_t>& entropy,
-           int32_t* _aidl_return) override;
+           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;
@@ -231,37 +230,6 @@
                                          std::vector<KeyParameter>* params);
 
     sp<KeyStore> mKeyStore;
-
-    /**
-     * This mutex locks keystore operations from concurrent execution.
-     * The keystore service has always been conceptually single threaded. Even with the introduction
-     * of keymaster workers, it was assumed that the dispatcher thread executes exclusively on
-     * certain code paths. With the introduction of wifi Keystore service in the keystore process
-     * this assumption no longer holds as the hwbinder thread servicing this interface makes
-     * functions (rather than IPC) calls into keystore. This mutex protects the keystore logic
-     * from concurrent execution.
-     */
-    std::mutex keystoreServiceMutex_;
-
-    std::mutex operationDeviceMapMutex_;
-    std::map<sp<IBinder>, std::shared_ptr<KeymasterWorker>> operationDeviceMap_;
-
-    void addOperationDevice(sp<IBinder> token, std::shared_ptr<KeymasterWorker> dev) {
-        std::lock_guard<std::mutex> lock(operationDeviceMapMutex_);
-        operationDeviceMap_.emplace(std::move(token), std::move(dev));
-    }
-    std::shared_ptr<KeymasterWorker> getOperationDevice(const sp<IBinder>& token) {
-        std::lock_guard<std::mutex> lock(operationDeviceMapMutex_);
-        auto it = operationDeviceMap_.find(token);
-        if (it != operationDeviceMap_.end()) {
-            return it->second;
-        }
-        return {};
-    }
-    void removeOperationDevice(const sp<IBinder>& token) {
-        std::lock_guard<std::mutex> lock(operationDeviceMapMutex_);
-        operationDeviceMap_.erase(token);
-    }
 };
 
 };  // namespace keystore
diff --git a/keystore/keymaster_worker.cpp b/keystore/keymaster_worker.cpp
index 922ef0a..f6d5621 100644
--- a/keystore/keymaster_worker.cpp
+++ b/keystore/keymaster_worker.cpp
@@ -22,6 +22,10 @@
 
 #include <android-base/logging.h>
 
+#include <log/log_event_list.h>
+
+#include <private/android_logger.h>
+
 #include "KeyStore.h"
 #include "keymaster_enforcement.h"
 
@@ -74,6 +78,26 @@
     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) {
@@ -111,12 +135,6 @@
             return;
         }
 
-        error = keyStore_->del(lockedEntry);
-        if (!error.isOk()) {
-            ALOGI("upgradeKeyBlob keystore->del failed %d", error.getErrorCode());
-            return;
-        }
-
         Blob newBlob(&upgradedKeyBlob[0], upgradedKeyBlob.size(), nullptr /* info */,
                      0 /* infoLength */, ::TYPE_KEYMASTER_10);
         newBlob.setSecurityLevel(blob.getSecurityLevel());
@@ -129,6 +147,8 @@
             ALOGI("upgradeKeyBlob keystore->put failed %d", error.getErrorCode());
             return;
         }
+
+        deleteOldKeyOnUpgrade(lockedEntry, std::move(blob));
         blob = std::move(newBlob);
     };
 
@@ -321,6 +341,7 @@
     // We mostly ignore errors from abort() because all we care about is whether at least
     // one operation has been removed.
     auto rc = abort(oldest);
+    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;
@@ -1091,6 +1112,7 @@
         auto operations = operationMap_.getOperationsForToken(who.unsafe_get());
         for (const auto& token : operations) {
             abort(token);
+            keyStore_->removeOperationDevice(token);
         }
     });
 }
diff --git a/keystore/keymaster_worker.h b/keystore/keymaster_worker.h
index e1a1c02..2c72c80 100644
--- a/keystore/keymaster_worker.h
+++ b/keystore/keymaster_worker.h
@@ -175,6 +175,8 @@
             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>
diff --git a/keystore/keystore.rc b/keystore/keystore.rc
index 132039a..a688c5f 100644
--- a/keystore/keystore.rc
+++ b/keystore/keystore.rc
@@ -1,5 +1,5 @@
 service keystore /system/bin/keystore /data/misc/keystore
-    class main
+    class core
     user keystore
     group keystore drmrpc readproc log
     writepid /dev/cpuset/foreground/tasks
diff --git a/keystore/keystore_cli.cpp b/keystore/keystore_cli.cpp
index 2705a19..428a9bc 100644
--- a/keystore/keystore_cli.cpp
+++ b/keystore/keystore_cli.cpp
@@ -47,21 +47,6 @@
     /* [WRONG_PASSWORD + 3] = */ "Wrong password (4 tries left)",
 };
 
-#define NO_ARG_INT_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            int32_t ret = -1; \
-            service->cmd(&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_INT_RETURN(cmd) \
     do { \
         if (strcmp(argv[1], #cmd) == 0) { \
@@ -242,8 +227,6 @@
                 argc < 4 ? -1 : atoi(argv[3]));
     }
 
-    NO_ARG_INT_RETURN(reset);
-
     // TODO: notifyUserPasswordChanged
 
     SINGLE_INT_ARG_INT_RETURN(lock);
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index b46b221..4f69eb0 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -416,16 +416,10 @@
         return result.getErrorCode();
     }
     AuthorizationSet empty_params;
-    size_t num_input_bytes_consumed;
     std::string output_data;
-    result = keystore->updateOperation(handle, empty_params, "data_to_sign",
-                                       &num_input_bytes_consumed, &output_params, &output_data);
-    if (!result.isOk()) {
-        printf("Sign: UpdateOperation failed: %d\n", result.getErrorCode());
-        return result.getErrorCode();
-    }
-    result = keystore->finishOperation(handle, empty_params, std::string() /*signature_to_verify*/,
-                                       &output_params, &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();
@@ -436,18 +430,8 @@
     output_data.clear();
     result =
         keystore->beginOperation(KeyPurpose::VERIFY, name, sign_params, &output_params, &handle);
-    if (!result.isOk()) {
-        printf("Verify: BeginOperation failed: %d\n", result.getErrorCode());
-        return result.getErrorCode();
-    }
-    result = keystore->updateOperation(handle, empty_params, "data_to_sign",
-                                       &num_input_bytes_consumed, &output_params, &output_data);
-    if (!result.isOk()) {
-        printf("Verify: UpdateOperation failed: %d\n", result.getErrorCode());
-        return result.getErrorCode();
-    }
-    result = keystore->finishOperation(handle, empty_params, signature_to_verify, &output_params,
-                                       &output_data);
+    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();
diff --git a/keystore/keystore_client_impl.cpp b/keystore/keystore_client_impl.cpp
index b9a142e..f888683 100644
--- a/keystore/keystore_client_impl.cpp
+++ b/keystore/keystore_client_impl.cpp
@@ -17,6 +17,7 @@
 #include "keystore/keystore_client_impl.h"
 
 #include <future>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -165,16 +166,9 @@
         return false;
     }
     AuthorizationSet empty_params;
-    size_t num_input_bytes_consumed;
     AuthorizationSet ignored_params;
-    result = updateOperation(handle, empty_params, input_data, &num_input_bytes_consumed,
-                             &ignored_params, output_data);
-    if (!result.isOk()) {
-        ALOGE("UpdateOperation failed: %d", result.getErrorCode());
-        return false;
-    }
-    result =
-        finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data);
+    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;
@@ -383,6 +377,7 @@
 
 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) {
@@ -390,12 +385,14 @@
     }
     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>)hidlSignature, hidl_vec<uint8_t>(), &error_code);
+        (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;
@@ -441,9 +438,14 @@
 
 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, kDefaultUID, &matches);
+    auto binder_result = keystore_->list(prefix16, uid, &matches);
     if (!binder_result.isOk()) return false;
 
     for (const auto& match : matches) {
@@ -453,6 +455,14 @@
     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_++;
 }
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
index f3eadd7..91ebd12 100644
--- a/keystore/keystore_main.cpp
+++ b/keystore/keystore_main.cpp
@@ -17,16 +17,13 @@
 #define LOG_TAG "keystore"
 
 #include <android-base/logging.h>
-#include <android/hidl/manager/1.1/IServiceManager.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
 #include <android/security/keystore/IKeystoreService.h>
-#include <android/system/wifi/keystore/1.0/IKeystore.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
-#include <hidl/HidlTransportSupport.h>
 #include <keymasterV4_0/Keymaster3.h>
 #include <keymasterV4_0/Keymaster4.h>
 #include <utils/StrongPointer.h>
-#include <wifikeystorehal/keystore.h>
 
 #include <keystore/keystore_hidl_support.h>
 #include <keystore/keystore_return_types.h>
@@ -43,15 +40,12 @@
  * the maximum space we needed, so boundary checks on buffers are omitted. */
 
 using ::android::sp;
-using ::android::hardware::configureRpcThreadpool;
-using ::android::system::wifi::keystore::V1_0::IKeystore;
-using ::android::system::wifi::keystore::V1_0::implementation::Keystore;
-using ::android::hidl::manager::V1_1::IServiceManager;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
-using ::android::hardware::keymaster::V4_0::SecurityLevel;
-using ::android::hardware::keymaster::V4_0::HmacSharingParameters;
 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;
@@ -62,7 +56,7 @@
 template <typename Wrapper>
 KeymasterDevices enumerateKeymasterDevices(IServiceManager* serviceManager) {
     KeymasterDevices result;
-    serviceManager->listByInterface(
+    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);
@@ -108,7 +102,7 @@
 }
 
 KeymasterDevices initializeKeymasters() {
-    auto serviceManager = android::hidl::manager::V1_1::IServiceManager::getService();
+    auto serviceManager = IServiceManager::getService();
     CHECK(serviceManager.get()) << "Failed to get ServiceManager";
     auto result = enumerateKeymasterDevices<Keymaster4>(serviceManager.get());
     auto softKeymaster = result[SecurityLevel::SOFTWARE];
@@ -160,16 +154,6 @@
     android::status_t ret = sm->addService(android::String16("android.security.keystore"), service);
     CHECK(ret == android::OK) << "Couldn't register binder service!";
 
-    /**
-     * Register the wifi keystore HAL service to run in passthrough mode.
-     * This will spawn off a new thread which will service the HIDL
-     * transactions.
-     */
-    configureRpcThreadpool(1, false /* callerWillJoin */);
-    android::sp<IKeystore> wifiKeystoreHalService = new Keystore();
-    android::status_t err = wifiKeystoreHalService->registerAsService();
-    CHECK(ret == android::OK) << "Cannot register wifi keystore HAL service: " << err;
-
     /*
      * This thread is just going to process Binder transactions.
      */
diff --git a/keystore/keystore_utils.cpp b/keystore/keystore_utils.cpp
index 78056d6..f0f6098 100644
--- a/keystore/keystore_utils.cpp
+++ b/keystore/keystore_utils.cpp
@@ -31,6 +31,9 @@
 #include <keystore/keymaster_types.h>
 #include <keystore/keystore_client.h>
 
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+
 #include "blob.h"
 
 size_t readFully(int fd, uint8_t* data, size_t size) {
@@ -64,6 +67,44 @@
     return size;
 }
 
+std::string getContainingDirectory(const std::string& filename) {
+    std::string containing_dir;
+    size_t last_pos;
+    size_t pos = std::string::npos;
+
+    __builtin_add_overflow(filename.size(), -1, &last_pos);
+
+    // strip all trailing '/'
+    while ((pos = filename.find_last_of('/', last_pos)) == last_pos && pos != 0) {
+        --last_pos;
+    }
+
+    if (pos == 0) {
+        containing_dir = "/";
+    } else if (pos == std::string::npos) {
+        containing_dir = ".";
+    } else {
+        containing_dir = filename.substr(0, pos);
+    }
+
+    return containing_dir;
+}
+
+void fsyncDirectory(const std::string& path) {
+    android::base::unique_fd dir_fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_DIRECTORY | O_RDONLY)));
+
+    if (dir_fd < 0) {
+        LOG(WARNING) << "Could not open dir: " << path << " error: " << strerror(errno);
+        return;
+    }
+
+    if (TEMP_FAILURE_RETRY(fsync(dir_fd)) == -1) {
+        LOG(WARNING) << "Failed to fsync the directory " << path << " error: " << strerror(errno);
+    }
+
+    return;
+}
+
 void add_legacy_key_authorizations(int keyType, keystore::AuthorizationSet* params) {
     using namespace keystore;
     params->push_back(TAG_PURPOSE, KeyPurpose::SIGN);
diff --git a/keystore/keystore_utils.h b/keystore/keystore_utils.h
index 3bc9c01..ce64d42 100644
--- a/keystore/keystore_utils.h
+++ b/keystore/keystore_utils.h
@@ -18,6 +18,7 @@
 #define KEYSTORE_KEYSTORE_UTILS_H_
 
 #include <cstdint>
+#include <string>
 #include <vector>
 
 #include <openssl/evp.h>
@@ -29,6 +30,8 @@
 
 size_t readFully(int fd, uint8_t* data, size_t size);
 size_t writeFully(int fd, uint8_t* data, size_t size);
+std::string getContainingDirectory(const std::string& filename);
+void fsyncDirectory(const std::string& path);
 
 void add_legacy_key_authorizations(int keyType, keystore::AuthorizationSet* params);
 
@@ -44,16 +47,6 @@
  */
 uid_t get_user_id(uid_t uid);
 
-struct EVP_PKEY_Delete {
-    void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); }
-};
-typedef std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
-
-struct PKCS8_PRIV_KEY_INFO_Delete {
-    void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); }
-};
-typedef std::unique_ptr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
-
 class Blob;
 
 // Tags for audit logging. Be careful and don't log sensitive data.
diff --git a/keystore/permissions.cpp b/keystore/permissions.cpp
index 05454cb..3e81585 100644
--- a/keystore/permissions.cpp
+++ b/keystore/permissions.cpp
@@ -55,10 +55,15 @@
 };
 
 user_euid user_euids[] = {{AID_VPN, AID_SYSTEM},
+                          // Wifi services will run in system_server on devices not using wifi
+                          // mainline module.
                           {AID_WIFI, AID_SYSTEM},
+                          // Wifi services will run in network_stack on devices using wifi mainline
+                          // module.
+                          {AID_WIFI, AID_NETWORK_STACK},
                           {AID_ROOT, AID_SYSTEM},
-                          {AID_WIFI, AID_KEYSTORE},
-                          {AID_KEYSTORE, AID_WIFI},
+                          {AID_FSVERITY_CERT, AID_ROOT},
+                          {AID_FSVERITY_CERT, AID_SYSTEM},
 
 #ifdef GRANT_ROOT_ALL_PERMISSIONS
                           // Allow VTS tests to act on behalf of the wifi user
diff --git a/keystore/tests/Android.bp b/keystore/tests/Android.bp
index 25fa10b..cb662d1 100644
--- a/keystore/tests/Android.bp
+++ b/keystore/tests/Android.bp
@@ -19,7 +19,7 @@
     static_libs: [
         "android.hardware.confirmationui@1.0",
         "libbase",
-        "libcrypto",
+        "libcrypto_static",
         "libcutils",
         "libgtest_main",
         "libhidlbase",
diff --git a/keystore/user_state.cpp b/keystore/user_state.cpp
index bc3f6d9..30dfe3c 100644
--- a/keystore/user_state.cpp
+++ b/keystore/user_state.cpp
@@ -37,7 +37,7 @@
 
 UserState::UserState(uid_t userId)
     : mMasterKeyEntry(".masterkey", "user_" + std::to_string(userId), userId, /* masterkey */ true),
-      mUserId(userId), mState(STATE_UNINITIALIZED), mRetry(MAX_RETRY) {}
+      mUserId(userId), mState(STATE_UNINITIALIZED) {}
 
 bool UserState::operator<(const UserState& rhs) const {
     return getUserId() < rhs.getUserId();
@@ -69,9 +69,6 @@
 
 void UserState::setState(State state) {
     mState = state;
-    if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
-        mRetry = MAX_RETRY;
-    }
 }
 
 void UserState::zeroizeMasterKeysInMemory() {
@@ -140,10 +137,13 @@
 }
 
 ResponseCode UserState::writeMasterKey(const android::String8& pw) {
-    std::vector<uint8_t> passwordKey(MASTER_KEY_SIZE_BYTES);
+    std::vector<uint8_t> passwordKey(mMasterKey.size());
     generateKeyFromPassword(passwordKey, pw, mSalt);
-    Blob masterKeyBlob(mMasterKey.data(), mMasterKey.size(), mSalt, sizeof(mSalt),
-                       TYPE_MASTER_KEY_AES256);
+    auto blobType = TYPE_MASTER_KEY_AES256;
+    if (mMasterKey.size() == kAes128KeySizeBytes) {
+        blobType = TYPE_MASTER_KEY;
+    }
+    Blob masterKeyBlob(mMasterKey.data(), mMasterKey.size(), mSalt, sizeof(mSalt), blobType);
     auto lockedEntry = LockedKeyBlobEntry::get(mMasterKeyEntry);
     return lockedEntry.writeBlobs(masterKeyBlob, {}, passwordKey, STATE_NO_ERROR);
 }
@@ -174,7 +174,7 @@
 
     size_t masterKeySize = MASTER_KEY_SIZE_BYTES;
     if (rawBlob.type == TYPE_MASTER_KEY) {
-        masterKeySize = SHA1_DIGEST_SIZE_BYTES;
+        masterKeySize = kAes128KeySizeBytes;
     }
 
     std::vector<uint8_t> passwordKey(masterKeySize);
@@ -205,23 +205,9 @@
         }
         return response;
     }
-    if (mRetry <= 0) {
-        reset();
-        return ResponseCode::UNINITIALIZED;
-    }
-    --mRetry;
-    switch (mRetry) {
-    case 0:
-        return ResponseCode::WRONG_PASSWORD_0;
-    case 1:
-        return ResponseCode::WRONG_PASSWORD_1;
-    case 2:
-        return ResponseCode::WRONG_PASSWORD_2;
-    case 3:
-        return ResponseCode::WRONG_PASSWORD_3;
-    default:
-        return ResponseCode::WRONG_PASSWORD_3;
-    }
+
+    LOG(ERROR) << "Invalid password presented";
+    return ResponseCode::WRONG_PASSWORD_0;
 }
 
 bool UserState::reset() {
@@ -263,7 +249,7 @@
     const EVP_MD* digest = EVP_sha256();
 
     // SHA1 was used prior to increasing the key size
-    if (key.size() == SHA1_DIGEST_SIZE_BYTES) {
+    if (key.size() == kAes128KeySizeBytes) {
         digest = EVP_sha1();
     }
 
diff --git a/keystore/user_state.h b/keystore/user_state.h
index b0671e3..75d99d9 100644
--- a/keystore/user_state.h
+++ b/keystore/user_state.h
@@ -55,8 +55,6 @@
     void setState(State state);
     State getState() const { return mState; }
 
-    int8_t getRetry() const { return mRetry; }
-
     void zeroizeMasterKeysInMemory();
     bool deleteMasterKey();
 
@@ -75,14 +73,13 @@
     bool operator<(uid_t userId) const;
 
   private:
-    static const int SHA1_DIGEST_SIZE_BYTES = 16;
-    static const int SHA256_DIGEST_SIZE_BYTES = 32;
+    static constexpr int SHA1_DIGEST_SIZE_BYTES = 16;
+    static constexpr int SHA256_DIGEST_SIZE_BYTES = 32;
 
-    static const int MASTER_KEY_SIZE_BYTES = SHA256_DIGEST_SIZE_BYTES;
-    static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
+    static constexpr int MASTER_KEY_SIZE_BYTES = kAes256KeySizeBytes;
+    static constexpr int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
 
-    static const int MAX_RETRY = 4;
-    static const size_t SALT_SIZE = 16;
+    static constexpr size_t SALT_SIZE = 16;
 
     void generateKeyFromPassword(std::vector<uint8_t>& key, const android::String8& pw,
                                  uint8_t* salt);
@@ -94,7 +91,6 @@
 
     uid_t mUserId;
     State mState;
-    int8_t mRetry;
 
     std::vector<uint8_t> mMasterKey;
     uint8_t mSalt[SALT_SIZE];