fscrypt: move fscrypt to android_system_vold

Change-Id: I2cb7385541b8d9c7f1d8de0cef8ed3803b457b8c
diff --git a/Android.mk b/Android.mk
index c2f1f59..61cec06 100755
--- a/Android.mk
+++ b/Android.mk
@@ -90,6 +90,7 @@
     system/gsid/include/ \
     system/core/init/ \
     system/extras/ext4_utils/include \
+    system/vold
 
 ifneq ($(TARGET_RECOVERY_REBOOT_SRC),)
   LOCAL_SRC_FILES += $(TARGET_RECOVERY_REBOOT_SRC)
@@ -108,6 +109,7 @@
     system/extras \
     packages/modules/adb \
     system/core/libsparse \
+    system/vold \
     external/zlib \
     system/libziparchive/include \
     external/freetype/include \
@@ -127,7 +129,7 @@
     $(LOCAL_PATH)/minuitwrp/include \
     $(LOCAL_PATH)/twinstall/include
 
-LOCAL_STATIC_LIBRARIES += libguitwrp
+LOCAL_STATIC_LIBRARIES += libguitwrp libvold
 LOCAL_SHARED_LIBRARIES += libz libc libcutils libstdc++ libtar libblkid libminuitwrp libmtdutils libtwadbbu 
 LOCAL_SHARED_LIBRARIES += libbootloader_message libcrecovery libtwrpdigest libc++ libaosprecovery libcrypto libbase 
 LOCAL_SHARED_LIBRARIES += libziparchive libselinux libdl_android.bootstrap
@@ -296,12 +298,6 @@
 ifeq ($(TW_NO_HAPTICS), true)
     LOCAL_CFLAGS += -DTW_NO_HAPTICS
 endif
-ifeq ($(TW_INCLUDE_JB_CRYPTO), true)
-    TW_INCLUDE_CRYPTO := true
-endif
-ifeq ($(TW_INCLUDE_L_CRYPTO), true)
-    TW_INCLUDE_CRYPTO := true
-endif
 ifneq ($(TW_ADDITIONAL_APEX_FILES),)
     LOCAL_CFLAGS += -DTW_ADDITIONAL_APEX_FILES=$(TW_ADDITIONAL_APEX_FILES)
 endif
@@ -313,14 +309,27 @@
 endif
 ifeq ($(TW_INCLUDE_CRYPTO), true)
     LOCAL_CFLAGS += -DTW_INCLUDE_CRYPTO -DUSE_FSCRYPT -Wno-macro-redefined
-    LOCAL_SHARED_LIBRARIES += libcryptfsfde
-    LOCAL_SHARED_LIBRARIES += libgpt_twrp libstatssocket.recovery
+    LOCAL_SHARED_LIBRARIES += libgpt_twrp
     LOCAL_C_INCLUDES += external/boringssl/src/include bootable/recovery/crypto
-    LOCAL_C_INCLUDES += $(commands_TWRP_local_path)/crypto/fscrypt
     TW_INCLUDE_CRYPTO_FBE := true
     LOCAL_CFLAGS += -DTW_INCLUDE_FBE
-    LOCAL_SHARED_LIBRARIES += libtwrpfscrypt android.frameworks.stats@1.0 android.hardware.authsecret@1.0 \
-        android.hardware.oemlock@1.0
+    LOCAL_SHARED_LIBRARIES += android.frameworks.stats@1.0 android.hardware.authsecret@1.0 \
+	android.security.authorization-ndk_platform \
+        android.hardware.oemlock@1.0 libf2fs_sparseblock libbinder libbinder_ndk \
+        libandroidicu.recovery \
+        android.hardware.gatekeeper@1.0 \
+        android.hardware.weaver@1.0 \
+        android.frameworks.stats@1.0 \
+        android.security.maintenance-ndk_platform \
+        android.system.keystore2-V1-ndk_platform \
+        libkeyutils \
+        liblog \
+        libsqlite.recovery \
+        libkeystoreinfo.recovery \
+        libgatekeeper_aidl
+
+    LOCAL_STATIC_LIBRARIES += libkeymint_support
+
     LOCAL_CFLAGS += -DTW_INCLUDE_FBE_METADATA_DECRYPT
     ifneq ($(TW_CRYPTO_USE_SYSTEM_VOLD),)
     ifneq ($(TW_CRYPTO_USE_SYSTEM_VOLD),false)
@@ -507,7 +516,13 @@
 TWRP_REQUIRED_MODULES += \
     vold_prepare_subdirs \
     task_recovery_profiles.json \
-    fscryptpolicyget
+    fscryptpolicyget.recovery \
+    keystore_auth \
+    keystore2 \
+    android.system.keystore2-service.xml \
+    keystore2.rc \
+    plat_keystore2_key_contexts
+
     ifneq ($(TW_INCLUDE_CRYPTO_FBE),)
     TWRP_REQUIRED_MODULES += \
         plat_service_contexts \
@@ -707,11 +722,8 @@
 endif
 
 ifeq ($(TW_INCLUDE_CRYPTO), true)
-    include $(commands_TWRP_local_path)/crypto/fde/Android.mk
+    # include $(commands_TWRP_local_path)/crypto/fde/Android.mk
     include $(commands_TWRP_local_path)/crypto/scrypt/Android.mk
-    ifeq ($(TW_INCLUDE_CRYPTO_FBE), true)
-        include $(commands_TWRP_local_path)/crypto/fscrypt/Android.mk
-    endif
     ifneq ($(TW_CRYPTO_USE_SYSTEM_VOLD),)
     ifneq ($(TW_CRYPTO_USE_SYSTEM_VOLD),false)
         include $(commands_TWRP_local_path)/crypto/vold_decrypt/Android.mk
diff --git a/crypto/fde/Android.mk b/crypto/fde/Android.mk
deleted file mode 100755
index faf7da8..0000000
--- a/crypto/fde/Android.mk
+++ /dev/null
@@ -1,126 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-ifeq ($(TW_INCLUDE_CRYPTO), true)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libcryptfsfde
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := cryptfs.cpp
-LOCAL_SHARED_LIBRARIES := libcrypto libhardware libcutils libstdc++
-LOCAL_STATIC_LIBRARIES := libscrypttwrp_static
-LOCAL_C_INCLUDES := external/openssl/include $(commands_recovery_local_path)/crypto/scrypt/lib/crypto
-ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 23; echo $$?),0)
-    LOCAL_C_INCLUDES += bionic external/stlport/stlport
-    LOCAL_SHARED_LIBRARIES += libstlport
-    LOCAL_CPPFLAGS := -std=c++11
-endif
-
-LOCAL_C_INCLUDES += $(commands_TWRP_local_path)/crypto/fscrypt
-
-ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26; echo $$?),0)
-    #8.0 or higher
-    LOCAL_C_INCLUDES +=  external/boringssl/src/include
-    ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 29; echo $$?),0)
-        LOCAL_SHARED_LIBRARIES += libtwrpfscrypt
-    else
-        LOCAL_SHARED_LIBRARIES += libe4crypt
-    endif
-    LOCAL_SHARED_LIBRARIES += libselinux libc libc++ libbase libcrypto libcutils libkeymaster_messages libhardware libprotobuf-cpp-lite \
-        android.hardware.keymaster@3.0 libkeystore_binder libhidlbase libutils libbinder
-    ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 28; echo $$?),0)
-        #9.0 rules
-        LOCAL_CFLAGS += -Wno-unused-variable -Wno-sign-compare -Wno-unused-parameter -Wno-comment
-        LOCAL_SHARED_LIBRARIES += android.hardware.keymaster@4.0 libkeymaster4support libkeyutils
-        LOCAL_CFLAGS += -DTW_KEYMASTER_MAX_API=4
-    else
-        #8.x rules
-        ifneq ($(wildcard system/core/libkeyutils/Android.bp),)
-            #only present in some 8.0 trees and should be in all 8.1 trees
-            LOCAL_SHARED_LIBRARIES += libkeyutils
-        endif
-        LOCAL_SHARED_LIBRARIES += libsoftkeymaster
-        LOCAL_CFLAGS += -DTW_KEYMASTER_MAX_API=3
-    endif
-else
-    # <= 7.x rules
-    ifneq ($(wildcard hardware/libhardware/include/hardware/keymaster0.h),)
-        LOCAL_C_INCLUDES +=  external/boringssl/src/include
-        LOCAL_CFLAGS += -DTW_KEYMASTER_MAX_API=1
-    else
-        LOCAL_CFLAGS += -DTW_KEYMASTER_MAX_API=0
-    endif
-endif
-ifeq ($(TARGET_HW_DISK_ENCRYPTION),true)
-    ifeq ($(TARGET_CRYPTFS_HW_PATH),)
-        LOCAL_C_INCLUDES += device/qcom/common/cryptfs_hw
-    else
-        LOCAL_C_INCLUDES += $(TARGET_CRYPTFS_HW_PATH)
-    endif
-    LOCAL_SHARED_LIBRARIES += libcryptfs_hw
-    LOCAL_CFLAGS += -DCONFIG_HW_DISK_ENCRYPTION
-endif
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := twrpdec
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/
-LOCAL_SRC_FILES := main.cpp cryptfs.cpp
-LOCAL_SHARED_LIBRARIES := libcrypto libhardware libcutils libc libstdc++
-LOCAL_C_INCLUDES := external/openssl/include $(commands_recovery_local_path)/crypto/scrypt/lib/crypto
-ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 23; echo $$?),0)
-    LOCAL_C_INCLUDES += bionic external/stlport/stlport
-    LOCAL_SHARED_LIBRARIES += libstlport
-    LOCAL_CPPFLAGS := -std=c++11
-endif
-
-ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26; echo $$?),0)
-    #8.0 or higher
-    LOCAL_C_INCLUDES +=  external/boringssl/src/include
-    ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 29; echo $$?),0)
-        LOCAL_SHARED_LIBRARIES += libtwrpfscrypt
-    else
-        LOCAL_SHARED_LIBRARIES += libe4crypt
-    endif
-    LOCAL_SHARED_LIBRARIES += libselinux libc libc++ libbase libcrypto libcutils libkeymaster_messages libhardware libprotobuf-cpp-lite \
-    android.hardware.keymaster@3.0 libkeystore_binder libhidlbase libutils libbinder
-    ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 28; echo $$?),0)
-        #9.0 rules
-        LOCAL_CFLAGS += -Wno-unused-variable -Wno-sign-compare -Wno-unused-parameter -Wno-comment
-        LOCAL_SHARED_LIBRARIES += android.hardware.keymaster@4.0 libkeymaster4support libkeyutils
-        LOCAL_CFLAGS += -DTW_KEYMASTER_MAX_API=4
-    else
-        #8.x rules
-        ifneq ($(wildcard system/core/libkeyutils/Android.bp),)
-            #only present in some 8.0 trees and should be in all 8.1 trees
-            LOCAL_SHARED_LIBRARIES += libkeyutils
-        endif
-        LOCAL_SHARED_LIBRARIES += libsoftkeymaster
-        LOCAL_CFLAGS += -DTW_KEYMASTER_MAX_API=3
-    endif
-else
-    # <= 7.x rules
-    ifneq ($(wildcard hardware/libhardware/include/hardware/keymaster0.h),)
-        LOCAL_C_INCLUDES +=  external/boringssl/src/include
-        LOCAL_CFLAGS += -DTW_KEYMASTER_MAX_API=1
-    else
-        LOCAL_CFLAGS += -DTW_KEYMASTER_MAX_API=0
-    endif
-endif
-ifeq ($(TARGET_HW_DISK_ENCRYPTION),true)
-    ifeq ($(TARGET_CRYPTFS_HW_PATH),)
-        LOCAL_C_INCLUDES += device/qcom/common/cryptfs_hw
-    else
-        LOCAL_C_INCLUDES += $(TARGET_CRYPTFS_HW_PATH)
-    endif
-    LOCAL_SHARED_LIBRARIES += libcryptfs_hw
-    LOCAL_CFLAGS += -DCONFIG_HW_DISK_ENCRYPTION
-endif
-
-LOCAL_WHOLE_STATIC_LIBRARIES += libscrypttwrp_static
-include $(BUILD_EXECUTABLE)
-
-endif
diff --git a/crypto/fde/cryptfs.cpp b/crypto/fde/cryptfs.cpp
deleted file mode 100644
index fa0dc78..0000000
--- a/crypto/fde/cryptfs.cpp
+++ /dev/null
@@ -1,1848 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-/* TO DO:
- *   1.  Perhaps keep several copies of the encrypted key, in case something
- *       goes horribly wrong?
- *
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <linux/dm-ioctl.h>
-#include <libgen.h>
-#include <stdlib.h>
-#include <sys/param.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-#include <errno.h>
-//#include <ext4_utils/ext4_crypt.h>
-//#include <ext4_utils/ext4_utils.h>
-#include <linux/kdev_t.h>
-//#include <fs_mgr.h>
-#include <time.h>
-#include <math.h>
-//#include <selinux/selinux.h>
-#include "cryptfs.h"
-//#include "secontext.h"
-#define LOG_TAG "Cryptfs"
-//#include "cutils/log.h"
-#include "cutils/properties.h"
-//#include "cutils/android_reboot.h"
-//#include "hardware_legacy/power.h"
-//#include <logwrap/logwrap.h>
-//#include "ScryptParameters.h"
-//#include "VolumeManager.h"
-//#include "VoldUtil.h"
-//#include "Ext4Crypt.h"
-//#include "f2fs_sparseblock.h"
-//#include "EncryptInplace.h"
-//#include "Process.h"
-#include "Keymaster.h"
-#if TW_KEYMASTER_MAX_API == 0
-#include <hardware/keymaster.h>
-#else // so far, all trees that have keymaster >= 1 have keymaster 1 support
-#include <stdbool.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-#include <hardware/keymaster0.h>
-#include <hardware/keymaster1.h>
-#include <hardware/keymaster2.h>
-#endif
-//#include "android-base/properties.h"
-//#include <bootloader_message/bootloader_message.h>
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-#include <cryptfs_hw.h>
-#endif
-extern "C" {
-#include <crypto_scrypt.h>
-}
-#include <string>
-#include <vector>
-
-#define ALOGE(...) fprintf(stdout, "E:" __VA_ARGS__)
-#define SLOGE(...) fprintf(stdout, "E:" __VA_ARGS__)
-#define SLOGW(...) fprintf(stdout, "W:" __VA_ARGS__)
-#define SLOGI(...) fprintf(stdout, "I:" __VA_ARGS__)
-#define SLOGD(...) fprintf(stdout, "D:" __VA_ARGS__)
-
-#define UNUSED __attribute__((unused))
-
-#define DM_CRYPT_BUF_SIZE 4096
-
-#define HASH_COUNT 2000
-
-#ifndef min /* already defined by windows.h */
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
-constexpr size_t INTERMEDIATE_KEY_LEN_BYTES = 16;
-constexpr size_t INTERMEDIATE_IV_LEN_BYTES = 16;
-constexpr size_t INTERMEDIATE_BUF_SIZE =
-    (INTERMEDIATE_KEY_LEN_BYTES + INTERMEDIATE_IV_LEN_BYTES);
-
-// SCRYPT_LEN is used by struct crypt_mnt_ftr for its intermediate key.
-static_assert(INTERMEDIATE_BUF_SIZE == SCRYPT_LEN,
-              "Mismatch of intermediate key sizes");
-
-#define KEY_IN_FOOTER  "footer"
-
-#define DEFAULT_HEX_PASSWORD "64656661756c745f70617373776f7264"
-#define DEFAULT_PASSWORD "default_password"
-
-#define CRYPTO_BLOCK_DEVICE "userdata"
-
-#define TABLE_LOAD_RETRIES 10
-
-#define RSA_KEY_SIZE 2048
-#define RSA_KEY_SIZE_BYTES (RSA_KEY_SIZE / 8)
-#define RSA_EXPONENT 0x10001
-#define KEYMASTER_CRYPTFS_RATE_LIMIT 1  // Maximum one try per second
-#define KEY_LEN_BYTES 16
-
-#define RETRY_MOUNT_ATTEMPTS 10
-#define RETRY_MOUNT_DELAY_SECONDS 1
-
-#define CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE (1)
-
-static unsigned char saved_master_key[MAX_KEY_LEN];
-static char *saved_mount_point;
-static int  master_key_saved = 0;
-static struct crypt_persist_data *persist_data = NULL;
-
-static int previous_type;
-
-static char key_fname[PROPERTY_VALUE_MAX] = "";
-static char real_blkdev[PROPERTY_VALUE_MAX] = "";
-static char file_system[PROPERTY_VALUE_MAX] = "";
-
-static void get_blkdev_size(int fd, unsigned long *nr_sec)
-{
-  if ( (ioctl(fd, BLKGETSIZE, nr_sec)) == -1) {
-    *nr_sec = 0;
-  }
-}
-
-#if TW_KEYMASTER_MAX_API == 0
-static int keymaster_init(keymaster_device_t **keymaster_dev)
-{
-    int rc;
-
-    const hw_module_t* mod;
-    rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
-    if (rc) {
-        printf("could not find any keystore module\n");
-        goto out;
-    }
-
-    rc = keymaster_open(mod, keymaster_dev);
-    if (rc) {
-        printf("could not open keymaster device in %s (%s)\n",
-            KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
-        goto out;
-    }
-
-    return 0;
-
-out:
-    *keymaster_dev = NULL;
-    return rc;
-}
-#else //TW_KEYMASTER_MAX_API == 0
-static int keymaster_init(keymaster0_device_t **keymaster0_dev,
-                          keymaster1_device_t **keymaster1_dev,
-			  keymaster2_device_t **keymaster2_dev)
-{
-    int rc;
-
-    const hw_module_t* mod;
-    rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
-    if (rc) {
-        printf("could not find any keystore module\n");
-        goto err;
-    }
-
-    printf("keymaster module name is %s\n", mod->name);
-    printf("keymaster version is %d\n", mod->module_api_version);
-
-    *keymaster0_dev = NULL;
-    *keymaster1_dev = NULL;
-    *keymaster2_dev = NULL;
-    if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_2_0) {
-        printf("Found keymaster2 module, using keymaster2 API.\n");
-        rc = keymaster2_open(mod, keymaster2_dev);
-    } else if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
-        printf("Found keymaster1 module, using keymaster1 API.\n");
-        rc = keymaster1_open(mod, keymaster1_dev);
-    } else {
-        printf("Found keymaster0 module, using keymaster0 API.\n");
-        rc = keymaster0_open(mod, keymaster0_dev);
-    }
-
-    if (rc) {
-        printf("could not open keymaster device in %s (%s)\n",
-              KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
-        goto err;
-    }
-
-    return 0;
-
-err:
-    *keymaster0_dev = NULL;
-    *keymaster1_dev = NULL;
-    *keymaster2_dev = NULL;
-    return rc;
-}
-#endif //TW_KEYMASTER_MAX_API == 0
-
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-static int scrypt_keymaster(const char *passwd, const unsigned char *salt,
-                            unsigned char *ikey, void *params);
-static void convert_key_to_hex_ascii(const unsigned char *master_key,
-                                     unsigned int keysize, char *master_key_ascii);
-static int test_mount_hw_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
-                const char *passwd, const char *mount_point, const char *label);
-int cryptfs_check_passwd_hw(char *passwd);
-int cryptfs_get_master_key(struct crypt_mnt_ftr* ftr, const char* password,
-                                   unsigned char* master_key);
-
-static void convert_key_to_hex_ascii_for_upgrade(const unsigned char *master_key,
-                                     unsigned int keysize, char *master_key_ascii)
-{
-    unsigned int i, a;
-    unsigned char nibble;
-
-    for (i = 0, a = 0; i < keysize; i++, a += 2) {
-        /* For each byte, write out two ascii hex digits */
-        nibble = (master_key[i] >> 4) & 0xf;
-        master_key_ascii[a] = nibble + (nibble > 9 ? 0x57 : 0x30);
-
-        nibble = master_key[i] & 0xf;
-        master_key_ascii[a + 1] = nibble + (nibble > 9 ? 0x57 : 0x30);
-    }
-
-    /* Add the null termination */
-    master_key_ascii[a] = '\0';
-}
-
-static int get_keymaster_hw_fde_passwd(const char* passwd, unsigned char* newpw,
-                                  unsigned char* salt,
-                                  const struct crypt_mnt_ftr *ftr)
-{
-    /* if newpw updated, return 0
-     * if newpw not updated return -1
-     */
-    int rc = -1;
-
-    if (should_use_keymaster()) {
-        if (scrypt_keymaster(passwd, salt, newpw, (void*)ftr)) {
-            SLOGE("scrypt failed");
-        } else {
-            rc = 0;
-        }
-    }
-
-    return rc;
-}
-
-static int verify_hw_fde_passwd(const char *passwd, struct crypt_mnt_ftr* crypt_ftr)
-{
-    unsigned char newpw[32] = {0};
-    int key_index;
-    SLOGI("starting verify_hw_fde_passwd\n");
-    if (get_keymaster_hw_fde_passwd(passwd, newpw, crypt_ftr->salt, crypt_ftr))
-        key_index = set_hw_device_encryption_key(passwd,
-                                           (char*) crypt_ftr->crypto_type_name);
-    else
-        key_index = set_hw_device_encryption_key((const char*)newpw,
-                                           (char*) crypt_ftr->crypto_type_name);
-    return key_index;
-}
-
-static int verify_and_update_hw_fde_passwd(const char *passwd,
-                                           struct crypt_mnt_ftr* crypt_ftr)
-{
-    char* new_passwd = NULL;
-    unsigned char newpw[32] = {0};
-    int key_index = -1;
-    int passwd_updated = -1;
-    int ascii_passwd_updated = (crypt_ftr->flags & CRYPT_ASCII_PASSWORD_UPDATED);
-
-    key_index = verify_hw_fde_passwd(passwd, crypt_ftr);
-    if (key_index < 0) {
-        ++crypt_ftr->failed_decrypt_count;
-
-        if (ascii_passwd_updated) {
-            SLOGI("Ascii password was updated");
-        } else {
-            /* Code in else part would execute only once:
-             * When device is upgraded from L->M release.
-             * Once upgraded, code flow should never come here.
-             * L release passed actual password in hex, so try with hex
-             * Each nible of passwd was encoded as a byte, so allocate memory
-             * twice of password len plus one more byte for null termination
-             */
-            if (crypt_ftr->crypt_type == CRYPT_TYPE_DEFAULT) {
-                new_passwd = (char*)malloc(strlen(DEFAULT_HEX_PASSWORD) + 1);
-                if (new_passwd == NULL) {
-                    SLOGE("System out of memory. Password verification  incomplete");
-                    goto out;
-                }
-                strlcpy(new_passwd, DEFAULT_HEX_PASSWORD, strlen(DEFAULT_HEX_PASSWORD) + 1);
-            } else {
-                new_passwd = (char*)malloc(strlen(passwd) * 2 + 1);
-                if (new_passwd == NULL) {
-                    SLOGE("System out of memory. Password verification  incomplete");
-                    goto out;
-                }
-                convert_key_to_hex_ascii_for_upgrade((const unsigned char*)passwd,
-                                       strlen(passwd), new_passwd);
-            }
-            key_index = set_hw_device_encryption_key((const char*)new_passwd,
-                                       (char*) crypt_ftr->crypto_type_name);
-            if (key_index >=0) {
-                crypt_ftr->failed_decrypt_count = 0;
-                SLOGI("Hex password verified...will try to update with Ascii value");
-                /* Before updating password, tie that with keymaster to tie with ROT */
-
-                if (get_keymaster_hw_fde_passwd(passwd, newpw,
-                                                crypt_ftr->salt, crypt_ftr)) {
-                    passwd_updated = update_hw_device_encryption_key(new_passwd,
-                                     passwd, (char*)crypt_ftr->crypto_type_name);
-                } else {
-                    passwd_updated = update_hw_device_encryption_key(new_passwd,
-                                     (const char*)newpw, (char*)crypt_ftr->crypto_type_name);
-                }
-
-                if (passwd_updated >= 0) {
-                    crypt_ftr->flags |= CRYPT_ASCII_PASSWORD_UPDATED;
-                    SLOGI("Ascii password recorded and updated");
-                } else {
-                    SLOGI("Passwd verified, could not update...Will try next time");
-                }
-            } else {
-                ++crypt_ftr->failed_decrypt_count;
-            }
-            free(new_passwd);
-        }
-    } else {
-        if (!ascii_passwd_updated)
-            crypt_ftr->flags |= CRYPT_ASCII_PASSWORD_UPDATED;
-    }
-out:
-    // update footer before leaving
-    //put_crypt_ftr_and_key(crypt_ftr);
-    return key_index;
-}
-#endif
-
-void set_partition_data(const char* block_device, const char* key_location, const char* fs)
-{
-  strcpy(key_fname, key_location);
-  strcpy(real_blkdev, block_device);
-  strcpy(file_system, fs);
-}
-
-/* This signs the given object using the keymaster key. */
-static int keymaster_sign_object(struct crypt_mnt_ftr *ftr,
-                                 const unsigned char *object,
-                                 const size_t object_size,
-                                 unsigned char **signature,
-                                 size_t *signature_size)
-{
-    SLOGI("TWRP keymaster max API: %i\n", TW_KEYMASTER_MAX_API);
-    unsigned char to_sign[RSA_KEY_SIZE_BYTES];
-    size_t to_sign_size = sizeof(to_sign);
-    memset(to_sign, 0, RSA_KEY_SIZE_BYTES);
-
-    // To sign a message with RSA, the message must satisfy two
-    // constraints:
-    //
-    // 1. The message, when interpreted as a big-endian numeric value, must
-    //    be strictly less than the public modulus of the RSA key.  Note
-    //    that because the most significant bit of the public modulus is
-    //    guaranteed to be 1 (else it's an (n-1)-bit key, not an n-bit
-    //    key), an n-bit message with most significant bit 0 always
-    //    satisfies this requirement.
-    //
-    // 2. The message must have the same length in bits as the public
-    //    modulus of the RSA key.  This requirement isn't mathematically
-    //    necessary, but is necessary to ensure consistency in
-    //    implementations.
-    switch (ftr->kdf_type) {
-        case KDF_SCRYPT_KEYMASTER_UNPADDED:
-            // This is broken: It produces a message which is shorter than
-            // the public modulus, failing criterion 2.
-            memcpy(to_sign, object, object_size);
-            to_sign_size = object_size;
-            SLOGI("Signing unpadded object\n");
-            break;
-        case KDF_SCRYPT_KEYMASTER_BADLY_PADDED:
-            // This is broken: Since the value of object is uniformly
-            // distributed, it produces a message that is larger than the
-            // public modulus with probability 0.25.
-            memcpy(to_sign, object, min(RSA_KEY_SIZE_BYTES, object_size));
-            SLOGI("Signing end-padded object\n");
-            break;
-        case KDF_SCRYPT_KEYMASTER:
-            // This ensures the most significant byte of the signed message
-            // is zero.  We could have zero-padded to the left instead, but
-            // this approach is slightly more robust against changes in
-            // object size.  However, it's still broken (but not unusably
-            // so) because we really should be using a proper deterministic
-            // RSA padding function, such as PKCS1.
-            memcpy(to_sign + 1, object, min((size_t)RSA_KEY_SIZE_BYTES - 1, object_size));
-            SLOGI("Signing safely-padded object");
-            break;
-        default:
-            SLOGE("Unknown KDF type %d", ftr->kdf_type);
-            return -1;
-    }
-
-    int rc = -1;
-
-#if TW_KEYMASTER_MAX_API >= 1
-    keymaster0_device_t *keymaster0_dev = 0;
-    keymaster1_device_t *keymaster1_dev = 0;
-    keymaster2_device_t *keymaster2_dev = 0;
-    if (keymaster_init(&keymaster0_dev, &keymaster1_dev, &keymaster2_dev)) {
-#else
-    keymaster_device_t *keymaster0_dev = 0;
-    if (keymaster_init(&keymaster0_dev)) {
-#endif
-        printf("Failed to init keymaster 0/1\n");
-        goto initfail;
-    }
-    if (keymaster0_dev) {
-        keymaster_rsa_sign_params_t params;
-        params.digest_type = DIGEST_NONE;
-        params.padding_type = PADDING_NONE;
-
-        rc = keymaster0_dev->sign_data(keymaster0_dev,
-                                      &params,
-                                      ftr->keymaster_blob,
-                                      ftr->keymaster_blob_size,
-                                      to_sign,
-                                      to_sign_size,
-                                      signature,
-                                      signature_size);
-        goto out;
-    }
-#if TW_KEYMASTER_MAX_API >= 1
-    else if (keymaster1_dev) {
-        keymaster_key_blob_t key = { ftr->keymaster_blob, ftr->keymaster_blob_size };
-        keymaster_key_param_t params[] = {
-            keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
-            keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
-        };
-        keymaster_key_param_set_t param_set = { params, sizeof(params)/sizeof(*params) };
-        keymaster_operation_handle_t op_handle;
-        keymaster_error_t error = keymaster1_dev->begin(keymaster1_dev, KM_PURPOSE_SIGN, &key,
-                                                        &param_set, NULL /* out_params */,
-                                                        &op_handle);
-        if (error == KM_ERROR_KEY_RATE_LIMIT_EXCEEDED) {
-            // Key usage has been rate-limited.  Wait a bit and try again.
-            sleep(KEYMASTER_CRYPTFS_RATE_LIMIT);
-            error = keymaster1_dev->begin(keymaster1_dev, KM_PURPOSE_SIGN, &key,
-                                          &param_set, NULL /* out_params */,
-                                          &op_handle);
-        }
-        if (error != KM_ERROR_OK) {
-            printf("Error starting keymaster signature transaction: %d\n", error);
-            rc = -1;
-            goto out;
-        }
-
-        keymaster_blob_t input = { to_sign, to_sign_size };
-        size_t input_consumed;
-        error = keymaster1_dev->update(keymaster1_dev, op_handle, NULL /* in_params */,
-                                       &input, &input_consumed, NULL /* out_params */,
-                                       NULL /* output */);
-        if (error != KM_ERROR_OK) {
-            printf("Error sending data to keymaster signature transaction: %d\n", error);
-            rc = -1;
-            goto out;
-        }
-        if (input_consumed != to_sign_size) {
-            // This should never happen.  If it does, it's a bug in the keymaster implementation.
-            printf("Keymaster update() did not consume all data.\n");
-            keymaster1_dev->abort(keymaster1_dev, op_handle);
-            rc = -1;
-            goto out;
-        }
-
-        keymaster_blob_t tmp_sig;
-        error = keymaster1_dev->finish(keymaster1_dev, op_handle, NULL /* in_params */,
-                                       NULL /* verify signature */, NULL /* out_params */,
-                                       &tmp_sig);
-        if (error != KM_ERROR_OK) {
-            printf("Error finishing keymaster signature transaction: %d\n", error);
-            rc = -1;
-            goto out;
-        }
-
-        *signature = (uint8_t*)tmp_sig.data;
-        *signature_size = tmp_sig.data_length;
-        rc = 0;
-    }
-    else if (keymaster2_dev) {
-        keymaster_key_blob_t key = { ftr->keymaster_blob, ftr->keymaster_blob_size };
-        keymaster_key_param_t params[] = {
-            keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
-            keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
-        };
-        keymaster_key_param_set_t param_set = { params, sizeof(params)/sizeof(*params) };
-        keymaster_operation_handle_t op_handle;
-        keymaster_key_param_t config_params[] = {
-            // Set these to crazy values so we don't need to synchronize
-            // the recovery with system updates.
-            // key upgrades will be required; it will be upgraded in-memory
-            keymaster_param_int(KM_TAG_OS_VERSION, 999999),
-	    keymaster_param_int(KM_TAG_OS_PATCHLEVEL, 209912),
-        };
-        keymaster_key_param_set_t config_param_set = { config_params, sizeof(config_params)/sizeof(*config_params) };
-        keymaster2_dev->configure(keymaster2_dev, &config_param_set);
-        keymaster_error_t error = keymaster2_dev->begin(keymaster2_dev, KM_PURPOSE_SIGN, &key,
-                                                        &param_set, NULL /* out_params */,
-                                                        &op_handle);
-        if (error == KM_ERROR_KEY_RATE_LIMIT_EXCEEDED) {
-            // Key usage has been rate-limited.  Wait a bit and try again.
-            sleep(KEYMASTER_CRYPTFS_RATE_LIMIT);
-            error = keymaster2_dev->begin(keymaster2_dev, KM_PURPOSE_SIGN, &key,
-                                          &param_set, NULL /* out_params */,
-                                          &op_handle);
-        }
-
-        if (error == KM_ERROR_KEY_REQUIRES_UPGRADE) {
-            // Upgrade key in-memory if required
-            // Do not actually write it back; just keep it in memory
-            const keymaster_key_blob_t key_to_upd = key;
-            keymaster2_dev->upgrade_key(keymaster2_dev, &key_to_upd, &config_param_set, &key);
-            error = keymaster2_dev->begin(keymaster2_dev, KM_PURPOSE_SIGN, &key,
-                                          &param_set, NULL /* out_params */,
-                                          &op_handle);
-        }
-
-        if (error != KM_ERROR_OK) {
-            printf("Error starting keymaster signature transaction: %d\n", error);
-            rc = -1;
-            goto out;
-        }
-
-        keymaster_blob_t input = { to_sign, to_sign_size };
-        size_t input_consumed;
-        error = keymaster2_dev->update(keymaster2_dev, op_handle, NULL /* in_params */,
-                                       &input, &input_consumed, NULL /* out_params */,
-                                       NULL /* output */);
-        if (error != KM_ERROR_OK) {
-            printf("Error sending data to keymaster signature transaction: %d\n", error);
-            rc = -1;
-            goto out;
-        }
-        if (input_consumed != to_sign_size) {
-            // This should never happen.  If it does, it's a bug in the keymaster implementation.
-            printf("Keymaster update() did not consume all data.\n");
-            keymaster2_dev->abort(keymaster2_dev, op_handle);
-            rc = -1;
-            goto out;
-        }
-
-        keymaster_blob_t tmp_sig;
-        error = keymaster2_dev->finish(keymaster2_dev, op_handle, NULL /* in_params */,
-                                       NULL, NULL /* verify signature */, NULL /* out_params */,
-                                       &tmp_sig);
-        if (error != KM_ERROR_OK) {
-            printf("Error finishing keymaster signature transaction: %d\n", error);
-            rc = -1;
-            goto out;
-        }
-
-        *signature = (uint8_t*)tmp_sig.data;
-        *signature_size = tmp_sig.data_length;
-        rc = 0;
-    }
-#endif // TW_KEYMASTER_API >= 1
-
-    out:
-#if TW_KEYMASTER_MAX_API >= 1
-        if (keymaster1_dev)
-            keymaster1_close(keymaster1_dev);
-#endif
-        if (keymaster0_dev)
-#if TW_KEYMASTER_MAX_API >= 1
-            keymaster0_close(keymaster0_dev);
-#else
-            keymaster_close(keymaster0_dev);
-#endif
-
-        if (rc == 0)
-            return 0; // otherwise we'll try for a newer keymaster API
-
-initfail:
-#if TW_KEYMASTER_MAX_API == 3
-    return keymaster_sign_object_for_cryptfs_scrypt(ftr->keymaster_blob, ftr->keymaster_blob_size,
-            KEYMASTER_CRYPTFS_RATE_LIMIT, to_sign, to_sign_size, signature, signature_size,
-            ftr->keymaster_blob, KEYMASTER_BLOB_SIZE, &ftr->keymaster_blob_size);
-#endif //TW_KEYMASTER_MAX_API == 3
-#if TW_KEYMASTER_MAX_API >= 4
-    for (int c = 1;c <= 20;c++) { // 20 tries are enough for signing keymaster
-        if (c > 2)
-            usleep(5000); // if failed in two tries lets rest
-        auto result = keymaster_sign_object_for_cryptfs_scrypt(
-            ftr->keymaster_blob, ftr->keymaster_blob_size, KEYMASTER_CRYPTFS_RATE_LIMIT, to_sign,
-            to_sign_size, signature, signature_size);
-        switch (result) {
-            case KeymasterSignResult::ok:
-                return 0;
-            case KeymasterSignResult::upgrade:
-                break;
-            default:
-                return -1;
-        }
-        SLOGD("Upgrading key\n");
-        if (keymaster_upgrade_key_for_cryptfs_scrypt(
-                RSA_KEY_SIZE, RSA_EXPONENT, KEYMASTER_CRYPTFS_RATE_LIMIT, ftr->keymaster_blob,
-                ftr->keymaster_blob_size, ftr->keymaster_blob, KEYMASTER_BLOB_SIZE,
-                &ftr->keymaster_blob_size) != 0) {
-            SLOGE("Failed to upgrade key\n");
-            return -1;
-        }
-        /*if (put_crypt_ftr_and_key(ftr) != 0) {
-            SLOGE("Failed to write upgraded key to disk");
-        }*/
-        SLOGD("Key upgraded successfully\n");
-    }
-#endif
-    return -1;
-}
-
-static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags)
-{
-    memset(io, 0, dataSize);
-    io->data_size = dataSize;
-    io->data_start = sizeof(struct dm_ioctl);
-    io->version[0] = 4;
-    io->version[1] = 0;
-    io->version[2] = 0;
-    io->flags = flags;
-    if (name) {
-        strlcpy(io->name, name, sizeof(io->name));
-    }
-}
-
-namespace {
-
-struct CryptoType;
-
-// Use to get the CryptoType in use on this device.
-const CryptoType &get_crypto_type();
-
-struct CryptoType {
-    // We should only be constructing CryptoTypes as part of
-    // supported_crypto_types[].  We do it via this pseudo-builder pattern,
-    // which isn't pure or fully protected as a concession to being able to
-    // do it all at compile time.  Add new CryptoTypes in
-    // supported_crypto_types[] below.
-    constexpr CryptoType() : CryptoType(nullptr, nullptr, 0xFFFFFFFF) {}
-    constexpr CryptoType set_keysize(uint32_t size) const {
-        return CryptoType(this->property_name, this->crypto_name, size);
-    }
-    constexpr CryptoType set_property_name(const char *property) const {
-        return CryptoType(property, this->crypto_name, this->keysize);
-    }
-    constexpr CryptoType set_crypto_name(const char *crypto) const {
-        return CryptoType(this->property_name, crypto, this->keysize);
-    }
-
-    constexpr const char *get_property_name() const { return property_name; }
-    constexpr const char *get_crypto_name() const { return crypto_name; }
-    constexpr uint32_t get_keysize() const { return keysize; }
-
- private:
-    const char *property_name;
-    const char *crypto_name;
-    uint32_t keysize;
-
-    constexpr CryptoType(const char *property, const char *crypto,
-                         uint32_t ksize)
-        : property_name(property), crypto_name(crypto), keysize(ksize) {}
-    friend const CryptoType &get_crypto_type();
-    static const CryptoType &get_device_crypto_algorithm();
-};
-
-// We only want to parse this read-only property once.  But we need to wait
-// until the system is initialized before we can read it.  So we use a static
-// scoped within this function to get it only once.
-const CryptoType &get_crypto_type() {
-    static CryptoType crypto_type = CryptoType::get_device_crypto_algorithm();
-    return crypto_type;
-}
-
-constexpr CryptoType default_crypto_type = CryptoType()
-    .set_property_name("AES-128-CBC")
-    .set_crypto_name("aes-cbc-essiv:sha256")
-    .set_keysize(16);
-
-constexpr CryptoType supported_crypto_types[] = {
-    default_crypto_type,
-    CryptoType()
-        .set_property_name("Speck128/128-XTS")
-        .set_crypto_name("speck128-xts-plain64")
-        .set_keysize(32),
-    // Add new CryptoTypes here.  Order is not important.
-};
-
-
-// ---------- START COMPILE-TIME SANITY CHECK BLOCK -------------------------
-// We confirm all supported_crypto_types have a small enough keysize and
-// had both set_property_name() and set_crypto_name() called.
-
-template <typename T, size_t N>
-constexpr size_t array_length(T (&)[N]) { return N; }
-
-constexpr bool indexOutOfBoundsForCryptoTypes(size_t index) {
-    return (index >= array_length(supported_crypto_types));
-}
-
-constexpr bool isValidCryptoType(const CryptoType &crypto_type) {
-    return ((crypto_type.get_property_name() != nullptr) &&
-            (crypto_type.get_crypto_name() != nullptr) &&
-            (crypto_type.get_keysize() <= MAX_KEY_LEN));
-}
-
-// Note in C++11 that constexpr functions can only have a single line.
-// So our code is a bit convoluted (using recursion instead of a loop),
-// but it's asserting at compile time that all of our key lengths are valid.
-constexpr bool validateSupportedCryptoTypes(size_t index) {
-    return indexOutOfBoundsForCryptoTypes(index) ||
-        (isValidCryptoType(supported_crypto_types[index]) &&
-         validateSupportedCryptoTypes(index + 1));
-}
-
-static_assert(validateSupportedCryptoTypes(0),
-              "We have a CryptoType with keysize > MAX_KEY_LEN or which was "
-              "incompletely constructed.");
-//  ---------- END COMPILE-TIME SANITY CHECK BLOCK -------------------------
-
-
-// Don't call this directly, use get_crypto_type(), which caches this result.
-const CryptoType &CryptoType::get_device_crypto_algorithm() {
-    constexpr char CRYPT_ALGO_PROP[] = "ro.crypto.fde_algorithm";
-    char paramstr[PROPERTY_VALUE_MAX];
-
-    property_get(CRYPT_ALGO_PROP, paramstr,
-                 default_crypto_type.get_property_name());
-    for (auto const &ctype : supported_crypto_types) {
-        if (strcmp(paramstr, ctype.get_property_name()) == 0) {
-            return ctype;
-        }
-    }
-    ALOGE("Invalid name (%s) for %s.  Defaulting to %s\n", paramstr,
-          CRYPT_ALGO_PROP, default_crypto_type.get_property_name());
-    return default_crypto_type;
-}
-
-}  // namespace
-
-#define SCRYPT_PROP "ro.crypto.scrypt_params"
-#define SCRYPT_DEFAULTS "15:3:1"
-
-bool parse_scrypt_parameters(const char* paramstr, int *Nf, int *rf, int *pf) {
-    int params[3] = {};
-    char *token;
-    char *saveptr;
-    int i;
-
-    /*
-     * The token we're looking for should be three integers separated by
-     * colons (e.g., "12:8:1"). Scan the property to make sure it matches.
-     */
-    for (i = 0, token = strtok_r(const_cast<char *>(paramstr), ":", &saveptr);
-            token != nullptr && i < 3;
-            i++, token = strtok_r(nullptr, ":", &saveptr)) {
-        char *endptr;
-        params[i] = strtol(token, &endptr, 10);
-
-        /*
-         * Check that there was a valid number and it's 8-bit.
-         */
-        if ((*token == '\0') || (*endptr != '\0') || params[i] < 0 || params[i] > 255) {
-            return false;
-        }
-    }
-    if (token != nullptr) {
-        return false;
-    }
-    *Nf = params[0]; *rf = params[1]; *pf = params[2];
-    return true;
-}
-
-uint32_t cryptfs_get_keysize() {
-    return get_crypto_type().get_keysize();
-}
-
-const char *cryptfs_get_crypto_name() {
-    return get_crypto_type().get_crypto_name();
-}
-
-static int get_crypt_ftr_info(char **metadata_fname, off64_t *off)
-{
-  static int cached_data = 0;
-  static off64_t cached_off = 0;
-  static char cached_metadata_fname[PROPERTY_VALUE_MAX] = "";
-  int fd;
-  //char key_loc[PROPERTY_VALUE_MAX];
-  //char real_blkdev[PROPERTY_VALUE_MAX];
-  int rc = -1;
-
-  if (!cached_data) {
-    //fs_mgr_get_crypt_info(fstab_default, key_loc, real_blkdev, sizeof(key_loc));
-
-    if (!strcmp(key_fname, KEY_IN_FOOTER)) {
-      if ( (fd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
-        SLOGE("Cannot open real block device %s\n", real_blkdev);
-        return -1;
-      }
-
-      unsigned long nr_sec = 0;
-      get_blkdev_size(fd, &nr_sec);
-      if (nr_sec != 0) {
-        /* If it's an encrypted Android partition, the last 16 Kbytes contain the
-         * encryption info footer and key, and plenty of bytes to spare for future
-         * growth.
-         */
-        strlcpy(cached_metadata_fname, real_blkdev, sizeof(cached_metadata_fname));
-        cached_off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;
-        cached_data = 1;
-      } else {
-        SLOGE("Cannot get size of block device %s\n", real_blkdev);
-      }
-      close(fd);
-    } else {
-      strlcpy(cached_metadata_fname, key_fname, sizeof(cached_metadata_fname));
-      cached_off = 0;
-      cached_data = 1;
-    }
-  }
-
-  if (cached_data) {
-    if (metadata_fname) {
-        *metadata_fname = cached_metadata_fname;
-    }
-    if (off) {
-        *off = cached_off;
-    }
-    rc = 0;
-  }
-
-  return rc;
-}
-
-static int get_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr)
-{
-  int fd;
-  unsigned int cnt;
-  off64_t starting_off;
-  int rc = -1;
-  char *fname = NULL;
-  struct stat statbuf;
-
-  if (get_crypt_ftr_info(&fname, &starting_off)) {
-    SLOGE("Unable to get crypt_ftr_info\n");
-    return -1;
-  }
-  if (fname[0] != '/') {
-    SLOGE("fde::get_crypt_ftr_and_key::Unexpected value for crypto key location: %s\n", fname);
-    return -1;
-  }
-  if ( (fd = open(fname, O_RDWR|O_CLOEXEC)) < 0) {
-    SLOGE("Cannot open footer file %s for get\n", fname);
-    return -1;
-  }
-
-  /* Make sure it's 16 Kbytes in length */
-  fstat(fd, &statbuf);
-  if (S_ISREG(statbuf.st_mode) && (statbuf.st_size != 0x4000)) {
-    SLOGE("footer file %s is not the expected size!\n", fname);
-    goto errout;
-  }
-
-  /* Seek to the start of the crypt footer */
-  if (lseek64(fd, starting_off, SEEK_SET) == -1) {
-    SLOGE("Cannot seek to real block device footer\n");
-    goto errout;
-  }
-
-  if ( (cnt = read(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
-    SLOGE("Cannot read real block device footer\n");
-    goto errout;
-  }
-
-  if (crypt_ftr->magic != CRYPT_MNT_MAGIC) {
-    SLOGE("Bad magic for real block device %s\n", fname);
-    goto errout;
-  }
-
-  if (crypt_ftr->major_version != CURRENT_MAJOR_VERSION) {
-    SLOGE("Cannot understand major version %d real block device footer; expected %d\n",
-          crypt_ftr->major_version, CURRENT_MAJOR_VERSION);
-    goto errout;
-  }
-
-  // We risk buffer overflows with oversized keys, so we just reject them.
-  // 0-sized keys are problematic (essentially by-passing encryption), and
-  // AES-CBC key wrapping only works for multiples of 16 bytes.
-  if ((crypt_ftr->keysize == 0) || ((crypt_ftr->keysize % 16) != 0) ||
-      (crypt_ftr->keysize > MAX_KEY_LEN)) {
-    SLOGE("Invalid keysize (%u) for block device %s; Must be non-zero, "
-          "divisible by 16, and <= %d\n", crypt_ftr->keysize, fname,
-          MAX_KEY_LEN);
-    goto errout;
-  }
-
-  if (crypt_ftr->minor_version > CURRENT_MINOR_VERSION) {
-    SLOGW("Warning: crypto footer minor version %d, expected <= %d, continuing...\n",
-          crypt_ftr->minor_version, CURRENT_MINOR_VERSION);
-  }
-
-  /* Success! */
-  rc = 0;
-
-errout:
-  close(fd);
-  return rc;
-}
-
-int cryptfs_check_footer()
-{
-    int rc = -1;
-    struct crypt_mnt_ftr crypt_ftr;
-
-    rc = get_crypt_ftr_and_key(&crypt_ftr);
-
-    return rc;
-}
-
-/* Convert a binary key of specified length into an ascii hex string equivalent,
- * without the leading 0x and with null termination
- */
-static void convert_key_to_hex_ascii(const unsigned char *master_key,
-                                     unsigned int keysize, char *master_key_ascii) {
-    unsigned int i, a;
-    unsigned char nibble;
-
-    for (i=0, a=0; i<keysize; i++, a+=2) {
-        /* For each byte, write out two ascii hex digits */
-        nibble = (master_key[i] >> 4) & 0xf;
-        master_key_ascii[a] = nibble + (nibble > 9 ? 0x37 : 0x30);
-
-        nibble = master_key[i] & 0xf;
-        master_key_ascii[a+1] = nibble + (nibble > 9 ? 0x37 : 0x30);
-    }
-
-    /* Add the null termination */
-    master_key_ascii[a] = '\0';
-
-}
-
-static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr,
-        const unsigned char *master_key, const char *real_blk_name,
-        const char *name, int fd, const char *extra_params) {
-  alignas(struct dm_ioctl) char buffer[DM_CRYPT_BUF_SIZE];
-  struct dm_ioctl *io;
-  struct dm_target_spec *tgt;
-  char *crypt_params;
-  // We need two ASCII characters to represent each byte, and need space for
-  // the '\0' terminator.
-  char master_key_ascii[MAX_KEY_LEN * 2 + 1];
-  size_t buff_offset;
-  int i;
-
-  io = (struct dm_ioctl *) buffer;
-
-  /* Load the mapping table for this device */
-  tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
-
-  ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
-  io->target_count = 1;
-  tgt->status = 0;
-  tgt->sector_start = 0;
-  tgt->length = crypt_ftr->fs_size;
-  crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
-  buff_offset = crypt_params - buffer;
-  SLOGI(
-	"Creating crypto dev \"%s\"; cipher=%s, keysize=%u, real_dev=%s, len=%llu, params=\"%s\"\n",
-	name, crypt_ftr->crypto_type_name, crypt_ftr->keysize, real_blk_name, tgt->length * 512,
-	extra_params);
-
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-  if(is_hw_disk_encryption((char*)crypt_ftr->crypto_type_name)) {
-    strlcpy(tgt->target_type, "req-crypt",DM_MAX_TYPE_NAME);
-    if (is_ice_enabled())
-      convert_key_to_hex_ascii(master_key, sizeof(int), master_key_ascii);
-    else
-      convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
-  }
-  else {
-    convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
-    strlcpy(tgt->target_type, "crypt", DM_MAX_TYPE_NAME);
-  }
-  snprintf(crypt_params, sizeof(buffer) - buff_offset, "%s %s 0 %s 0 %s 0",
-           crypt_ftr->crypto_type_name, master_key_ascii,
-           real_blk_name, extra_params);
-
-  SLOGI("target_type = %s", tgt->target_type);
-  SLOGI("real_blk_name = %s, extra_params = %s", real_blk_name, extra_params);
-#else
-  convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
-  strlcpy(tgt->target_type, "crypt", DM_MAX_TYPE_NAME);
-  snprintf(crypt_params, sizeof(buffer) - buff_offset, "%s %s 0 %s 0 %s",
-           crypt_ftr->crypto_type_name, master_key_ascii, real_blk_name,
-           extra_params);
-#endif
-
-  crypt_params += strlen(crypt_params) + 1;
-  crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */
-  tgt->next = crypt_params - buffer;
-
-  for (i = 0; i < TABLE_LOAD_RETRIES; i++) {
-    int ret = ioctl(fd, DM_TABLE_LOAD, io);
-    if (!ret)  {
-      SLOGI("ioctl err: %d", ret);
-      break;
-    }
-    usleep(500000);
-  }
-
-  if (i == TABLE_LOAD_RETRIES) {
-    /* We failed to load the table, return an error */
-    return -1;
-  } else {
-    return i + 1;
-  }
-}
-
-static int get_dm_crypt_version(int fd, const char *name,  int *version)
-{
-    char buffer[DM_CRYPT_BUF_SIZE];
-    struct dm_ioctl *io;
-    struct dm_target_versions *v;
-
-    io = (struct dm_ioctl *) buffer;
-
-    ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
-
-    if (ioctl(fd, DM_LIST_VERSIONS, io)) {
-        return -1;
-    }
-
-    /* Iterate over the returned versions, looking for name of "crypt".
-     * When found, get and return the version.
-     */
-    v = (struct dm_target_versions *) &buffer[sizeof(struct dm_ioctl)];
-    while (v->next) {
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-        if (! strcmp(v->name, "crypt") || ! strcmp(v->name, "req-crypt")) {
-#else
-        if (! strcmp(v->name, "crypt")) {
-#endif
-            /* We found the crypt driver, return the version, and get out */
-            version[0] = v->version[0];
-            version[1] = v->version[1];
-            version[2] = v->version[2];
-            return 0;
-        }
-        v = (struct dm_target_versions *)(((char *)v) + v->next);
-    }
-
-    return -1;
-}
-
-#ifndef CONFIG_HW_DISK_ENCRYPTION
-static std::string extra_params_as_string(const std::vector<std::string>& extra_params_vec) {
-    if (extra_params_vec.empty()) return "";
-    char temp[10];
-    snprintf(temp, sizeof(temp), "%zd", extra_params_vec.size());
-    std::string extra_params = temp; //std::to_string(extra_params_vec.size());
-    for (const auto& p : extra_params_vec) {
-        extra_params.append(" ");
-        extra_params.append(p);
-    }
-    return extra_params;
-}
-#endif
-
-static int create_crypto_blk_dev(struct crypt_mnt_ftr* crypt_ftr, const unsigned char* master_key,
-                                 const char* real_blk_name, char* crypto_blk_name, const char* name,
-                                 uint32_t flags) {
-    char buffer[DM_CRYPT_BUF_SIZE];
-    struct dm_ioctl* io;
-    unsigned int minor;
-    int fd = 0;
-    int err;
-    int retval = -1;
-    int version[3];
-    int load_count;
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-    char encrypted_state[PROPERTY_VALUE_MAX] = {0};
-    char progress[PROPERTY_VALUE_MAX] = {0};
-    const char *extra_params;
-#else
-    std::vector<std::string> extra_params_vec;
-#endif
-
-    if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
-        SLOGE("Cannot open device-mapper\n");
-        goto errout;
-    }
-
-    io = (struct dm_ioctl*)buffer;
-
-    ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
-    err = ioctl(fd, DM_DEV_CREATE, io);
-    if (err) {
-        SLOGE("Cannot create dm-crypt device %s: %s\n", name, strerror(errno));
-        goto errout;
-    }
-
-    /* Get the device status, in particular, the name of it's device file */
-    ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
-    if (ioctl(fd, DM_DEV_STATUS, io)) {
-        SLOGE("Cannot retrieve dm-crypt device status\n");
-        goto errout;
-    }
-    minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
-    snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor);
-
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-    if(is_hw_disk_encryption((char*)crypt_ftr->crypto_type_name)) {
-      /* Set fde_enabled if either FDE completed or in-progress */
-      property_get("ro.crypto.state", encrypted_state, ""); /* FDE completed */
-      property_get("vold.encrypt_progress", progress, ""); /* FDE in progress */
-      if (!strcmp(encrypted_state, "encrypted") || strcmp(progress, "")) {
-        if (is_ice_enabled()) {
-          if (flags & CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE)
-            extra_params = "fde_enabled ice allow_encrypt_override";
-          else
-            extra_params = "fde_enabled ice";
-        } else {
-          if (flags & CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE)
-            extra_params = "fde_enabled allow_encrypt_override";
-          else
-            extra_params = "fde_enabled";
-        }
-      } else {
-          if (flags & CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE)
-            extra_params = "fde_enabled allow_encrypt_override";
-          else
-            extra_params = "fde_enabled";
-      }
-    } else {
-      extra_params = "";
-      if (! get_dm_crypt_version(fd, name, version)) {
-        /* Support for allow_discards was added in version 1.11.0 */
-        if ((version[0] >= 2) || ((version[0] == 1) && (version[1] >= 11))) {
-          if (flags & CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE)
-            extra_params = "2 allow_discards allow_encrypt_override";
-          else
-            extra_params = "1 allow_discards";
-          SLOGI("Enabling support for allow_discards in dmcrypt.\n");
-        }
-      }
-    }
-    load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name, fd,
-                                           extra_params);
-#else
-    if (!get_dm_crypt_version(fd, name, version)) {
-        /* Support for allow_discards was added in version 1.11.0 */
-        if ((version[0] >= 2) || ((version[0] == 1) && (version[1] >= 11))) {
-            extra_params_vec.push_back(std::string("allow_discards")); // Used to be extra_params_vec.emplace_back("allow_discards"); but this won't compile in 5.1 trees
-        }
-    }
-    if (flags & CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE) {
-        extra_params_vec.push_back(std::string("allow_encrypt_override")); // Used to be extra_params_vec.emplace_back("allow_encrypt_override"); but this won't compile in 5.1 trees
-    }
-    load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name, fd,
-                                           extra_params_as_string(extra_params_vec).c_str());
-#endif
-    if (load_count < 0) {
-        SLOGE("Cannot load dm-crypt mapping table.\n");
-        goto errout;
-    } else if (load_count > 1) {
-        SLOGI("Took %d tries to load dmcrypt table.\n", load_count);
-    }
-
-    /* Resume this device to activate it */
-    ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
-
-    if (ioctl(fd, DM_DEV_SUSPEND, io)) {
-        SLOGE("Cannot resume the dm-crypt device\n");
-        goto errout;
-    }
-
-    /* We made it here with no errors.  Woot! */
-    retval = 0;
-
-errout:
-  close(fd);   /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
-
-  return retval;
-}
-
-int delete_crypto_blk_dev(const char *name)
-{
-  int fd;
-  char buffer[DM_CRYPT_BUF_SIZE];
-  struct dm_ioctl *io;
-  int retval = -1;
-
-  if ((fd = open("/dev/device-mapper", O_RDWR|O_CLOEXEC)) < 0 ) {
-    SLOGE("Cannot open device-mapper\n");
-    goto errout;
-  }
-
-  io = (struct dm_ioctl *) buffer;
-
-  ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
-  if (ioctl(fd, DM_DEV_REMOVE, io)) {
-    SLOGE("Cannot remove dm-crypt device\n");
-    goto errout;
-  }
-
-  /* We made it here with no errors.  Woot! */
-  retval = 0;
-
-errout:
-  close(fd);    /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
-
-  return retval;
-
-}
-
-static int pbkdf2(const char *passwd, const unsigned char *salt,
-                  unsigned char *ikey, void *params UNUSED)
-{
-    SLOGI("Using pbkdf2 for cryptfs KDF\n");
-
-    /* Turn the password into a key and IV that can decrypt the master key */
-    return PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, SALT_LEN,
-                                  HASH_COUNT, INTERMEDIATE_BUF_SIZE,
-                                  ikey) != 1;
-}
-
-static int scrypt(const char *passwd, const unsigned char *salt,
-                  unsigned char *ikey, void *params)
-{
-    SLOGI("Using scrypt for cryptfs KDF\n");
-
-    struct crypt_mnt_ftr *ftr = (struct crypt_mnt_ftr *) params;
-
-    int N = 1 << ftr->N_factor;
-    int r = 1 << ftr->r_factor;
-    int p = 1 << ftr->p_factor;
-
-    /* Turn the password into a key and IV that can decrypt the master key */
-    crypto_scrypt((const uint8_t*)passwd, strlen(passwd),
-                  salt, SALT_LEN, N, r, p, ikey,
-                  INTERMEDIATE_BUF_SIZE);
-
-   return 0;
-}
-
-static int scrypt_keymaster(const char *passwd, const unsigned char *salt,
-                            unsigned char *ikey, void *params)
-{
-    SLOGI("Using scrypt with keymaster for cryptfs KDF\n");
-
-    int rc;
-    size_t signature_size;
-    unsigned char* signature;
-    struct crypt_mnt_ftr *ftr = (struct crypt_mnt_ftr *) params;
-
-    int N = 1 << ftr->N_factor;
-    int r = 1 << ftr->r_factor;
-    int p = 1 << ftr->p_factor;
-
-    rc = crypto_scrypt((const uint8_t*)passwd, strlen(passwd),
-                       salt, SALT_LEN, N, r, p, ikey,
-                       INTERMEDIATE_BUF_SIZE);
-
-    if (rc) {
-        SLOGE("scrypt failed");
-        return -1;
-    }
-
-    if (keymaster_sign_object(ftr, ikey, INTERMEDIATE_BUF_SIZE,
-                              &signature, &signature_size)) {
-        SLOGE("Keymaster signing failed");
-        return -1;
-    }
-
-    rc = crypto_scrypt(signature, signature_size, salt, SALT_LEN,
-                       N, r, p, ikey, INTERMEDIATE_BUF_SIZE);
-    free(signature);
-
-    if (rc) {
-        SLOGE("scrypt failed");
-        return -1;
-    }
-
-    return 0;
-}
-
-static int decrypt_master_key_aux(const char *passwd, unsigned char *salt,
-                                  const unsigned char *encrypted_master_key,
-                                  size_t keysize,
-                                  unsigned char *decrypted_master_key,
-                                  kdf_func kdf, void *kdf_params,
-                                  unsigned char** intermediate_key,
-                                  size_t* intermediate_key_size)
-{
-  unsigned char ikey[INTERMEDIATE_BUF_SIZE] = { 0 };
-  EVP_CIPHER_CTX d_ctx;
-  int decrypted_len, final_len;
-
-  /* Turn the password into an intermediate key and IV that can decrypt the
-     master key */
-  if (kdf(passwd, salt, ikey, kdf_params)) {
-    SLOGE("kdf failed");
-    return -1;
-  }
-
-  /* Initialize the decryption engine */
-  EVP_CIPHER_CTX_init(&d_ctx);
-  if (! EVP_DecryptInit_ex(&d_ctx, EVP_aes_128_cbc(), NULL, ikey, ikey+INTERMEDIATE_KEY_LEN_BYTES)) {
-    return -1;
-  }
-  EVP_CIPHER_CTX_set_padding(&d_ctx, 0); /* Turn off padding as our data is block aligned */
-  /* Decrypt the master key */
-  if (! EVP_DecryptUpdate(&d_ctx, decrypted_master_key, &decrypted_len,
-                            encrypted_master_key, keysize)) {
-    return -1;
-  }
-  if (! EVP_DecryptFinal_ex(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) {
-    return -1;
-  }
-
-  if (decrypted_len + final_len != static_cast<int>(keysize)) {
-    return -1;
-  }
-
-  /* Copy intermediate key if needed by params */
-  if (intermediate_key && intermediate_key_size) {
-    *intermediate_key = (unsigned char*) malloc(INTERMEDIATE_KEY_LEN_BYTES);
-    if (*intermediate_key) {
-      memcpy(*intermediate_key, ikey, INTERMEDIATE_KEY_LEN_BYTES);
-      *intermediate_key_size = INTERMEDIATE_KEY_LEN_BYTES;
-    }
-  }
-
-  EVP_CIPHER_CTX_cleanup(&d_ctx);
-
-  return 0;
-}
-
-static void get_kdf_func(struct crypt_mnt_ftr *ftr, kdf_func *kdf, void** kdf_params)
-{
-    if (ftr->kdf_type == KDF_SCRYPT_KEYMASTER) {
-        *kdf = scrypt_keymaster;
-        *kdf_params = ftr;
-    } else if (ftr->kdf_type == KDF_SCRYPT) {
-        *kdf = scrypt;
-        *kdf_params = ftr;
-    } else {
-        *kdf = pbkdf2;
-        *kdf_params = NULL;
-    }
-}
-
-static int decrypt_master_key(const char *passwd, unsigned char *decrypted_master_key,
-                              struct crypt_mnt_ftr *crypt_ftr,
-                              unsigned char** intermediate_key,
-                              size_t* intermediate_key_size)
-{
-    kdf_func kdf;
-    void *kdf_params;
-    int ret;
-
-    get_kdf_func(crypt_ftr, &kdf, &kdf_params);
-    ret = decrypt_master_key_aux(passwd, crypt_ftr->salt, crypt_ftr->master_key,
-                                 crypt_ftr->keysize,
-                                 decrypted_master_key, kdf, kdf_params,
-                                 intermediate_key, intermediate_key_size);
-    if (ret != 0) {
-        SLOGW("failure decrypting master key");
-    }
-
-    return ret;
-}
-
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-static int test_mount_hw_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
-             const char *passwd, const char *mount_point, const char *label)
-{
-  /* Allocate enough space for a 256 bit key, but we may use less */
-  unsigned char decrypted_master_key[32];
-  char crypto_blkdev[MAXPATHLEN];
-  //char real_blkdev[MAXPATHLEN];
-  unsigned int orig_failed_decrypt_count;
-  int rc = 0;
-
-  SLOGD("crypt_ftr->fs_size = %lld\n", crypt_ftr->fs_size);
-  orig_failed_decrypt_count = crypt_ftr->failed_decrypt_count;
-
-  //fs_mgr_get_crypt_info(fstab_default, 0, real_blkdev, sizeof(real_blkdev));
-
-  int key_index = 0;
-  if(is_hw_disk_encryption((char*)crypt_ftr->crypto_type_name)) {
-    key_index = verify_and_update_hw_fde_passwd(passwd, crypt_ftr);
-    if (key_index < 0) {
-      rc = -1;
-      goto errout;
-    }
-    else {
-      if (is_ice_enabled()) {
-#ifndef CONFIG_HW_DISK_ENCRYPT_PERF
-        if (create_crypto_blk_dev(crypt_ftr, (unsigned char*)&key_index,
-                            real_blkdev, crypto_blkdev, label, 0)) {
-          SLOGE("Error creating decrypted block device");
-          rc = -1;
-          goto errout;
-        }
-#endif
-      } else {
-        if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key,
-                            real_blkdev, crypto_blkdev, label, 0)) {
-          SLOGE("Error creating decrypted block device");
-          rc = -1;
-          goto errout;
-        }
-      }
-    }
-  }
-
-  if (rc == 0) {
-    /* Save the name of the crypto block device
-     * so we can mount it when restarting the framework. */
-#ifdef CONFIG_HW_DISK_ENCRYPT_PERF
-    if (!is_ice_enabled())
-#endif
-    property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev);
-    master_key_saved = 1;
-  }
-
- errout:
-  return rc;
-}
-#endif
-
-static int try_mount_multiple_fs(const char *crypto_blkdev,
-                                 const char *mount_point,
-                                 const char *file_system)
-{
-    if (!mount(crypto_blkdev, mount_point, file_system, 0, NULL))
-        return 0;
-    if (strcmp(file_system, "ext4") &&
-        !mount(crypto_blkdev, mount_point, "ext4", 0, NULL))
-        return 0;
-    if (strcmp(file_system, "f2fs") &&
-        !mount(crypto_blkdev, mount_point, "f2fs", 0, NULL))
-        return 0;
-    return 1;
-}
-
-static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
-                                   const char *passwd, const char *mount_point, const char *label)
-{
-  unsigned char decrypted_master_key[MAX_KEY_LEN];
-  char crypto_blkdev[MAXPATHLEN];
-  //char real_blkdev[MAXPATHLEN];
-  char tmp_mount_point[64];
-  unsigned int orig_failed_decrypt_count;
-  int rc;
-  int use_keymaster = 0;
-  unsigned char* intermediate_key = 0;
-  size_t intermediate_key_size = 0;
-  int N = 1 << crypt_ftr->N_factor;
-  int r = 1 << crypt_ftr->r_factor;
-  int p = 1 << crypt_ftr->p_factor;
-
-  SLOGD("crypt_ftr->fs_size = %lld\n", crypt_ftr->fs_size);
-  orig_failed_decrypt_count = crypt_ftr->failed_decrypt_count;
-
-  if (! (crypt_ftr->flags & CRYPT_MNT_KEY_UNENCRYPTED) ) {
-    if (decrypt_master_key(passwd, decrypted_master_key, crypt_ftr,
-                           &intermediate_key, &intermediate_key_size)) {
-      SLOGE("Failed to decrypt master key\n");
-      rc = -1;
-      goto errout;
-    }
-  }
-
-  //fs_mgr_get_crypt_info(fstab_default, 0, real_blkdev, sizeof(real_blkdev));
-
-  // Create crypto block device - all (non fatal) code paths
-  // need it
-  if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev, label, 0)) {
-      SLOGE("Error creating decrypted block device\n");
-      rc = -1;
-      goto errout;
-  }
-
-  /* Work out if the problem is the password or the data */
-  unsigned char scrypted_intermediate_key[sizeof(crypt_ftr->
-                                                 scrypted_intermediate_key)];
-
-  rc = crypto_scrypt(intermediate_key, intermediate_key_size,
-                     crypt_ftr->salt, sizeof(crypt_ftr->salt),
-                     N, r, p, scrypted_intermediate_key,
-                     sizeof(scrypted_intermediate_key));
-
-  // Does the key match the crypto footer?
-  if (rc == 0 && memcmp(scrypted_intermediate_key,
-                        crypt_ftr->scrypted_intermediate_key,
-                        sizeof(scrypted_intermediate_key)) == 0) {
-    SLOGI("Password matches");
-    rc = 0;
-  } else {
-    /* Try mounting the file system anyway, just in case the problem's with
-     * the footer, not the key. */
-    snprintf(tmp_mount_point, sizeof(tmp_mount_point), "%s/tmp_mnt",
-             mount_point);
-    mkdir(tmp_mount_point, 0755);
-    if (try_mount_multiple_fs(crypto_blkdev, tmp_mount_point, file_system)) {
-      SLOGE("Error temp mounting decrypted block device\n");
-      delete_crypto_blk_dev(label);
-
-      rc = -1;
-    } else {
-      /* Success! */
-      SLOGI("Password did not match but decrypted drive mounted - continue");
-      umount(tmp_mount_point);
-      rc = 0;
-    }
-  }
-
-  if (rc == 0) {
-    /* Save the name of the crypto block device
-     * so we can mount it when restarting the framework. */
-    property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev);
-
-    /* Also save a the master key so we can reencrypted the key
-     * the key when we want to change the password on it. */
-    memcpy(saved_master_key, decrypted_master_key, crypt_ftr->keysize);
-    saved_mount_point = strdup(mount_point);
-    master_key_saved = 1;
-    SLOGD("%s(): Master key saved\n", __FUNCTION__);
-    rc = 0;
-  }
-
- errout:
-  if (intermediate_key) {
-    memset(intermediate_key, 0, intermediate_key_size);
-    free(intermediate_key);
-  }
-  return rc;
-}
-
-/*
- * Called by vold when it's asked to mount an encrypted external
- * storage volume. The incoming partition has no crypto header/footer,
- * as any metadata is been stored in a separate, small partition.  We
- * assume it must be using our same crypt type and keysize.
- *
- * out_crypto_blkdev must be MAXPATHLEN.
- */
-int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev,
-        const unsigned char* key, int keysize, char* out_crypto_blkdev) {
-    int fd = open(real_blkdev, O_RDONLY|O_CLOEXEC);
-    if (fd == -1) {
-        SLOGE("Failed to open %s: %s", real_blkdev, strerror(errno));
-        return -1;
-    }
-
-    unsigned long nr_sec = 0;
-    get_blkdev_size(fd, &nr_sec);
-    close(fd);
-
-    if (nr_sec == 0) {
-        SLOGE("Failed to get size of %s: %s", real_blkdev, strerror(errno));
-        return -1;
-    }
-
-    struct crypt_mnt_ftr ext_crypt_ftr;
-    memset(&ext_crypt_ftr, 0, sizeof(ext_crypt_ftr));
-    ext_crypt_ftr.fs_size = nr_sec;
-    ext_crypt_ftr.keysize = cryptfs_get_keysize();
-    strlcpy((char*) ext_crypt_ftr.crypto_type_name, cryptfs_get_crypto_name(),
-            MAX_CRYPTO_TYPE_NAME_LEN);
-    uint32_t flags = 0;
-    /*if (e4crypt_is_native() &&
-        android::base::GetBoolProperty("ro.crypto.allow_encrypt_override", false))
-        flags |= CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE;*/
-
-    return create_crypto_blk_dev(&ext_crypt_ftr, key, real_blkdev, out_crypto_blkdev, label, flags);
-}
-
-/*
- * Called by vold when it's asked to unmount an encrypted external
- * storage volume.
- */
-int cryptfs_revert_ext_volume(const char* label) {
-    return delete_crypto_blk_dev(label);
-}
-
-int check_unmounted_and_get_ftr(struct crypt_mnt_ftr* crypt_ftr)
-{
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    property_get("ro.crypto.state", encrypted_state, "");
-    if ( master_key_saved || strcmp(encrypted_state, "encrypted") ) {
-        SLOGE("encrypted fs already validated or not running with encryption,"
-              " aborting");
-        return -1;
-    }
-
-    if (get_crypt_ftr_and_key(crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key");
-        return -1;
-    }
-
-    return 0;
-}
-
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-int cryptfs_check_passwd_hw(const char* passwd)
-{
-    struct crypt_mnt_ftr crypt_ftr;
-    int rc;
-    unsigned char master_key[KEY_LEN_BYTES];
-    /* get key */
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key");
-        return -1;
-    }
-
-    /*
-     * in case of manual encryption (from GUI), the encryption is done with
-     * default password
-     */
-    if (crypt_ftr.flags & CRYPT_FORCE_COMPLETE) {
-        /* compare scrypted_intermediate_key with stored scrypted_intermediate_key
-         * which was created with actual password before reboot.
-         */
-        rc = cryptfs_get_master_key(&crypt_ftr, passwd, master_key);
-        if (rc) {
-            SLOGE("password doesn't match");
-            return rc;
-        }
-
-        rc = test_mount_hw_encrypted_fs(&crypt_ftr, DEFAULT_PASSWORD,
-            DATA_MNT_POINT, CRYPTO_BLOCK_DEVICE);
-
-        if (rc) {
-            SLOGE("Default password did not match on reboot encryption");
-            return rc;
-        }
-    } else {
-        rc = test_mount_hw_encrypted_fs(&crypt_ftr, passwd,
-            DATA_MNT_POINT, CRYPTO_BLOCK_DEVICE);
-        SLOGE("test mount returned %i\n", rc);
-    }
-
-    return rc;
-}
-#endif
-
-int cryptfs_check_passwd(const char *passwd)
-{
-    /*if (e4crypt_is_native()) {
-        SLOGE("cryptfs_check_passwd not valid for file encryption");
-        return -1;
-    }*/
-
-    struct crypt_mnt_ftr crypt_ftr;
-    int rc;
-
-    rc = check_unmounted_and_get_ftr(&crypt_ftr);
-    if (rc) {
-        SLOGE("Could not get footer");
-        return rc;
-    }
-
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-    if (is_hw_disk_encryption((char*)crypt_ftr.crypto_type_name))
-        return cryptfs_check_passwd_hw(passwd);
-#endif
-
-    rc = test_mount_encrypted_fs(&crypt_ftr, passwd,
-                                 DATA_MNT_POINT, CRYPTO_BLOCK_DEVICE);
-
-    if (rc) {
-        SLOGE("Password did not match");
-        return rc;
-    }
-
-    if (crypt_ftr.flags & CRYPT_FORCE_COMPLETE) {
-        // Here we have a default actual password but a real password
-        // we must test against the scrypted value
-        // First, we must delete the crypto block device that
-        // test_mount_encrypted_fs leaves behind as a side effect
-        delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE);
-        rc = test_mount_encrypted_fs(&crypt_ftr, DEFAULT_PASSWORD,
-                                     DATA_MNT_POINT, CRYPTO_BLOCK_DEVICE);
-        if (rc) {
-            SLOGE("Default password did not match on reboot encryption");
-            return rc;
-        }
-    }
-
-    return rc;
-}
-
-int cryptfs_verify_passwd(const char *passwd)
-{
-    struct crypt_mnt_ftr crypt_ftr;
-    unsigned char decrypted_master_key[MAX_KEY_LEN];
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    int rc;
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (strcmp(encrypted_state, "encrypted") ) {
-        SLOGE("device not encrypted, aborting");
-        return -2;
-    }
-
-    if (!master_key_saved) {
-        SLOGE("encrypted fs not yet mounted, aborting");
-        return -1;
-    }
-
-    if (!saved_mount_point) {
-        SLOGE("encrypted fs failed to save mount point, aborting");
-        return -1;
-    }
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key\n");
-        return -1;
-    }
-
-    if (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) {
-        /* If the device has no password, then just say the password is valid */
-        rc = 0;
-    } else {
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-        if(is_hw_disk_encryption((char*)crypt_ftr.crypto_type_name)) {
-            if (verify_hw_fde_passwd(passwd, &crypt_ftr) >= 0)
-              rc = 0;
-            else
-              rc = -1;
-        } else {
-            decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
-            if (!memcmp(decrypted_master_key, saved_master_key, crypt_ftr.keysize)) {
-                /* They match, the password is correct */
-                rc = 0;
-            } else {
-              /* If incorrect, sleep for a bit to prevent dictionary attacks */
-                sleep(1);
-                rc = 1;
-            }
-        }
-#else
-        decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
-        if (!memcmp(decrypted_master_key, saved_master_key, crypt_ftr.keysize)) {
-            /* They match, the password is correct */
-            rc = 0;
-        } else {
-            /* If incorrect, sleep for a bit to prevent dictionary attacks */
-            sleep(1);
-            rc = 1;
-        }
-#endif
-    }
-
-    return rc;
-}
-
-/* Returns type of the password, default, pattern, pin or password.
- */
-int cryptfs_get_password_type(void)
-{
-    struct crypt_mnt_ftr crypt_ftr;
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key\n");
-        return -1;
-    }
-
-    if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) {
-        return -1;
-    }
-
-    return crypt_ftr.crypt_type;
-}
-
-int cryptfs_get_master_key(struct crypt_mnt_ftr* ftr, const char* password,
-                           unsigned char* master_key)
-{
-    int rc;
-
-    unsigned char* intermediate_key = 0;
-    size_t intermediate_key_size = 0;
-
-    if (password == 0 || *password == 0) {
-        password = DEFAULT_PASSWORD;
-    }
-
-    rc = decrypt_master_key(password, master_key, ftr, &intermediate_key,
-                            &intermediate_key_size);
-
-    if (rc) {
-        SLOGE("Can't calculate intermediate key");
-        return rc;
-    }
-
-    int N = 1 << ftr->N_factor;
-    int r = 1 << ftr->r_factor;
-    int p = 1 << ftr->p_factor;
-
-    unsigned char scrypted_intermediate_key[sizeof(ftr->scrypted_intermediate_key)];
-
-    rc = crypto_scrypt(intermediate_key, intermediate_key_size,
-                       ftr->salt, sizeof(ftr->salt), N, r, p,
-                       scrypted_intermediate_key,
-                       sizeof(scrypted_intermediate_key));
-
-    free(intermediate_key);
-
-    if (rc) {
-        SLOGE("Can't scrypt intermediate key");
-        return rc;
-    }
-
-    return memcmp(scrypted_intermediate_key, ftr->scrypted_intermediate_key,
-                  intermediate_key_size);
-}
-
diff --git a/crypto/fde/cryptfs.h b/crypto/fde/cryptfs.h
deleted file mode 100644
index c67113a..0000000
--- a/crypto/fde/cryptfs.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2010 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 ANDROID_VOLD_CRYPTFS_H
-#define ANDROID_VOLD_CRYPTFS_H
-
-/* This structure starts 16,384 bytes before the end of a hardware
- * partition that is encrypted, or in a separate partition.  It's location
- * is specified by a property set in init.<device>.rc.
- * The structure allocates 48 bytes for a key, but the real key size is
- * specified in the struct.  Currently, the code is hardcoded to use 128
- * bit keys.
- * The fields after salt are only valid in rev 1.1 and later stuctures.
- * Obviously, the filesystem does not include the last 16 kbytes
- * of the partition if the crypt_mnt_ftr lives at the end of the
- * partition.
- */
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <cutils/properties.h>
-
-/* The current cryptfs version */
-#define CURRENT_MAJOR_VERSION 1
-#define CURRENT_MINOR_VERSION 3
-
-#define CRYPT_FOOTER_OFFSET 0x4000
-#define CRYPT_FOOTER_TO_PERSIST_OFFSET 0x1000
-#define CRYPT_PERSIST_DATA_SIZE 0x1000
-
-#define MAX_CRYPTO_TYPE_NAME_LEN 64
-
-#define MAX_KEY_LEN 48
-#define SALT_LEN 16
-#define SCRYPT_LEN 32
-
-/* definitions of flags in the structure below */
-#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */
-#define CRYPT_ENCRYPTION_IN_PROGRESS 0x2 /* Encryption partially completed,
-                                            encrypted_upto valid*/
-#define CRYPT_INCONSISTENT_STATE 0x4 /* Set when starting encryption, clear when
-                                        exit cleanly, either through success or
-                                        correctly marked partial encryption */
-#define CRYPT_DATA_CORRUPT 0x8 /* Set when encryption is fine, but the
-                                  underlying volume is corrupt */
-#define CRYPT_FORCE_ENCRYPTION 0x10 /* Set when it is time to encrypt this
-                                       volume on boot. Everything in this
-                                       structure is set up correctly as
-                                       though device is encrypted except
-                                       that the master key is encrypted with the
-                                       default password. */
-#define CRYPT_FORCE_COMPLETE 0x20 /* Set when the above encryption cycle is
-                                     complete. On next cryptkeeper entry, match
-                                     the password. If it matches fix the master
-                                     key and remove this flag. */
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-/* This flag is used to transition from L->M upgrade. L release passed
- * a byte for every nible of user password while M release is passing
- * ascii value of user password.
- * Random flag value is chosen so that it does not conflict with other use cases
- */
-#define CRYPT_ASCII_PASSWORD_UPDATED 0x1000
-#endif
-
-/* Allowed values for type in the structure below */
-#define CRYPT_TYPE_PASSWORD 0 /* master_key is encrypted with a password
-                               * Must be zero to be compatible with pre-L
-                               * devices where type is always password.*/
-#define CRYPT_TYPE_DEFAULT  1 /* master_key is encrypted with default
-                               * password */
-#define CRYPT_TYPE_PATTERN  2 /* master_key is encrypted with a pattern */
-#define CRYPT_TYPE_PIN      3 /* master_key is encrypted with a pin */
-#define CRYPT_TYPE_MAX_TYPE 3 /* type cannot be larger than this value */
-
-#define CRYPT_MNT_MAGIC 0xD0B5B1C4
-#define PERSIST_DATA_MAGIC 0xE950CD44
-
-/* Key Derivation Function algorithms */
-#define KDF_PBKDF2 1
-#define KDF_SCRYPT 2
-/* Algorithms 3 & 4 deprecated before shipping outside of google, so removed */
-#define KDF_SCRYPT_KEYMASTER_UNPADDED 3
-#define KDF_SCRYPT_KEYMASTER_BADLY_PADDED 4
-#define KDF_SCRYPT_KEYMASTER 5
-
-/* Maximum allowed keymaster blob size. */
-#define KEYMASTER_BLOB_SIZE 2048
-
-/* __le32 and __le16 defined in system/extras/ext4_utils/ext4_utils.h */
-#define __le8  unsigned char
-
-#if !defined(SHA256_DIGEST_LENGTH)
-#define SHA256_DIGEST_LENGTH 32
-#endif
-
-struct crypt_mnt_ftr {
-  __le32 magic;         /* See above */
-  __le16 major_version;
-  __le16 minor_version;
-  __le32 ftr_size;      /* in bytes, not including key following */
-  __le32 flags;         /* See above */
-  __le32 keysize;       /* in bytes */
-  __le32 crypt_type;    /* how master_key is encrypted. Must be a
-                         * CRYPT_TYPE_XXX value */
-  __le64 fs_size;       /* Size of the encrypted fs, in 512 byte sectors */
-  __le32 failed_decrypt_count; /* count of # of failed attempts to decrypt and
-                                  mount, set to 0 on successful mount */
-  unsigned char crypto_type_name[MAX_CRYPTO_TYPE_NAME_LEN]; /* The type of encryption
-                                                               needed to decrypt this
-                                                               partition, null terminated */
-  __le32 spare2;        /* ignored */
-  unsigned char master_key[MAX_KEY_LEN]; /* The encrypted key for decrypting the filesystem */
-  unsigned char salt[SALT_LEN];   /* The salt used for this encryption */
-  __le64 persist_data_offset[2];  /* Absolute offset to both copies of crypt_persist_data
-                                   * on device with that info, either the footer of the
-                                   * real_blkdevice or the metadata partition. */
-
-  __le32 persist_data_size;       /* The number of bytes allocated to each copy of the
-                                   * persistent data table*/
-
-  __le8  kdf_type; /* The key derivation function used. */
-
-  /* scrypt parameters. See www.tarsnap.com/scrypt/scrypt.pdf */
-  __le8  N_factor; /* (1 << N) */
-  __le8  r_factor; /* (1 << r) */
-  __le8  p_factor; /* (1 << p) */
-  __le64 encrypted_upto; /* If we are in state CRYPT_ENCRYPTION_IN_PROGRESS and
-                            we have to stop (e.g. power low) this is the last
-                            encrypted 512 byte sector.*/
-  __le8  hash_first_block[SHA256_DIGEST_LENGTH]; /* When CRYPT_ENCRYPTION_IN_PROGRESS
-                                                    set, hash of first block, used
-                                                    to validate before continuing*/
-
-  /* key_master key, used to sign the derived key which is then used to generate
-   * the intermediate key
-   * This key should be used for no other purposes! We use this key to sign unpadded 
-   * data, which is acceptable but only if the key is not reused elsewhere. */
-  __le8 keymaster_blob[KEYMASTER_BLOB_SIZE];
-  __le32 keymaster_blob_size;
-
-  /* Store scrypt of salted intermediate key. When decryption fails, we can
-     check if this matches, and if it does, we know that the problem is with the
-     drive, and there is no point in asking the user for more passwords.
-
-     Note that if any part of this structure is corrupt, this will not match and
-     we will continue to believe the user entered the wrong password. In that
-     case the only solution is for the user to enter a password enough times to
-     force a wipe.
-
-     Note also that there is no need to worry about migration. If this data is
-     wrong, we simply won't recognise a right password, and will continue to
-     prompt. On the first password change, this value will be populated and
-     then we will be OK.
-   */
-  unsigned char scrypted_intermediate_key[SCRYPT_LEN];
-
-  /* sha of this structure with this element set to zero
-     Used when encrypting on reboot to validate structure before doing something
-     fatal
-   */
-  unsigned char sha256[SHA256_DIGEST_LENGTH];
-};
-
-#define DATA_MNT_POINT "/data"
-
-/* Return values for cryptfs_crypto_complete */
-#define CRYPTO_COMPLETE_NOT_ENCRYPTED  1
-#define CRYPTO_COMPLETE_ENCRYPTED      0
-#define CRYPTO_COMPLETE_BAD_METADATA  (-1)
-#define CRYPTO_COMPLETE_PARTIAL       (-2)
-#define CRYPTO_COMPLETE_INCONSISTENT  (-3)
-#define CRYPTO_COMPLETE_CORRUPT       (-4)
-
-/* Return values for cryptfs_enable_inplace*() */
-#define ENABLE_INPLACE_OK 0
-#define ENABLE_INPLACE_ERR_OTHER (-1)
-#define ENABLE_INPLACE_ERR_DEV (-2)  /* crypto_blkdev issue */
-
-typedef int (*kdf_func)(const char* passwd, const unsigned char* salt, unsigned char* ikey,
-                        void* params);
-
-int cryptfs_check_passwd(const char* pw);
-int cryptfs_verify_passwd(const char* pw);
-int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev, const unsigned char* key, int keysize, char* out_crypto_blkdev);
-int cryptfs_revert_ext_volume(const char* label);
-int cryptfs_get_password_type(void);
-
-uint32_t cryptfs_get_keysize();
-const char* cryptfs_get_crypto_name();
-
-void set_partition_data(const char* block_device, const char* key_location, const char* fs);
-int cryptfs_check_footer();
-int delete_crypto_blk_dev(const char *name);
-
-#endif /* ANDROID_VOLD_CRYPTFS_H */
diff --git a/crypto/fde/main.cpp b/crypto/fde/main.cpp
deleted file mode 100644
index 7051a6d..0000000
--- a/crypto/fde/main.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <linux/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <linux/dm-ioctl.h>
-#include <libgen.h>
-#include <stdlib.h>
-#include <sys/param.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <openssl/evp.h>
-#include <errno.h>
-#include <linux/kdev_t.h>
-#include <time.h>
-#include "cryptfs.h"
-#include "cutils/properties.h"
-#include "crypto_scrypt.h"
-
-void usage() {
-	printf("  Usage:\n");
-	printf("    twrpdec /path/to/userdata /path/to/metadata filesystem password\n");
-	printf("\n");
-	printf("  The metadata path is the path to the footer. If no metadata\n");
-	printf("  partition is present then use footer for this argument.\n");
-	printf("\n");
-	printf("  Example:\n");
-	printf("    twrpdec /dev/block/bootdevice/by-name/userdata footer ext4 0000\n");
-}
-
-int main(int argc, char **argv) {
-	if (argc != 5) {
-		usage();
-		return -1;
-	}
-	set_partition_data(argv[1], argv[2], argv[3]);
-	//int ret = cryptfs_check_passwd("30303030");
-	int ret = cryptfs_check_passwd(argv[4]);
-	return 0;
-}
diff --git a/crypto/fscrypt/Android.mk b/crypto/fscrypt/Android.mk
deleted file mode 100755
index d9fb6ef..0000000
--- a/crypto/fscrypt/Android.mk
+++ /dev/null
@@ -1,87 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-ifeq ($(TW_INCLUDE_CRYPTO), true)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libtwrpfscrypt
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Wno-unused-variable -Wno-sign-compare -Wno-unused-parameter -Wno-comment -Wno-missing-field-initializers \
-    -DHAVE_LIBKEYUTILS -std=gnu++2a -Wno-macro-redefined -Wno-unused-function -fpic
-LOCAL_SRC_FILES := FsCrypt.cpp Decrypt.cpp ScryptParameters.cpp fscrypt_policy.cpp Utils.cpp HashPassword.cpp \
-    KeyUtil.cpp Keymaster.cpp KeyStorage.cpp MetadataCrypt.cpp KeyBuffer.cpp \
-    Process.cpp EncryptInplace.cpp Weaver1.cpp cryptfs.cpp Checkpoint.cpp CryptoType.cpp VoldUtil.cpp
-LOCAL_SHARED_LIBRARIES := libselinux libc libc++ libext4_utils libbase libcrypto libcutils \
-libkeymaster_messages libhardware libprotobuf-cpp-lite libfscrypt android.hardware.confirmationui@1.0 \
-android.hardware.keymaster@3.0 libkeystore_binder libhidlbase libutils libbinder android.hardware.gatekeeper@1.0 \
-libfs_mgr android.hardware.keymaster@4.0 android.hardware.keymaster@4.1 libkeymaster4support libkeymaster4_1support \
-libf2fs_sparseblock libkeystore_parcelables libkeystore_aidl android.hardware.weaver@1.0 libkeyutils liblog libhwbinder \
-libchrome android.hardware.boot@1.0 libbootloader_message
-LOCAL_STATIC_LIBRARIES := libscrypt_static libvold_binder libc++fs
-LOCAL_C_INCLUDES := system/extras/ext4_utils \
-    system/extras/ext4_utils/include/ext4_utils \
-    external/scrypt/lib/crypto \
-    system/security/keystore/include \
-    hardware/libhardware/include/hardware \
-    system/security/softkeymaster/include/keymaster \
-    system/keymaster/include \
-    system/extras/libfscrypt/include \
-    system/core/fs_mgr/libfs_avb/include/ \
-    system/core/fs_mgr/include_fstab/ \
-    system/core/fs_mgr/include/ \
-    system/core/fs_mgr/libdm/include/ \
-    system/core/fs_mgr/liblp/include/ \
-    system/gsid/include/ \
-    system/core/init/ \
-    system/vold/model \
-    system/vold/ \
-    system/extras/f2fs_utils/ \
-    bootable/recovery/bootloader_message/include
-
-ifeq  ($(TW_USE_FSCRYPT_POLICY), 1)
-    LOCAL_CFLAGS += -DUSE_FSCRYPT_POLICY_V1
-else
-    LOCAL_CFLAGS += -DUSE_FSCRYPT_POLICY_V2
-endif
-
-ifneq ($(wildcard hardware/libhardware/include/hardware/keymaster0.h),)
-    LOCAL_CFLAGS += -DTW_CRYPTO_HAVE_KEYMASTERX
-    LOCAL_C_INCLUDES +=  external/boringssl/src/include
-endif
-
-LOCAL_REQUIRED_MODULES := keystore_auth keystore
-LOCAL_CLANG := true
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := fscryptpolicyget
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/bin
-LOCAL_C_INCLUDES += system/extras/libfscrypt/include
-LOCAL_SRC_FILES := fscryptpolicyget.cpp
-LOCAL_SHARED_LIBRARIES := libtwrpfscrypt
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := twrpfbe
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/bin
-LOCAL_SRC_FILES := main.cpp
-LOCAL_SHARED_LIBRARIES := libtwrpfscrypt
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := keystore_auth
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/bin
-LOCAL_SRC_FILES := keystore_auth.cpp
-LOCAL_SHARED_LIBRARIES := libc libkeystore_binder libutils libbinder liblog
-LOCAL_CFLAGS += -DUSE_SECURITY_NAMESPACE
-LOCAL_SHARED_LIBRARIES += libkeystore_aidl
-
-include $(BUILD_EXECUTABLE)
-
-endif
diff --git a/crypto/fscrypt/Checkpoint.cpp b/crypto/fscrypt/Checkpoint.cpp
deleted file mode 100644
index fac0d9f..0000000
--- a/crypto/fscrypt/Checkpoint.cpp
+++ /dev/null
@@ -1,744 +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 "Checkpoint"
-#include "Checkpoint.h"
-#include "VoldUtil.h"
-#include "VolumeManager.h"
-
-#include <fstream>
-#include <list>
-#include <memory>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/properties.h>
-#include <android-base/unique_fd.h>
-#include <android/hardware/boot/1.0/IBootControl.h>
-#include <cutils/android_reboot.h>
-#include <fcntl.h>
-#include <fs_mgr.h>
-#include <linux/fs.h>
-#include <mntent.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <unistd.h>
-
-using android::base::GetBoolProperty;
-using android::base::GetUintProperty;
-using android::base::SetProperty;
-using android::binder::Status;
-using android::fs_mgr::Fstab;
-using android::fs_mgr::ReadDefaultFstab;
-using android::fs_mgr::ReadFstabFromFile;
-using android::hardware::hidl_string;
-using android::hardware::boot::V1_0::BoolResult;
-using android::hardware::boot::V1_0::CommandResult;
-using android::hardware::boot::V1_0::IBootControl;
-using android::hardware::boot::V1_0::Slot;
-
-
-namespace {
-const std::string kMetadataCPFile = "/metadata/vold/checkpoint";
-
-android::binder::Status error(const std::string& msg) {
-    PLOG(ERROR) << msg;
-    return android::binder::Status::fromServiceSpecificError(errno, android::String8(msg.c_str()));
-}
-
-android::binder::Status error(int error, const std::string& msg) {
-    LOG(ERROR) << msg;
-    return android::binder::Status::fromServiceSpecificError(error, android::String8(msg.c_str()));
-}
-
-bool setBowState(std::string const& block_device, std::string const& state) {
-    std::string bow_device = fs_mgr_find_bow_device(block_device);
-    if (bow_device.empty()) return false;
-
-    if (!android::base::WriteStringToFile(state, bow_device + "/bow/state")) {
-        PLOG(ERROR) << "Failed to write to file " << bow_device + "/bow/state";
-        return false;
-    }
-
-    return true;
-}
-
-}  // namespace
-
-Status cp_supportsCheckpoint(bool& result) {
-    result = false;
-
-    for (const auto& entry : fstab_default) {
-        if (entry.fs_mgr_flags.checkpoint_blk || entry.fs_mgr_flags.checkpoint_fs) {
-            result = true;
-            return Status::ok();
-        }
-    }
-    return Status::ok();
-}
-
-Status cp_supportsBlockCheckpoint(bool& result) {
-    result = false;
-
-    for (const auto& entry : fstab_default) {
-        if (entry.fs_mgr_flags.checkpoint_blk) {
-            result = true;
-            return Status::ok();
-        }
-    }
-    return Status::ok();
-}
-
-Status cp_supportsFileCheckpoint(bool& result) {
-    result = false;
-
-    for (const auto& entry : fstab_default) {
-        if (entry.fs_mgr_flags.checkpoint_fs) {
-            result = true;
-            return Status::ok();
-        }
-    }
-    return Status::ok();
-}
-
-Status cp_startCheckpoint(int retry) {
-    bool result;
-    if (!cp_supportsCheckpoint(result).isOk() || !result)
-        return error(ENOTSUP, "Checkpoints not supported");
-
-    if (retry < -1) return error(EINVAL, "Retry count must be more than -1");
-    std::string content = std::to_string(retry + 1);
-    if (retry == -1) {
-        android::sp<IBootControl> module = IBootControl::getService();
-        if (module) {
-            std::string suffix;
-            auto cb = [&suffix](hidl_string s) { suffix = s; };
-            if (module->getSuffix(module->getCurrentSlot(), cb).isOk()) content += " " + suffix;
-        }
-    }
-    if (!android::base::WriteStringToFile(content, kMetadataCPFile))
-        return error("Failed to write checkpoint file");
-    return Status::ok();
-}
-
-namespace {
-
-volatile bool isCheckpointing = false;
-
-volatile bool needsCheckpointWasCalled = false;
-
-// Protects isCheckpointing, needsCheckpointWasCalled and code that makes decisions based on status
-// of isCheckpointing
-std::mutex isCheckpointingLock;
-}
-
-Status cp_commitChanges() {
-    std::lock_guard<std::mutex> lock(isCheckpointingLock);
-
-    if (!isCheckpointing) {
-        return Status::ok();
-    }
-    if (android::base::GetProperty("persist.vold.dont_commit_checkpoint", "0") == "1") {
-        LOG(WARNING)
-            << "NOT COMMITTING CHECKPOINT BECAUSE persist.vold.dont_commit_checkpoint IS 1";
-        return Status::ok();
-    }
-    // TWRP should not mark errors on slots
-    // android::sp<IBootControl> module = IBootControl::getService();
-    // if (module) {
-    //     CommandResult cr;
-    //     module->markBootSuccessful([&cr](CommandResult result) { cr = result; });
-    //     if (!cr.success)
-    //         return error(EINVAL, "Error marking booted successfully: " + std::string(cr.errMsg));
-    //     LOG(INFO) << "Marked slot as booted successfully.";
-    //     // Clears the warm reset flag for next reboot.
-    //     if (!SetProperty("ota.warm_reset", "0")) {
-    //         LOG(WARNING) << "Failed to reset the warm reset flag";
-    //     }
-    // }
-    // Must take action for list of mounted checkpointed things here
-    // To do this, we walk the list of mounted file systems.
-    // But we also need to get the matching fstab entries to see
-    // the original flags
-    std::string err_str;
-
-    Fstab mounts;
-    if (!ReadFstabFromFile("/proc/mounts", &mounts)) {
-        return error(EINVAL, "Failed to get /proc/mounts");
-    }
-
-    // Walk mounted file systems
-    for (const auto& mount_rec : mounts) {
-        const auto fstab_rec = GetEntryForMountPoint(&fstab_default, mount_rec.mount_point);
-        if (!fstab_rec) continue;
-
-        if (fstab_rec->fs_mgr_flags.checkpoint_fs) {
-            if (fstab_rec->fs_type == "f2fs") {
-                std::string options = mount_rec.fs_options + ",checkpoint=enable";
-                if (mount(mount_rec.blk_device.c_str(), mount_rec.mount_point.c_str(), "none",
-                          MS_REMOUNT | fstab_rec->flags, options.c_str())) {
-                    return error(EINVAL, "Failed to remount");
-                }
-            }
-        } else if (fstab_rec->fs_mgr_flags.checkpoint_blk) {
-            if (!setBowState(mount_rec.blk_device, "2"))
-                return error(EINVAL, "Failed to set bow state");
-        }
-    }
-    SetProperty("vold.checkpoint_committed", "1");
-    LOG(INFO) << "Checkpoint has been committed.";
-    isCheckpointing = false;
-    if (!android::base::RemoveFileIfExists(kMetadataCPFile, &err_str))
-        return error(err_str.c_str());
-
-    return Status::ok();
-}
-
-namespace {
-void abort_metadata_file() {
-    std::string oldContent, newContent;
-    int retry = 0;
-    struct stat st;
-    int result = stat(kMetadataCPFile.c_str(), &st);
-
-    // If the file doesn't exist, we aren't managing a checkpoint retry counter
-    if (result != 0) return;
-    if (!android::base::ReadFileToString(kMetadataCPFile, &oldContent)) {
-        PLOG(ERROR) << "Failed to read checkpoint file";
-        return;
-    }
-    std::string retryContent = oldContent.substr(0, oldContent.find_first_of(" "));
-
-    if (!android::base::ParseInt(retryContent, &retry)) {
-        PLOG(ERROR) << "Could not parse retry count";
-        return;
-    }
-    if (retry > 0) {
-        newContent = "0";
-        if (!android::base::WriteStringToFile(newContent, kMetadataCPFile))
-            PLOG(ERROR) << "Could not write checkpoint file";
-    }
-}
-}  // namespace
-
-void cp_abortChanges(const std::string& message, bool retry) {
-    if (!cp_needsCheckpoint()) return;
-    if (!retry) abort_metadata_file();
-    android_reboot(ANDROID_RB_RESTART2, 0, message.c_str());
-}
-
-bool cp_needsRollback() {
-    std::string content;
-    bool ret;
-
-    ret = android::base::ReadFileToString(kMetadataCPFile, &content);
-    if (ret) {
-        if (content == "0") return true;
-        if (content.substr(0, 3) == "-1 ") {
-            std::string oldSuffix = content.substr(3);
-            android::sp<IBootControl> module = IBootControl::getService();
-            std::string newSuffix;
-
-            if (module) {
-                auto cb = [&newSuffix](hidl_string s) { newSuffix = s; };
-                module->getSuffix(module->getCurrentSlot(), cb);
-                if (oldSuffix == newSuffix) return true;
-            }
-        }
-    }
-    return false;
-}
-
-bool cp_needsCheckpoint() {
-    std::lock_guard<std::mutex> lock(isCheckpointingLock);
-
-    // Make sure we only return true during boot. See b/138952436 for discussion
-    if (needsCheckpointWasCalled) return isCheckpointing;
-    needsCheckpointWasCalled = true;
-
-    bool ret;
-    std::string content;
-    android::sp<IBootControl> module = IBootControl::getService();
-
-    if (isCheckpointing) return isCheckpointing;
-
-    if (module && module->isSlotMarkedSuccessful(module->getCurrentSlot()) == BoolResult::FALSE) {
-        isCheckpointing = true;
-        return true;
-    }
-    ret = android::base::ReadFileToString(kMetadataCPFile, &content);
-    if (ret) {
-        ret = content != "0";
-        isCheckpointing = ret;
-        return ret;
-    }
-    return false;
-}
-
-bool cp_isCheckpointing() {
-    return isCheckpointing;
-}
-
-namespace {
-const std::string kSleepTimeProp = "ro.sys.cp_msleeptime";
-const uint32_t msleeptime_default = 1000;  // 1 s
-const uint32_t max_msleeptime = 3600000;   // 1 h
-
-const std::string kMinFreeBytesProp = "ro.sys.cp_min_free_bytes";
-const uint64_t min_free_bytes_default = 100 * (1 << 20);  // 100 MiB
-
-const std::string kCommitOnFullProp = "ro.sys.cp_commit_on_full";
-const bool commit_on_full_default = true;
-
-static void cp_healthDaemon(std::string mnt_pnt, std::string blk_device, bool is_fs_cp) {
-    struct statvfs data;
-    uint32_t msleeptime = GetUintProperty(kSleepTimeProp, msleeptime_default, max_msleeptime);
-    uint64_t min_free_bytes =
-        GetUintProperty(kMinFreeBytesProp, min_free_bytes_default, (uint64_t)-1);
-    bool commit_on_full = GetBoolProperty(kCommitOnFullProp, commit_on_full_default);
-
-    struct timespec req;
-    req.tv_sec = msleeptime / 1000;
-    msleeptime %= 1000;
-    req.tv_nsec = msleeptime * 1000000;
-    while (isCheckpointing) {
-        uint64_t free_bytes = 0;
-        if (is_fs_cp) {
-            statvfs(mnt_pnt.c_str(), &data);
-            free_bytes = ((uint64_t) data.f_bavail) * data.f_frsize;
-        } else {
-            std::string bow_device = fs_mgr_find_bow_device(blk_device);
-            if (!bow_device.empty()) {
-                std::string content;
-                if (android::base::ReadFileToString(bow_device + "/bow/free", &content)) {
-                    free_bytes = std::strtoull(content.c_str(), NULL, 10);
-                }
-            }
-        }
-        if (free_bytes < min_free_bytes) {
-            if (commit_on_full) {
-                LOG(INFO) << "Low space for checkpointing. Commiting changes";
-                cp_commitChanges();
-                break;
-            } else {
-                LOG(INFO) << "Low space for checkpointing. Rebooting";
-                cp_abortChanges("checkpoint,low_space", false);
-                break;
-            }
-        }
-        nanosleep(&req, NULL);
-    }
-}
-
-}  // namespace
-
-Status cp_prepareCheckpoint() {
-    // Log to notify CTS - see b/137924328 for context
-    LOG(INFO) << "cp_prepareCheckpoint called";
-    std::lock_guard<std::mutex> lock(isCheckpointingLock);
-    if (!isCheckpointing) {
-        return Status::ok();
-    }
-
-    Fstab mounts;
-    if (!ReadFstabFromFile("/proc/mounts", &mounts)) {
-        return error(EINVAL, "Failed to get /proc/mounts");
-    }
-
-    for (const auto& mount_rec : mounts) {
-        const auto fstab_rec = GetEntryForMountPoint(&fstab_default, mount_rec.mount_point);
-        if (!fstab_rec) continue;
-
-        if (fstab_rec->fs_mgr_flags.checkpoint_blk) {
-            android::base::unique_fd fd(
-                TEMP_FAILURE_RETRY(open(mount_rec.mount_point.c_str(), O_RDONLY | O_CLOEXEC)));
-            if (fd == -1) {
-                PLOG(ERROR) << "Failed to open mount point" << mount_rec.mount_point;
-                continue;
-            }
-
-            struct fstrim_range range = {};
-            range.len = ULLONG_MAX;
-            nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME);
-            if (ioctl(fd, FITRIM, &range)) {
-                PLOG(ERROR) << "Failed to trim " << mount_rec.mount_point;
-                continue;
-            }
-            nsecs_t time = systemTime(SYSTEM_TIME_BOOTTIME) - start;
-            LOG(INFO) << "Trimmed " << range.len << " bytes on " << mount_rec.mount_point << " in "
-                      << nanoseconds_to_milliseconds(time) << "ms for checkpoint";
-
-            setBowState(mount_rec.blk_device, "1");
-        }
-        if (fstab_rec->fs_mgr_flags.checkpoint_blk || fstab_rec->fs_mgr_flags.checkpoint_fs) {
-            std::thread(cp_healthDaemon, std::string(mount_rec.mount_point),
-                        std::string(mount_rec.blk_device),
-                        fstab_rec->fs_mgr_flags.checkpoint_fs == 1)
-                .detach();
-        }
-    }
-    return Status::ok();
-}
-
-namespace {
-const int kSectorSize = 512;
-
-typedef uint64_t sector_t;
-
-struct log_entry {
-    sector_t source;  // in sectors of size kSectorSize
-    sector_t dest;    // in sectors of size kSectorSize
-    uint32_t size;    // in bytes
-    uint32_t checksum;
-} __attribute__((packed));
-
-struct log_sector_v1_0 {
-    uint32_t magic;
-    uint16_t header_version;
-    uint16_t header_size;
-    uint32_t block_size;
-    uint32_t count;
-    uint32_t sequence;
-    uint64_t sector0;
-} __attribute__((packed));
-
-// MAGIC is BOW in ascii
-const int kMagic = 0x00574f42;
-// Partially restored MAGIC is WOB in ascii
-const int kPartialRestoreMagic = 0x00424f57;
-
-void crc32(const void* data, size_t n_bytes, uint32_t* crc) {
-    static uint32_t table[0x100] = {
-        0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
-        0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
-        0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
-        0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
-        0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
-        0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
-        0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
-        0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
-        0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
-        0xB6662D3D,
-
-        0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5,
-        0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
-        0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED,
-        0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
-        0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074,
-        0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC,
-        0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C,
-        0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
-        0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B,
-        0xC0BA6CAD,
-
-        0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
-        0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
-        0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D,
-        0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
-        0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4,
-        0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C,
-        0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C,
-        0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
-        0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B,
-        0x5BDEAE1D,
-
-        0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785,
-        0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
-        0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD,
-        0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
-        0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354,
-        0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
-        0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C,
-        0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
-        0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B,
-        0x2D02EF8D};
-
-    for (size_t i = 0; i < n_bytes; ++i) {
-        *crc ^= ((uint8_t*)data)[i];
-        *crc = table[(uint8_t)*crc] ^ *crc >> 8;
-    }
-}
-
-// A map of relocations.
-// The map must be initialized so that relocations[0] = 0
-// During restore, we replay the log records in reverse, copying from dest to
-// source
-// To validate, we must be able to read the 'dest' sectors as though they had
-// been copied but without actually copying. This map represents how the sectors
-// would have been moved. To read a sector s, find the index <= s and read
-// relocations[index] + s - index
-typedef std::map<sector_t, sector_t> Relocations;
-
-void relocate(Relocations& relocations, sector_t dest, sector_t source, int count) {
-    // Find first one we're equal to or greater than
-    auto s = --relocations.upper_bound(source);
-
-    // Take slice
-    Relocations slice;
-    slice[dest] = source - s->first + s->second;
-    ++s;
-
-    // Add rest of elements
-    for (; s != relocations.end() && s->first < source + count; ++s)
-        slice[dest - source + s->first] = s->second;
-
-    // Split range at end of dest
-    auto dest_end = --relocations.upper_bound(dest + count);
-    relocations[dest + count] = dest + count - dest_end->first + dest_end->second;
-
-    // Remove all elements in [dest, dest + count)
-    relocations.erase(relocations.lower_bound(dest), relocations.lower_bound(dest + count));
-
-    // Add new elements
-    relocations.insert(slice.begin(), slice.end());
-}
-
-// A map of sectors that have been written to.
-// The final entry must always be False.
-// When we restart the restore after an interruption, we must take care that
-// when we copy from dest to source, that the block we copy to was not
-// previously copied from.
-// i e. A->B C->A; If we replay this sequence, we end up copying C->B
-// We must save our partial result whenever we finish a page, or when we copy
-// to a location that was copied from earlier (our source is an earlier dest)
-typedef std::map<sector_t, bool> Used_Sectors;
-
-bool checkCollision(Used_Sectors& used_sectors, sector_t start, sector_t end) {
-    auto second_overlap = used_sectors.upper_bound(start);
-    auto first_overlap = --second_overlap;
-
-    if (first_overlap->second) {
-        return true;
-    } else if (second_overlap != used_sectors.end() && second_overlap->first < end) {
-        return true;
-    }
-    return false;
-}
-
-void markUsed(Used_Sectors& used_sectors, sector_t start, sector_t end) {
-    auto start_pos = used_sectors.insert_or_assign(start, true).first;
-    auto end_pos = used_sectors.insert_or_assign(end, false).first;
-
-    if (start_pos == used_sectors.begin() || !std::prev(start_pos)->second) {
-        start_pos++;
-    }
-    if (std::next(end_pos) != used_sectors.end() && !std::next(end_pos)->second) {
-        end_pos++;
-    }
-    if (start_pos->first < end_pos->first) {
-        used_sectors.erase(start_pos, end_pos);
-    }
-}
-
-// Restores the given log_entry's data from dest -> source
-// If that entry is a log sector, set the magic to kPartialRestoreMagic and flush.
-void restoreSector(int device_fd, Used_Sectors& used_sectors, std::vector<char>& ls_buffer,
-                   log_entry* le, std::vector<char>& buffer) {
-    log_sector_v1_0& ls = *reinterpret_cast<log_sector_v1_0*>(&ls_buffer[0]);
-    uint32_t index = le - ((log_entry*)&ls_buffer[ls.header_size]);
-    int count = (le->size - 1) / kSectorSize + 1;
-
-    if (checkCollision(used_sectors, le->source, le->source + count)) {
-        fsync(device_fd);
-        lseek64(device_fd, 0, SEEK_SET);
-        ls.count = index + 1;
-        ls.magic = kPartialRestoreMagic;
-        write(device_fd, &ls_buffer[0], ls.block_size);
-        fsync(device_fd);
-        used_sectors.clear();
-        used_sectors[0] = false;
-    }
-
-    markUsed(used_sectors, le->dest, le->dest + count);
-
-    if (index == 0 && ls.sequence != 0) {
-        log_sector_v1_0* next = reinterpret_cast<log_sector_v1_0*>(&buffer[0]);
-        if (next->magic == kMagic) {
-            next->magic = kPartialRestoreMagic;
-        }
-    }
-
-    lseek64(device_fd, le->source * kSectorSize, SEEK_SET);
-    write(device_fd, &buffer[0], le->size);
-
-    if (index == 0) {
-        fsync(device_fd);
-    }
-}
-
-// Read from the device
-// If we are validating, the read occurs as though the relocations had happened
-std::vector<char> relocatedRead(int device_fd, Relocations const& relocations, bool validating,
-                                sector_t sector, uint32_t size, uint32_t block_size) {
-    if (!validating) {
-        std::vector<char> buffer(size);
-        lseek64(device_fd, sector * kSectorSize, SEEK_SET);
-        read(device_fd, &buffer[0], size);
-        return buffer;
-    }
-
-    std::vector<char> buffer(size);
-    for (uint32_t i = 0; i < size; i += block_size, sector += block_size / kSectorSize) {
-        auto relocation = --relocations.upper_bound(sector);
-        lseek64(device_fd, (sector + relocation->second - relocation->first) * kSectorSize,
-                SEEK_SET);
-        read(device_fd, &buffer[i], block_size);
-    }
-
-    return buffer;
-}
-
-}  // namespace
-
-Status cp_restoreCheckpoint(const std::string& blockDevice, int restore_limit) {
-    bool validating = true;
-    std::string action = "Validating";
-    int restore_count = 0;
-
-    for (;;) {
-        Relocations relocations;
-        relocations[0] = 0;
-        Status status = Status::ok();
-
-        LOG(INFO) << action << " checkpoint on " << blockDevice;
-        android::base::unique_fd device_fd(open(blockDevice.c_str(), O_RDWR | O_CLOEXEC));
-        if (device_fd < 0) return error("Cannot open " + blockDevice);
-
-        log_sector_v1_0 original_ls;
-        read(device_fd, reinterpret_cast<char*>(&original_ls), sizeof(original_ls));
-        if (original_ls.magic == kPartialRestoreMagic) {
-            validating = false;
-            action = "Restoring";
-        } else if (original_ls.magic != kMagic) {
-            return error(EINVAL, "No magic");
-        }
-
-        LOG(INFO) << action << " " << original_ls.sequence << " log sectors";
-
-        for (int sequence = original_ls.sequence; sequence >= 0 && status.isOk(); sequence--) {
-            auto ls_buffer = relocatedRead(device_fd, relocations, validating, 0,
-                                           original_ls.block_size, original_ls.block_size);
-            log_sector_v1_0& ls = *reinterpret_cast<log_sector_v1_0*>(&ls_buffer[0]);
-
-            Used_Sectors used_sectors;
-            used_sectors[0] = false;
-
-            if (ls.magic != kMagic && (ls.magic != kPartialRestoreMagic || validating)) {
-                status = error(EINVAL, "No magic");
-                break;
-            }
-
-            if (ls.block_size != original_ls.block_size) {
-                status = error(EINVAL, "Block size mismatch");
-                break;
-            }
-
-            if ((int)ls.sequence != sequence) {
-                status = error(EINVAL, "Expecting log sector " + std::to_string(sequence) +
-                                           " but got " + std::to_string(ls.sequence));
-                break;
-            }
-
-            LOG(INFO) << action << " from log sector " << ls.sequence;
-            for (log_entry* le =
-                     reinterpret_cast<log_entry*>(&ls_buffer[ls.header_size]) + ls.count - 1;
-                 le >= reinterpret_cast<log_entry*>(&ls_buffer[ls.header_size]); --le) {
-                // This is very noisy - limit to DEBUG only
-                LOG(VERBOSE) << action << " " << le->size << " bytes from sector " << le->dest
-                             << " to " << le->source << " with checksum " << std::hex
-                             << le->checksum;
-
-                auto buffer = relocatedRead(device_fd, relocations, validating, le->dest, le->size,
-                                            ls.block_size);
-                uint32_t checksum = le->source / (ls.block_size / kSectorSize);
-                for (size_t i = 0; i < le->size; i += ls.block_size) {
-                    crc32(&buffer[i], ls.block_size, &checksum);
-                }
-
-                if (le->checksum && checksum != le->checksum) {
-                    status = error(EINVAL, "Checksums don't match");
-                    break;
-                }
-
-                if (validating) {
-                    relocate(relocations, le->source, le->dest, (le->size - 1) / kSectorSize + 1);
-                } else {
-                    restoreSector(device_fd, used_sectors, ls_buffer, le, buffer);
-                    restore_count++;
-                    if (restore_limit && restore_count >= restore_limit) {
-                        status = error(EAGAIN, "Hit the test limit");
-                        break;
-                    }
-                }
-            }
-        }
-
-        if (!status.isOk()) {
-            if (!validating) {
-                LOG(ERROR) << "Checkpoint restore failed even though checkpoint validation passed";
-                return status;
-            }
-
-            LOG(WARNING) << "Checkpoint validation failed - attempting to roll forward";
-            auto buffer = relocatedRead(device_fd, relocations, false, original_ls.sector0,
-                                        original_ls.block_size, original_ls.block_size);
-            lseek64(device_fd, 0, SEEK_SET);
-            write(device_fd, &buffer[0], original_ls.block_size);
-            return Status::ok();
-        }
-
-        if (!validating) break;
-
-        validating = false;
-        action = "Restoring";
-    }
-
-    return Status::ok();
-}
-
-Status cp_markBootAttempt() {
-    std::string oldContent, newContent;
-    int retry = 0;
-    struct stat st;
-    int result = stat(kMetadataCPFile.c_str(), &st);
-
-    // If the file doesn't exist, we aren't managing a checkpoint retry counter
-    if (result != 0) return Status::ok();
-    if (!android::base::ReadFileToString(kMetadataCPFile, &oldContent))
-        return error("Failed to read checkpoint file");
-    std::string retryContent = oldContent.substr(0, oldContent.find_first_of(" "));
-
-    if (!android::base::ParseInt(retryContent, &retry))
-        return error(EINVAL, "Could not parse retry count");
-    if (retry > 0) {
-        retry--;
-
-        newContent = std::to_string(retry);
-        if (!android::base::WriteStringToFile(newContent, kMetadataCPFile))
-            return error("Could not write checkpoint file");
-    }
-    return Status::ok();
-}
-
-void cp_resetCheckpoint() {
-    std::lock_guard<std::mutex> lock(isCheckpointingLock);
-    needsCheckpointWasCalled = false;
-}
diff --git a/crypto/fscrypt/Checkpoint.h b/crypto/fscrypt/Checkpoint.h
deleted file mode 100644
index cd17c78..0000000
--- a/crypto/fscrypt/Checkpoint.h
+++ /dev/null
@@ -1,50 +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 _CHECKPOINT_H
-#define _CHECKPOINT_H
-
-#include <binder/Status.h>
-#include <string>
-
-
-android::binder::Status cp_supportsCheckpoint(bool& result);
-
-android::binder::Status cp_supportsBlockCheckpoint(bool& result);
-
-android::binder::Status cp_supportsFileCheckpoint(bool& result);
-
-android::binder::Status cp_startCheckpoint(int retry);
-
-android::binder::Status cp_commitChanges();
-
-void cp_abortChanges(const std::string& message, bool retry);
-
-bool cp_needsRollback();
-
-bool cp_needsCheckpoint();
-
-bool cp_isCheckpointing();
-
-android::binder::Status cp_prepareCheckpoint();
-
-android::binder::Status cp_restoreCheckpoint(const std::string& mountPoint, int count = 0);
-
-android::binder::Status cp_markBootAttempt();
-
-void cp_resetCheckpoint();
-
-#endif
diff --git a/crypto/fscrypt/CryptoType.cpp b/crypto/fscrypt/CryptoType.cpp
deleted file mode 100644
index cf1ef42..0000000
--- a/crypto/fscrypt/CryptoType.cpp
+++ /dev/null
@@ -1,38 +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.
- */
-
-#include "CryptoType.h"
-
-#include <string.h>
-
-#include <android-base/logging.h>
-#include <cutils/properties.h>
-
-
-const CryptoType& lookup_crypto_algorithm(const CryptoType table[], int table_len,
-                                          const CryptoType& default_alg, const char* property) {
-    char paramstr[PROPERTY_VALUE_MAX];
-
-    property_get(property, paramstr, default_alg.get_config_name());
-    for (int i = 0; i < table_len; i++) {
-        if (strcmp(paramstr, table[i].get_config_name()) == 0) {
-            return table[i];
-        }
-    }
-    LOG(ERROR) << "Invalid name (" << paramstr << ") for " << property << ".  Defaulting to "
-               << default_alg.get_config_name() << ".";
-    return default_alg;
-}
diff --git a/crypto/fscrypt/CryptoType.h b/crypto/fscrypt/CryptoType.h
deleted file mode 100644
index 79ea93d..0000000
--- a/crypto/fscrypt/CryptoType.h
+++ /dev/null
@@ -1,98 +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.
- */
-
-#pragma once
-
-#include <stdlib.h>
-
-
-// Struct representing an encryption algorithm supported by vold.
-// "config_name" represents the name we give the algorithm in
-// read-only properties and fstab files
-// "kernel_name" is the name we present to the Linux kernel
-// "keysize" is the size of the key in bytes.
-struct CryptoType {
-    // We should only be constructing CryptoTypes as part of
-    // supported_crypto_types[].  We do it via this pseudo-builder pattern,
-    // which isn't pure or fully protected as a concession to being able to
-    // do it all at compile time.  Add new CryptoTypes in
-    // supported_crypto_types[] below.
-    constexpr CryptoType() : CryptoType(nullptr, nullptr, 0xFFFFFFFF) {}
-    constexpr CryptoType set_keysize(size_t size) const {
-        return CryptoType(this->config_name, this->kernel_name, size);
-    }
-    constexpr CryptoType set_config_name(const char* property) const {
-        return CryptoType(property, this->kernel_name, this->keysize);
-    }
-    constexpr CryptoType set_kernel_name(const char* crypto) const {
-        return CryptoType(this->config_name, crypto, this->keysize);
-    }
-
-    constexpr const char* get_config_name() const { return config_name; }
-    constexpr const char* get_kernel_name() const { return kernel_name; }
-    constexpr size_t get_keysize() const { return keysize; }
-
-  private:
-    const char* config_name;
-    const char* kernel_name;
-    size_t keysize;
-
-    constexpr CryptoType(const char* property, const char* crypto, size_t ksize)
-        : config_name(property), kernel_name(crypto), keysize(ksize) {}
-};
-
-// Use the named android property to look up a type from the table
-// If the property is not set or matches no table entry, return the default.
-const CryptoType& lookup_crypto_algorithm(const CryptoType table[], int table_len,
-                                          const CryptoType& default_alg, const char* property);
-
-// Some useful types
-
-constexpr CryptoType invalid_crypto_type = CryptoType();
-
-constexpr CryptoType aes_256_xts = CryptoType()
-                                           .set_config_name("aes-256-xts")
-                                           .set_kernel_name("aes-xts-plain64")
-                                           .set_keysize(64);
-
-constexpr CryptoType adiantum = CryptoType()
-                                        .set_config_name("adiantum")
-                                        .set_kernel_name("xchacha12,aes-adiantum-plain64")
-                                        .set_keysize(32);
-
-// Support compile-time validation of a crypto type table
-
-template <typename T, size_t N>
-constexpr size_t array_length(T (&)[N]) {
-    return N;
-}
-
-constexpr bool isValidCryptoType(size_t max_keylen, const CryptoType& crypto_type) {
-    return ((crypto_type.get_config_name() != nullptr) &&
-            (crypto_type.get_kernel_name() != nullptr) &&
-            (crypto_type.get_keysize() <= max_keylen));
-}
-
-// Confirms that all supported_crypto_types have a small enough keysize and
-// had both set_config_name() and set_kernel_name() called.
-// Note in C++11 that constexpr functions can only have a single line.
-// So our code is a bit convoluted (using recursion instead of a loop),
-// but it's asserting at compile time that all of our key lengths are valid.
-constexpr bool validateSupportedCryptoTypes(size_t max_keylen, const CryptoType types[],
-                                            size_t len) {
-    return len == 0 || (isValidCryptoType(max_keylen, types[len - 1]) &&
-                        validateSupportedCryptoTypes(max_keylen, types, len - 1));
-}
diff --git a/crypto/fscrypt/Decrypt.cpp b/crypto/fscrypt/Decrypt.cpp
deleted file mode 100755
index 0217358..0000000
--- a/crypto/fscrypt/Decrypt.cpp
+++ /dev/null
@@ -1,1220 +0,0 @@
-/*
- * Copyright (C) 2016 - 2020 The TeamWin Recovery 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 "Decrypt.h"
-#include "FsCrypt.h"
-#include <fscrypt/fscrypt.h>
-
-#include <map>
-#include <string>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#ifndef HAVE_LIBKEYUTILS
-#include "key_control.h"
-#else
-#include <keyutils.h>
-#endif
-#include "keystore_client.pb.h"
-#include "Weaver1.h"
-#include "cutils/properties.h"
-
-#include <openssl/sha.h>
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-
-#include <dirent.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-#include <fstream>
-#include <future>
-#include <algorithm>
-
-#include <android-base/file.h>
-#include <base/threading/platform_thread.h>
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <android/security/BnConfirmationPromptCallback.h>
-#include <android/security/keystore/IKeystoreService.h>
-#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
-
-#include <binder/IServiceManager.h>
-#include <binder/IPCThreadState.h>
-#include <hardware/hw_auth_token.h>
-
-#include <keystore/keystore.h>
-#include <keystore/keystore_client.h>
-#include <keystore/keystore_client_impl.h>
-#include <keystore/KeystoreResponse.h>
-#include <keystore/keystore_hidl_support.h>
-#include <keystore/keystore_promises.h>
-#include <keystore/keystore_return_types.h>
-#include <keystore/keymaster_types.h>
-#include <keymasterV4_1/Keymaster.h>
-#include <keystore/OperationResult.h>
-#include "keystore_client.pb.h"
-
-#include <keymasterV4_1/authorization_set.h>
-#include <keymasterV4_1/keymaster_utils.h>
-
-extern "C" {
-#include "crypto_scrypt.h"
-}
-
-#include "fscrypt_policy.h"
-#include "fscrypt-common.h"
-#include "HashPassword.h"
-#include "KeyStorage.h"
-#include "android/os/IVold.h"
-
-using android::security::keystore::IKeystoreService;
-using keystore::KeystoreResponsePromise;
-using keystore::OperationResultPromise;
-using android::security::keymaster::OperationResult;
-using android::hardware::keymaster::V4_1::support::blob2hidlVec;
-
-
-inline std::string hidlVec2String(const ::keystore::hidl_vec<uint8_t>& value) {
-    return std::string(reinterpret_cast<const std::string::value_type*>(&value[0]), value.size());
-}
-
-static bool lookup_ref_key_internal(std::map<userid_t, android::fscrypt::EncryptionPolicy> key_map, const uint8_t* policy, userid_t* user_id) {
-#ifdef USE_FSCRYPT_POLICY_V1
-	char policy_string_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-	char key_map_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-	bytes_to_hex(policy, FS_KEY_DESCRIPTOR_SIZE, policy_string_hex);
-#else
-	char policy_string_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
-	char key_map_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
-	bytes_to_hex(policy, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_string_hex);
-#endif
-
-    for (std::map<userid_t, android::fscrypt::EncryptionPolicy>::iterator it=key_map.begin(); it!=key_map.end(); ++it) {
-#ifdef USE_FSCRYPT_POLICY_V1
-		bytes_to_hex(reinterpret_cast<const uint8_t*>(&it->second.key_raw_ref[0]), FS_KEY_DESCRIPTOR_SIZE, key_map_hex);
-#else
-		bytes_to_hex(reinterpret_cast<const uint8_t*>(&it->second.key_raw_ref[0]), FSCRYPT_KEY_IDENTIFIER_SIZE, key_map_hex);
-#endif
-		std::string key_map_hex_string = std::string(key_map_hex);
-		if (key_map_hex_string == policy_string_hex) {
-            *user_id = it->first;
-            return true;
-        }
-    }
-    return false;
-}
-
-#ifdef USE_FSCRYPT_POLICY_V1
-extern "C" bool lookup_ref_key(fscrypt_policy_v1* fep, uint8_t* policy_type) {
-#else
-extern "C" bool lookup_ref_key(fscrypt_policy_v2* fep, uint8_t* policy_type) {
-#endif
-	userid_t user_id = 0;
-	std::string policy_type_string;
-
-#ifdef USE_FSCRYPT_POLICY_V1
-	char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-	bytes_to_hex(fep->master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE, policy_hex);
-	if (std::strncmp((const char*)fep->master_key_descriptor, de_key_raw_ref.c_str(), FS_KEY_DESCRIPTOR_SIZE) == 0) {
-		policy_type_string = SYSTEM_DE_FSCRYPT_POLICY;
-		memcpy(policy_type, policy_type_string.data(), policy_type_string.size());
-		return true;
-	}
-    if (!lookup_ref_key_internal(s_de_policies, fep->master_key_descriptor, &user_id)) {
-        if (!lookup_ref_key_internal(s_ce_policies, fep->master_key_descriptor, &user_id)) {
-            return false;
-		} else {
-			policy_type_string = USER_CE_FSCRYPT_POLICY + std::to_string(user_id);
-		}
-    } else {
-			policy_type_string = USER_DE_FSCRYPT_POLICY + std::to_string(user_id);
-	}
-#else
-	char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
-	bytes_to_hex(fep->master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
-	if (std::strncmp((const char*)fep->master_key_identifier, de_key_raw_ref.c_str(), FSCRYPT_KEY_IDENTIFIER_SIZE) == 0) {
-		policy_type_string = SYSTEM_DE_FSCRYPT_POLICY;
-		memcpy(policy_type, policy_type_string.data(), policy_type_string.size());
-		return true;
-	}
-    if (!lookup_ref_key_internal(s_de_policies, fep->master_key_identifier, &user_id)) {
-        if (!lookup_ref_key_internal(s_ce_policies, fep->master_key_identifier, &user_id)) {
-            return false;
-		} else {
-			policy_type_string = USER_CE_FSCRYPT_POLICY + std::to_string(user_id);
-		}
-    } else {
-			policy_type_string = USER_DE_FSCRYPT_POLICY + std::to_string(user_id);
-	}
-#endif
-
-	memcpy(policy_type, policy_type_string.data(), policy_type_string.size());
-	LOG(INFO) << "storing policy type: " << policy_type;
-    return true;
-}
-
-extern "C" bool lookup_ref_tar(const uint8_t* policy_type, uint8_t* policy) {
-	std::string policy_type_string = std::string((char *) policy_type);
-#ifdef USE_FSCRYPT_POLICY_V1
-	char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-	bytes_to_hex(policy_type, FS_KEY_DESCRIPTOR_SIZE, policy_hex);
-#else
-	char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
-	bytes_to_hex(policy_type, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
-#endif
-
-	userid_t user_id = atoi(policy_type_string.substr(3, 4).c_str());
-
-	// TODO Update version # and make magic strings
-#ifdef USE_FSCRYPT_POLICY_V1
-	if (policy_type_string.substr(0,1) != FSCRYPT_V1) {
-#else
-	if (policy_type_string.substr(0,1) != FSCRYPT_V2) {
-#endif
-        LOG(ERROR) << "Unexpected version:" << policy_type[0];
-        return false;
-    }
-
-	if (policy_type_string.substr(1, 2) == SYSTEM_DE_KEY) {
-        memcpy(policy, de_key_raw_ref.data(), de_key_raw_ref.size());
-        return true;
-    }
-
-    std::string raw_ref;
-
-	if (policy_type_string.substr(1, 1) == USER_DE_KEY) {
-        if (lookup_key_ref(s_de_policies, user_id, &raw_ref)) {
-            memcpy(policy, raw_ref.data(), raw_ref.size());
-        } else
-            return false;
-    } else if (policy_type_string.substr(1, 1) == USER_CE_KEY) {
-        if (lookup_key_ref(s_ce_policies, user_id, &raw_ref)) {
-            memcpy(policy, raw_ref.data(), raw_ref.size());
-        } else
-            return false;
-    } else {
-        LOG(ERROR) << "unknown policy type: " << policy_type;
-        return false;
-    }
-    return true;
-}
-
-bool Decrypt_DE() {
-	if (!fscrypt_initialize_systemwide_keys()) { // this deals with the overarching device encryption
-		printf("fscrypt_initialize_systemwide_keys returned fail\n");
-		return false;
-	}
-	if (!fscrypt_init_user0()) {
-		printf("fscrypt_init_user0 returned fail\n");
-		return false;
-	}
-	return true;
-}
-
-// Crappy functions for debugging, please ignore unless you need to debug
-// void output_hex(const std::string& in) {
-// 	const char *buf = in.data();
-// 	char hex[in.size() * 2 + 1];
-// 	unsigned int index;
-// 	for (index = 0; index < in.size(); index++)
-// 		sprintf(&hex[2 * index], "%02X", buf[index]);
-// 	printf("%s", hex);
-// }
-
-// void output_hex(const char* buf, const int size) {
-// 	char hex[size * 2 + 1];
-// 	int index;
-// 	for (index = 0; index < size; index++)
-// 		sprintf(&hex[2 * index], "%02X", buf[index]);
-// 	printf("%s", hex);
-// }
-
-// void output_hex(const unsigned char* buf, const int size) {
-// 	char hex[size * 2 + 1];
-// 	int index;
-// 	for (index = 0; index < size; index++)
-// 		sprintf(&hex[2 * index], "%02X", buf[index]);
-// 	printf("%s", hex);
-// }
-
-// void output_hex(std::vector<uint8_t>* vec) {
-// 	char hex[3];
-// 	unsigned int index;
-// 	for (index = 0; index < vec->size(); index++) {
-// 		sprintf(&hex[0], "%02X", vec->at(index));
-// 		printf("%s", hex);
-// 	}
-// }
-
-/* An alternative is to use:
- * sqlite3 /data/system/locksettings.db "SELECT value FROM locksettings WHERE name='sp-handle' AND user=0;"
- * but we really don't want to include the 1.1MB libsqlite in TWRP. We scan the spblob folder for the
- * password data file (*.pwd) and get the handle from the filename instead. This is a replacement for
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/LockSettingsService.java#2017
- * We never use this data as an actual long. We always use it as a string. */
-bool Find_Handle(const std::string& spblob_path, std::string& handle_str) {
-	DIR* dir = opendir(spblob_path.c_str());
-	if (!dir) {
-		printf("Error opening '%s'\n", spblob_path.c_str());
-		return false;
-	}
-
-	struct dirent* de = 0;
-
-	while ((de = readdir(dir)) != 0) {
-		if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
-			continue;
-		size_t len = strlen(de->d_name);
-		if (len <= 4)
-			continue;
-		char* p = de->d_name;
-		p += len - 4;
-		if (strncmp(p, ".pwd", 4) == 0) {
-			handle_str = de->d_name;
-			handle_str = handle_str.substr(0, len - 4);
-			//*handle = strtoull(handle_str.c_str(), 0 , 16);
-			closedir(dir);
-			return true;
-		}
-	}
-	closedir(dir);
-	return false;
-}
-
-/* This is the structure of the data in the password data (*.pwd) file which the structure can be found
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#187 */
-struct password_data_struct {
-	int password_type;
-	unsigned char scryptN;
-	unsigned char scryptR;
-	unsigned char scryptP;
-	int salt_len;
-	void* salt;
-	int handle_len;
-	void* password_handle;
-};
-
-/* C++ replacement for
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#764 */
-bool Get_Password_Data(const std::string& spblob_path, const std::string& handle_str, password_data_struct *pwd) {
-	std::string pwd_file = spblob_path + handle_str + ".pwd";
-	std::string pwd_data;
-	if (!android::base::ReadFileToString(pwd_file, &pwd_data)) {
-		printf("Failed to read '%s'\n", pwd_file.c_str());
-		return false;
-	}
-	// output_hex(pwd_data.data(), pwd_data.size());printf("\n");
-	const int* intptr = (const int*)pwd_data.data();
-	pwd->password_type = *intptr;
-	endianswap(&pwd->password_type);
-	//printf("password type %i\n", pwd->password_type); // 2 was PIN, 1 for pattern, 2 also for password, -1 for default password
-	const unsigned char* byteptr = (const unsigned char*)pwd_data.data() + sizeof(int);
-	pwd->scryptN = *byteptr;
-	byteptr++;
-	pwd->scryptR = *byteptr;
-	byteptr++;
-	pwd->scryptP = *byteptr;
-	byteptr++;
-	intptr = (const int*)byteptr;
-	pwd->salt_len = *intptr;
-	endianswap(&pwd->salt_len);
-	if (pwd->salt_len != 0) {
-		pwd->salt = malloc(pwd->salt_len);
-		if (!pwd->salt) {
-			printf("Get_Password_Data malloc salt\n");
-			return false;
-		}
-		memcpy(pwd->salt, intptr + 1, pwd->salt_len);
-		intptr++;
-		byteptr = (const unsigned char*)intptr;
-		byteptr += pwd->salt_len;
-	} else {
-		printf("Get_Password_Data salt_len is 0\n");
-		return false;
-	}
-	intptr = (const int*)byteptr;
-	pwd->handle_len = *intptr;
-	endianswap(&pwd->handle_len);
-	if (pwd->handle_len != 0) {
-		pwd->password_handle = malloc(pwd->handle_len);
-		if (!pwd->password_handle) {
-			printf("Get_Password_Data malloc password_handle\n");
-			return false;
-		}
-		memcpy(pwd->password_handle, intptr + 1, pwd->handle_len);
-	} else {
-		printf("Get_Password_Data handle_len is 0\n");
-		// Not an error if using weaver
-	}
-	return true;
-}
-
-/* C++ replacement for
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#765
- * called here
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#1050 */
-bool Get_Password_Token(const password_data_struct *pwd, const std::string& Password, unsigned char* password_token) {
-	if (!password_token) {
-		printf("password_token is null\n");
-		return false;
-	}
-	unsigned int N = 1 << pwd->scryptN;
-	unsigned int r = 1 << pwd->scryptR;
-	unsigned int p = 1 << pwd->scryptP;
-	//printf("N %i r %i p %i\n", N, r, p);
-	int ret = crypto_scrypt(reinterpret_cast<const uint8_t*>(Password.data()), Password.size(),
-                          reinterpret_cast<const uint8_t*>(pwd->salt), pwd->salt_len,
-                          N, r, p,
-                          password_token, 32);
-	if (ret != 0) {
-		printf("scrypt error\n");
-		return false;
-	}
-	return true;
-}
-
-// Data structure for the *.weaver file, see Get_Weaver_Data below
-struct weaver_data_struct {
-	unsigned char version;
-	int slot;
-};
-
-/* C++ replacement for
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#501
- * called here
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#768 */
-bool Get_Weaver_Data(const std::string& spblob_path, const std::string& handle_str, weaver_data_struct *wd) {
-	std::string weaver_file = spblob_path + handle_str + ".weaver";
-	std::string weaver_data;
-	if (!android::base::ReadFileToString(weaver_file, &weaver_data)) {
-		printf("Failed to read '%s'\n", weaver_file.c_str());
-		return false;
-	}
-	// output_hex(weaver_data.data(), weaver_data.size());printf("\n");
-	const unsigned char* byteptr = (const unsigned char*)weaver_data.data();
-	wd->version = *byteptr;
-	// printf("weaver version %i\n", wd->version);
-	const int* intptr = (const int*)weaver_data.data() + sizeof(unsigned char);
-	wd->slot = *intptr;
-	//endianswap(&wd->slot); not needed
-	// printf("weaver slot %i\n", wd->slot);
-	return true;
-}
-
-namespace android {
-
-// On Android 8.0 for some reason init can't seem to completely stop keystore
-// so we have to kill it too if it doesn't die on its own.
-static void kill_keystore() {
-    DIR* dir = opendir("/proc");
-    if (dir) {
-        struct dirent* de = 0;
-
-        while ((de = readdir(dir)) != 0) {
-            if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
-                continue;
-
-            int pid = -1;
-            int ret = sscanf(de->d_name, "%d", &pid);
-
-            if (ret == 1) {
-                char cmdpath[PATH_MAX];
-                sprintf(cmdpath, "/proc/%d/cmdline", pid);
-
-                FILE* file = fopen(cmdpath, "r");
-                size_t task_size = PATH_MAX;
-                char task[PATH_MAX];
-                char* p = task;
-                if (getline(&p, &task_size, file) > 0) {
-                    if (strstr(task, "keystore") != 0) {
-                        printf("keystore pid %d found, sending kill.\n", pid);
-                        kill(pid, SIGINT);
-                        usleep(5000);
-                        kill(pid, SIGKILL);
-                    }
-                }
-                fclose(file);
-            }
-        }
-        closedir(dir);
-    }
-}
-
-// The keystore holds a file open on /data so we have to stop / kill it
-// if we want to be able to unmount /data for things like formatting.
-static void stop_keystore() {
-    printf("Stopping keystore...\n");
-    property_set("ctl.stop", "keystore");
-    usleep(5000);
-    kill_keystore();
-}
-
-/* These next 2 functions try to get the keystore service 50 times because
- * the keystore is not always ready when TWRP boots */
-android::sp<IBinder> getKeystoreBinder() {
-	android::sp<IServiceManager> sm = android::defaultServiceManager();
-    return sm->getService(String16("android.security.keystore"));
-}
-
-android::sp<IBinder> getKeystoreBinderRetry() {
-	printf("Starting keystore...\n");
-    property_set("ctl.start", "keystore");
-	int retry_count = 50;
-	android::sp<IBinder> binder = getKeystoreBinder();
-	while (binder == NULL && retry_count) {
-		printf("Waiting for keystore service... %i\n", retry_count--);
-		sleep(1);
-		binder = getKeystoreBinder();
-	}
-	return binder;
-}
-
-namespace keystore {
-
-#define SYNTHETIC_PASSWORD_VERSION_V1 1
-#define SYNTHETIC_PASSWORD_VERSION_V2 2
-#define SYNTHETIC_PASSWORD_VERSION_V3 3
-#define SYNTHETIC_PASSWORD_PASSWORD_BASED 0
-#define SYNTHETIC_PASSWORD_KEY_PREFIX "USRSKEY_synthetic_password_"
-#define USR_PRIVATE_KEY_PREFIX "USRPKEY_synthetic_password_"
-
-static std::string mKey_Prefix;
-
-/* The keystore alias subid is sometimes the same as the handle, but not always.
- * In the case of handle 0c5303fd2010fe29, the alias subid used c5303fd2010fe29
- * without the leading 0. We could try to parse the data from a previous
- * keystore request, but I think this is an easier solution because there
- * is little to no documentation on the format of data we get back from
- * the keystore in this instance. We also want to copy everything to a temp
- * folder so that any key upgrades that might take place do not actually
- * upgrade the keys on the data partition. We rename all 1000 uid files to 0
- * to pass the keystore permission checks. */
-bool Find_Keystore_Alias_SubID_And_Prep_Files(const userid_t user_id, std::string& keystoreid, const std::string& handle_str) {
-	char path_c[PATH_MAX];
-	sprintf(path_c, "/data/misc/keystore/user_%d", user_id);
-	char user_dir[PATH_MAX];
-	sprintf(user_dir, "user_%d", user_id);
-	std::string source_path = "/data/misc/keystore/";
-	source_path += user_dir;
-	std::string handle_sub = handle_str;
-	while (handle_sub.substr(0,1) == "0") {
-		std::string temp = handle_sub.substr(1);
-		handle_sub = temp;
-	}
-	mKey_Prefix = "";
-
-	mkdir("/tmp/misc", 0755);
-	mkdir("/tmp/misc/keystore", 0755);
-	std::string destination_path = "/tmp/misc/keystore/";
-	destination_path += user_dir;
-	if (mkdir(destination_path.c_str(), 0755) && errno != EEXIST) {
-		printf("failed to mkdir '%s' %s\n", destination_path.c_str(), strerror(errno));
-		return false;
-	}
-	destination_path += "/";
-
-	DIR* dir = opendir(source_path.c_str());
-	if (!dir) {
-		printf("Error opening '%s'\n", source_path.c_str());
-		return false;
-	}
-	source_path += "/";
-
-	struct dirent* de = 0;
-	size_t prefix_len = strlen(SYNTHETIC_PASSWORD_KEY_PREFIX);
-	bool found_subid = false;
-	bool has_pkey = false; // PKEY has priority over SKEY
-
-	while ((de = readdir(dir)) != 0) {
-		if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
-			continue;
-		if (!found_subid) {
-			size_t len = strlen(de->d_name);
-			if (len <= prefix_len)
-				continue;
-			if (strstr(de->d_name, SYNTHETIC_PASSWORD_KEY_PREFIX) && !has_pkey)
-				mKey_Prefix = SYNTHETIC_PASSWORD_KEY_PREFIX;
-			else if (strstr(de->d_name, USR_PRIVATE_KEY_PREFIX)) {
-				mKey_Prefix = USR_PRIVATE_KEY_PREFIX;
-				has_pkey = true;
-			} else
-				continue;
-			if (strstr(de->d_name, handle_sub.c_str())) {
-				keystoreid = handle_sub;
-				printf("keystoreid matched handle_sub: '%s'\n", keystoreid.c_str());
-				found_subid = true;
-			} else {
-				std::string file = de->d_name;
-				std::size_t found = file.find_last_of("_");
-				if (found != std::string::npos) {
-					keystoreid = file.substr(found + 1);
-					// printf("possible keystoreid: '%s'\n", keystoreid.c_str());
-					//found_subid = true; // we'll keep going in hopes that we find a pkey or a match to the handle_sub
-				}
-			}
-		}
-		std::string src = source_path;
-		src += de->d_name;
-		std::ifstream srcif(src.c_str(), std::ios::binary);
-		std::string dst = destination_path;
-		dst += de->d_name;
-		std::size_t source_uid = dst.find("1000");
-		if (source_uid != std::string::npos)
-			dst.replace(source_uid, 4, "0");
-		std::ofstream dstof(dst.c_str(), std::ios::binary);
-		printf("copying '%s' to '%s'\n", src.c_str(), dst.c_str());
-		dstof << srcif.rdbuf();
-		srcif.close();
-		dstof.close();
-	}
-	closedir(dir);
-	if (!found_subid && !mKey_Prefix.empty() && !keystoreid.empty())
-		found_subid = true;
-	return found_subid;
-}
-
-/* C++ replacement for function of the same name
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#867
- * returning an empty string indicates an error */
-std::string unwrapSyntheticPasswordBlob(const std::string& spblob_path, const std::string& handle_str, const userid_t user_id,
-	const void* application_id, const size_t application_id_size, uint32_t auth_token_len) {
-	std::string disk_decryption_secret_key = "";
-
-	android::ProcessState::self()->startThreadPool();
-
-	std::string keystore_alias_subid;
-	// Can be stored in user 0, so check for both.
-	if (!Find_Keystore_Alias_SubID_And_Prep_Files(user_id, keystore_alias_subid, handle_str) &&
-		!Find_Keystore_Alias_SubID_And_Prep_Files(0, keystore_alias_subid, handle_str))
-	{
-		printf("failed to scan keystore alias subid and prep keystore files\n");
-		return disk_decryption_secret_key;
-	}
-
-	// First get the keystore service
-    android::sp<IBinder> binder = getKeystoreBinderRetry();
-	android::sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-
-	if (service == NULL) {
-		printf("error: could not connect to keystore service\n");
-		return disk_decryption_secret_key;
-	}
-
-	if (auth_token_len > 0) {
-		printf("Starting keystore_auth service...\n");
-		property_set("ctl.start", "keystore_auth");
-	}
-
-	// Read the data from the .spblob file per: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#869
-	std::string spblob_file = spblob_path + handle_str + ".spblob";
-	std::string spblob_data;
-	if (!android::base::ReadFileToString(spblob_file, &spblob_data)) {
-		printf("Failed to read '%s'\n", spblob_file.c_str());
-		return disk_decryption_secret_key;
-	}
-	unsigned char* byteptr = (unsigned char*)spblob_data.data();
-	if (*byteptr != SYNTHETIC_PASSWORD_VERSION_V2 && *byteptr != SYNTHETIC_PASSWORD_VERSION_V1
-			&& *byteptr != SYNTHETIC_PASSWORD_VERSION_V3) {
-		printf("Unsupported synthetic password version %i\n", *byteptr);
-		return disk_decryption_secret_key;
-	}
-	const unsigned char* synthetic_password_version = byteptr;
-	byteptr++;
-	if (*byteptr != SYNTHETIC_PASSWORD_PASSWORD_BASED) {
-		printf("spblob data is not SYNTHETIC_PASSWORD_PASSWORD_BASED\n");
-		return disk_decryption_secret_key;
-	}
-	byteptr++; // Now we're pointing to the blob data itself
-	if (*synthetic_password_version == SYNTHETIC_PASSWORD_VERSION_V2
-			|| *synthetic_password_version == SYNTHETIC_PASSWORD_VERSION_V3) {
-		printf("spblob v2 / v3\n");
-		/* Version 2 / 3 of the spblob is basically the same as version 1, but the order of getting the intermediate key and disk decryption key have been flip-flopped
-		 * as seen in https://android.googlesource.com/platform/frameworks/base/+/5025791ac6d1538224e19189397de8d71dcb1a12
-		 */
-		/* First decrypt call found in
-		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.1.0_r18/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#135
-		 * We will use https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
-		 * and https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
-		 * First we set some algorithm parameters as seen in two places:
-		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java#297
-		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java#216 */
-		// When using secdis (aka not weaver) you must supply an auth token to the keystore prior to the begin operation
-		if (auth_token_len > 0) {
-			/*::keystore::KeyStoreServiceReturnCode auth_result = service->addAuthToken(auth_token, auth_token_len);
-			if (!auth_result.isOk()) {
-				// The keystore checks the uid of the calling process and will return a permission denied on this operation for user 0
-				printf("keystore error adding auth token\n");
-				return disk_decryption_secret_key;
-			}*/
-			// The keystore refuses to allow the root user to supply auth tokens, so we write the auth token to a file earlier and
-			// run a separate service that runs user the system user to add the auth token. We wait for the auth token file to be
-			// deleted by the keymaster_auth service and check for a /auth_error file in case of errors. We quit after after a while if
-			// the /auth_token file never gets deleted.
-			int auth_wait_count = 20;
-			while (access("/auth_token", F_OK) == 0 && auth_wait_count-- > 0)
-				usleep(5000);
-			if (auth_wait_count == 0 || access("/auth_error", F_OK) == 0) {
-				printf("error during keymaster_auth service\n");
-				/* If you are getting this error, make sure that you have the keymaster_auth service defined in your init scripts, preferrably in init.recovery.{ro.hardware}.rc
-				 * service keystore_auth /system/bin/keystore_auth
-				 *     disabled
-				 *     oneshot
-				 *     user system
-				 *     group root
-				 *     seclabel u:r:recovery:s0
-				 *
-				 * And check dmesg for error codes regarding this service if needed. */
-				return disk_decryption_secret_key;
-			}
-		}
-		int32_t ret;
-		size_t maclen = 128;
-		unsigned char* iv = (unsigned char*)byteptr; // The IV is the first 12 bytes of the spblob
-		::keystore::hidl_vec<uint8_t> iv_hidlvec;
-		iv_hidlvec.setToExternal((unsigned char*)byteptr, 12);
-		// printf("iv: "); output_hex((const unsigned char*)iv, 12); printf("\n");
-		std::string keystore_alias = mKey_Prefix;
-		keystore_alias += keystore_alias_subid;
-		String16 keystore_alias16(keystore_alias.data(), keystore_alias.size());
-		int32_t error_code;
-		unsigned char* cipher_text = (unsigned char*)byteptr + 12; // The cipher text comes immediately after the IV
-		std::string cipher_text_str(byteptr, byteptr + spblob_data.size() - 14);
-
-		::keystore::hidl_vec<uint8_t> cipher_text_hidlvec;
-		::keystore::AuthorizationSetBuilder begin_params;
-
-        cipher_text_hidlvec.setToExternal(cipher_text, spblob_data.size() - 14 /* 1 each for version and SYNTHETIC_PASSWORD_PASSWORD_BASED and 12 for the iv */);
-		begin_params.Authorization(::keystore::TAG_ALGORITHM, ::keystore::Algorithm::AES);
-		begin_params.Authorization(::keystore::TAG_BLOCK_MODE, ::keystore::BlockMode::GCM);
-		begin_params.Padding(::keystore::PaddingMode::NONE);
-		begin_params.Authorization(::keystore::TAG_NONCE, iv_hidlvec);
-		begin_params.Authorization(::keystore::TAG_MAC_LENGTH, maclen);
-
-		::keystore::hidl_vec<uint8_t> entropy; // No entropy is needed for decrypt
-		entropy.resize(0);
-		android::security::keymaster::KeymasterArguments empty_params;
-		android::hardware::keymaster::V4_0::KeyPurpose decryptPurpose  = android::hardware::keymaster::V4_0::KeyPurpose::DECRYPT;
-		android::sp<android::IBinder> decryptAuthToken(new android::BBinder);
-
-		android::sp<OperationResultPromise> promise = new OperationResultPromise;
-		auto future = promise->get_future();
-		auto binder_result = service->begin(promise, decryptAuthToken, keystore_alias16, (int32_t)decryptPurpose, true,
-			android::security::keymaster::KeymasterArguments(begin_params.hidl_data()), 
-			entropy, -1, &error_code);
-	    if (!binder_result.isOk()) {
-        	printf("communication error while calling keystore\n");
-			return disk_decryption_secret_key;
-   		}
-		::keystore::KeyStoreNativeReturnCode rc(error_code);
-		if (!rc.isOk()) {
-			printf("Keystore begin returned: %u\n", error_code);
-        	return disk_decryption_secret_key;
-    	}
-		OperationResult result = future.get();
-		std::map<uint64_t, android::sp<android::IBinder>> active_operations_;
-		uint64_t next_virtual_handle_ = 1;
-		active_operations_[next_virtual_handle_] = result.token;
-
-		// The cipher.doFinal call triggers an update to the keystore followed by a finish https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#64
-		// See also https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java#208
-		future = {};
-		promise = new OperationResultPromise();
-	    future = promise->get_future();
-		binder_result = service->update(promise, active_operations_[next_virtual_handle_], empty_params, cipher_text_hidlvec, &error_code);
-		rc = ::keystore::KeyStoreNativeReturnCode(error_code);
-        if (!rc.isOk()) {
-            printf("Keystore update returned: %d\n", error_code);
-            return disk_decryption_secret_key;
-        }
-		result = future.get();
-        if (!result.resultCode.isOk()) {
-            printf("update failed: %d\n", error_code);
-            return disk_decryption_secret_key;
-        }
-
-		size_t keystore_result_size = result.data.size();
-		unsigned char* keystore_result = (unsigned char*)malloc(keystore_result_size);
-		if (!keystore_result) {
-			printf("malloc on keystore_result\n");
-			return disk_decryption_secret_key;
-		}
-		memcpy(keystore_result, &result.data[0], result.data.size());
-		future = {};
-		promise = new OperationResultPromise();
-		future = promise->get_future();
-
-		auto hidlSignature = blob2hidlVec("");
-		auto hidlInput = blob2hidlVec(disk_decryption_secret_key);
-		binder_result = service->finish(promise, active_operations_[next_virtual_handle_], empty_params, hidlInput, hidlSignature, ::keystore::hidl_vec<uint8_t>(), &error_code);
-		if (!binder_result.isOk()) {
-			printf("communication error while calling keystore\n");
-			free(keystore_result);
-			return disk_decryption_secret_key;
-		}
-		rc = ::keystore::KeyStoreNativeReturnCode(error_code);
-		if (!rc.isOk()) {
-			printf("Keystore finish returned: %d\n", error_code);
-			return disk_decryption_secret_key;
-		}
-		result = future.get();
-		if (!result.resultCode.isOk()) {
-			printf("finish failed: %d\n", error_code);
-			return disk_decryption_secret_key;
-		}
-		stop_keystore();
-		/* Now we do the second decrypt call as seen in:
-		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.1.0_r18/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#136
-		 */
-		const unsigned char* intermediate_iv = keystore_result;
-		// printf("intermediate_iv: "); output_hex((const unsigned char*)intermediate_iv, 12); printf("\n");
-		const unsigned char* intermediate_cipher_text = (const unsigned char*)keystore_result + 12; // The cipher text comes immediately after the IV
-		int cipher_size = keystore_result_size - 12;
-		// First we personalize as seen https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#102
-		void* personalized_application_id = PersonalizedHashBinary(PERSONALISATION_APPLICATION_ID, (const char*)application_id, application_id_size);
-		if (!personalized_application_id) {
-			return disk_decryption_secret_key;
-		}
-		// printf("personalized application id: "); output_hex((unsigned char*)personalized_application_id, SHA512_DIGEST_LENGTH); printf("\n");
-		// Now we'll decrypt using openssl AES/GCM/NoPadding
-		OpenSSL_add_all_ciphers();
-		int actual_size=0, final_size=0;
-		EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new();
-		const unsigned char* key = (const unsigned char*)personalized_application_id; // The key is the now personalized copy of the application ID
-		// printf("key: "); output_hex((const unsigned char*)key, 32); printf("\n");
-		EVP_DecryptInit(d_ctx, EVP_aes_256_gcm(), key, intermediate_iv);
-		unsigned char* secret_key = (unsigned char*)malloc(cipher_size);
-		if (!secret_key) {
-			printf("malloc failure on secret key\n");
-			return disk_decryption_secret_key;
-		}
-		EVP_DecryptUpdate(d_ctx, secret_key, &actual_size, intermediate_cipher_text, cipher_size);
-		unsigned char tag[AES_BLOCK_SIZE];
-		EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, tag);
-		EVP_DecryptFinal_ex(d_ctx, secret_key + actual_size, &final_size);
-		EVP_CIPHER_CTX_free(d_ctx);
-		free(personalized_application_id);
-		free(keystore_result);
-		int secret_key_real_size = actual_size - 16;
-		// printf("secret key:  "); output_hex((const unsigned char*)secret_key, secret_key_real_size); printf("\n");
-		// The payload data from the keystore update is further personalized at https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#153
-		// We now have the disk decryption key!
-		if (*synthetic_password_version == SYNTHETIC_PASSWORD_VERSION_V3) {
-			// V3 uses SP800 instead of SHA512
-			disk_decryption_secret_key = PersonalizedHashSP800(PERSONALIZATION_FBE_KEY, PERSONALISATION_CONTEXT, (const char*)secret_key, secret_key_real_size);
-		} else {
-			disk_decryption_secret_key = PersonalizedHash(PERSONALIZATION_FBE_KEY, (const char*)secret_key, secret_key_real_size);
-		}
-		// printf("disk_decryption_secret_key: '%s'\n", disk_decryption_secret_key.c_str());
-		free(secret_key);
-		return disk_decryption_secret_key;
-	}
-	return disk_decryption_secret_key;
-}
-
-}}
-
-#define PASSWORD_TOKEN_SIZE 32
-
-/* C++ replacement for
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#992
- * called here
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#813 */
-bool Get_Secdis(const std::string& spblob_path, const std::string& handle_str, std::string& secdis_data) {
-	std::string secdis_file = spblob_path + handle_str + ".secdis";
-	if (!android::base::ReadFileToString(secdis_file, &secdis_data)) {
-		printf("Failed to read '%s'\n", secdis_file.c_str());
-		return false;
-	}
-	// output_hex(secdis_data.data(), secdis_data.size());printf("\n");
-	return true;
-}
-
-// C++ replacement for https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#1033
-userid_t fakeUid(const userid_t uid) {
-    return 100000 + uid;
-}
-
-bool Is_Weaver(const std::string& spblob_path, const std::string& handle_str) {
-	std::string weaver_file = spblob_path + handle_str + ".weaver";
-	struct stat st;
-	if (stat(weaver_file.c_str(), &st) == 0)
-		return true;
-	return false;
-}
-
-bool Free_Return(bool retval, void* weaver_key, password_data_struct* pwd) {
-	if (weaver_key)
-		free(weaver_key);
-	if (pwd->salt)
-		free(pwd->salt);
-	if (pwd->password_handle)
-		free(pwd->password_handle);
-	return retval;
-}
-
-/* Decrypt_User_Synth_Pass is the TWRP C++ equivalent to spBasedDoVerifyCredential
- * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/LockSettingsService.java#1998 */
-bool Decrypt_User_Synth_Pass(const userid_t user_id, const std::string& Password) {
-	bool retval = false;
-	void* weaver_key = NULL;
-	password_data_struct pwd;
-	pwd.salt = NULL;
-	pwd.salt_len = 0;
-	pwd.password_handle = NULL;
-	pwd.handle_len = 0;
-	char application_id[PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH];
-
-    uint32_t auth_token_len = 0;
-
-	std::string secret; // this will be the disk decryption key that is sent to vold
-	std::string token = "!"; // there is no token used for this kind of decrypt, key escrow is handled by weaver
-	int flags = android::os::IVold::STORAGE_FLAG_CE;
-	char spblob_path_char[PATH_MAX];
-	sprintf(spblob_path_char, "/data/system_de/%d/spblob/", user_id);
-	std::string spblob_path = spblob_path_char;
-	long handle = 0;
-	std::string handle_str;
-	// Get the handle: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/LockSettingsService.java#2017
-	if (!Find_Handle(spblob_path, handle_str)) {
-		printf("Error getting handle\n");
-		return Free_Return(retval, weaver_key, &pwd);
-	}
-	// printf("Handle is '%s'\n", handle_str.c_str());
-	// Now we begin driving unwrapPasswordBasedSyntheticPassword from: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#758
-	// First we read the password data which contains scrypt parameters
-	if (!Get_Password_Data(spblob_path, handle_str, &pwd)) {
-		printf("Failed to Get_Password_Data\n");
-		return Free_Return(retval, weaver_key, &pwd);
-	}
-	// printf("pwd N %i R %i P %i salt ", pwd.scryptN, pwd.scryptR, pwd.scryptP); output_hex((char*)pwd.salt, pwd.salt_len); printf("\n");
-	unsigned char password_token[PASSWORD_TOKEN_SIZE];
-	// printf("Password: '%s'\n", Password.c_str());
-	// The password token is the password scrypted with the parameters from the password data file
-	if (!Get_Password_Token(&pwd, Password, &password_token[0])) {
-		printf("Failed to Get_Password_Token\n");
-		return Free_Return(retval, weaver_key, &pwd);
-	}
-	// output_hex(&password_token[0], PASSWORD_TOKEN_SIZE);printf("\n");
-	if (Is_Weaver(spblob_path, handle_str)) {
-		printf("using weaver\n");
-		// BEGIN PIXEL 2 WEAVER
-		// Get the weaver data from the .weaver file which tells us which slot to use when we ask weaver for the escrowed key
-		// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#768
-		weaver_data_struct wd;
-		if (!Get_Weaver_Data(spblob_path, handle_str, &wd)) {
-			printf("Failed to get weaver data\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		}
-		// The weaver key is the the password token prefixed with "weaver-key" padded to 128 with nulls with the password token appended then SHA512
-		// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#1059
-		weaver_key = PersonalizedHashBinary(PERSONALISATION_WEAVER_KEY, (char*)&password_token[0], PASSWORD_TOKEN_SIZE);
-		if (!weaver_key) {
-			printf("malloc error getting weaver_key\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		}
-		// Now we start driving weaverVerify: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#343
-		// Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#776
-		android::vold::Weaver weaver;
-		if (!weaver) {
-			printf("Failed to get weaver service\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		}
-		// Get the key size from weaver service
-		uint32_t weaver_key_size = 0;
-		if (!weaver.GetKeySize(&weaver_key_size)) {
-			printf("Failed to get weaver key size\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		} else {
-			printf("weaver key size is %u\n", weaver_key_size);
-		}
-		// printf("weaver key: "); output_hex((unsigned char*)weaver_key, weaver_key_size); printf("\n");
-		// Send the slot from the .weaver file, the computed weaver key, and get the escrowed key data
-		std::vector<uint8_t> weaver_payload;
-		// TODO: we should return more information about the status including time delays before the next retry
-		if (!weaver.WeaverVerify(wd.slot, weaver_key, &weaver_payload)) {
-			printf("failed to weaver verify\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		}
-		// printf("weaver payload: "); output_hex(&weaver_payload); printf("\n");
-		// Done with weaverVerify
-		// Now we will compute the application ID
-		// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#964
-		// Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#780
-		// The escrowed weaver key data is prefixed with "weaver-pwd" padded to 128 with nulls with the weaver payload appended then SHA512
-		void* weaver_secret = PersonalizedHashBinary(PERSONALISATION_WEAVER_PASSWORD, (const char*)weaver_payload.data(), weaver_payload.size());
-		// printf("weaver secret: "); output_hex((unsigned char*)weaver_secret, SHA512_DIGEST_LENGTH); printf("\n");
-		// The application ID is the password token and weaver secret appended to each other
-		memcpy((void*)&application_id[0], (void*)&password_token[0], PASSWORD_TOKEN_SIZE);
-		memcpy((void*)&application_id[PASSWORD_TOKEN_SIZE], weaver_secret, SHA512_DIGEST_LENGTH);
-		// printf("application ID: "); output_hex((unsigned char*)application_id, PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH); printf("\n");
-		// END PIXEL 2 WEAVER
-	} else {
-		printf("using secdis\n");
-		std::string secdis_data;
-		if (!Get_Secdis(spblob_path, handle_str, secdis_data)) {
-			printf("Failed to get secdis data\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		}
-		void* secdiscardable = PersonalizedHashBinary(PERSONALISATION_SECDISCARDABLE, (char*)secdis_data.data(), secdis_data.size());
-		if (!secdiscardable) {
-			printf("malloc error getting secdiscardable\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		}
-		memcpy((void*)&application_id[0], (void*)&password_token[0], PASSWORD_TOKEN_SIZE);
-		memcpy((void*)&application_id[PASSWORD_TOKEN_SIZE], secdiscardable, SHA512_DIGEST_LENGTH);
-
-		int ret = -1;
-		bool request_reenroll = false;
-		android::sp<android::hardware::gatekeeper::V1_0::IGatekeeper> gk_device;
-		gk_device = ::android::hardware::gatekeeper::V1_0::IGatekeeper::getService();
-		if (gk_device == nullptr) {
-			printf("failed to get gatekeeper service\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		}
-		if (pwd.handle_len <= 0) {
-			printf("no password handle supplied\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		}
-		android::hardware::hidl_vec<uint8_t> pwd_handle_hidl;
-		pwd_handle_hidl.setToExternal(const_cast<uint8_t *>((const uint8_t *)pwd.password_handle), pwd.handle_len);
-		void* gk_pwd_token = PersonalizedHashBinary(PERSONALIZATION_USER_GK_AUTH, (char*)&password_token[0], PASSWORD_TOKEN_SIZE);
-		if (!gk_pwd_token) {
-			printf("malloc error getting gatekeeper_key\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		}
-		android::hardware::hidl_vec<uint8_t> gk_pwd_token_hidl;
-		gk_pwd_token_hidl.setToExternal(const_cast<uint8_t *>((const uint8_t *)gk_pwd_token), SHA512_DIGEST_LENGTH);
-		android::hardware::Return<void> hwRet =
-			gk_device->verify(fakeUid(user_id), 0 /* challange */,
-							  pwd_handle_hidl,
-							  gk_pwd_token_hidl,
-							  [&ret, &request_reenroll, &auth_token_len]
-								(const android::hardware::gatekeeper::V1_0::GatekeeperResponse &rsp) {
-									ret = static_cast<int>(rsp.code); // propagate errors
-									if (rsp.code >= android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::STATUS_OK) {
-										auth_token_len = rsp.data.size();
-										request_reenroll = (rsp.code == android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::STATUS_REENROLL);
-										ret = 0; // all success states are reported as 0
-										// The keystore refuses to allow the root user to supply auth tokens, so we write the auth token to a file here and later
-										// run a separate service that runs as the system user to add the auth token. We wait for the auth token file to be
-										// deleted by the keymaster_auth service and check for a /auth_error file in case of errors. We quit after a while seconds if
-										// the /auth_token file never gets deleted.
-										unlink("/auth_token");
-										FILE* auth_file = fopen("/auth_token","wb");
-										if (auth_file != NULL) {
-											fwrite(rsp.data.data(), sizeof(uint8_t), rsp.data.size(), auth_file);
-											fclose(auth_file);
-										} else {
-											printf("failed to open /auth_token for writing\n");
-											ret = -2;
-										}
-									} else if (rsp.code == android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::ERROR_RETRY_TIMEOUT && rsp.timeout > 0) {
-										ret = rsp.timeout;
-									}
-								}
-							 );
-		free(gk_pwd_token);
-		if (!hwRet.isOk() || ret != 0) {
-			printf("gatekeeper verification failed\n");
-			return Free_Return(retval, weaver_key, &pwd);
-		}
-	}
-	// Now we will handle https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#816
-	// Plus we will include the last bit that computes the disk decrypt key found in:
-	// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#153
-	secret = android::keystore::unwrapSyntheticPasswordBlob(spblob_path, handle_str, user_id, (const void*)&application_id[0], 
-		PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH, auth_token_len);
-	if (!secret.size()) {
-		printf("failed to unwrapSyntheticPasswordBlob\n");
-		return Free_Return(retval, weaver_key, &pwd);
-	}
-
-	if (!fscrypt_unlock_user_key(user_id, 0, token.c_str(), secret.c_str())) {
-		printf("fscrypt_unlock_user_key returned fail\n");
-		return Free_Return(retval, weaver_key, &pwd);
-	}
-
-	if (!fscrypt_prepare_user_storage("", user_id, 0, flags)) {
-		printf("failed to fscrypt_prepare_user_storage\n");
-		return Free_Return(retval, weaver_key, &pwd);
-	}
-	printf("User %i Decrypted Successfully!\n", user_id);
-	retval = true;
-	return Free_Return(retval, weaver_key, &pwd);
-}
-
-int Get_Password_Type(const userid_t user_id, std::string& filename) {
-	struct stat st;
-	char spblob_path_char[PATH_MAX];
-	sprintf(spblob_path_char, "/data/system_de/%d/spblob/", user_id);
-	if (stat(spblob_path_char, &st) == 0) {
-		printf("Using synthetic password method\n");
-		std::string spblob_path = spblob_path_char;
-		std::string handle_str;
-		if (!Find_Handle(spblob_path, handle_str)) {
-			printf("Error getting handle\n");
-			return 0;
-		}
-		printf("Handle is '%s'\n", handle_str.c_str());
-		password_data_struct pwd;
-		if (!Get_Password_Data(spblob_path, handle_str, &pwd)) {
-			printf("Failed to Get_Password_Data\n");
-			return 0;
-		}
-		// In Android type 1 is pattern
-		// In Android <11 type 2 is PIN or password
-		// In Android 11+ type 3 is PIN and type 4 is password
-		if (pwd.password_type == 2) {
-			printf("password type: password/PIN\n");
-			return 1; // In TWRP this means password or PIN (Android <11)
-		} else if (pwd.password_type == 4) {
-			printf("password type: password\n");
-			return 1; // In TWRP this means password
-		} else if (pwd.password_type == 1) {
-			printf("password type: pattern\n");
-			return 2; // In TWRP this means pattern
-		} else if (pwd.password_type == 3) {
-			printf("password type: PIN\n");
-			return 3; // In TWRP this means PIN
-		}
-		printf("using default password\n");
-		return 0; // We'll try the default password
-	}
-	std::string path;
-    if (user_id == 0) {
-		path = "/data/system/";
-	} else {
-		char user_id_str[5];
-		sprintf(user_id_str, "%i", user_id);
-		path = "/data/system/users/";
-		path += user_id_str;
-		path += "/";
-	}
-	filename = path + "gatekeeper.password.key";
-	if (stat(filename.c_str(), &st) == 0 && st.st_size > 0)
-		return 1;
-	filename = path + "gatekeeper.pattern.key";
-	if (stat(filename.c_str(), &st) == 0 && st.st_size > 0)
-		return 2;
-	printf("Unable to locate gatekeeper password file '%s'\n", filename.c_str());
-	filename = "";
-	return 0;
-}
-
-bool Decrypt_User(const userid_t user_id, const std::string& Password) {
-    uint8_t *auth_token;
-    uint32_t auth_token_len;
-    int ret;
-
-    struct stat st;
-    if (user_id > 9999) {
-		printf("user_id is too big\n");
-		return false;
-	}
-    std::string filename;
-    bool Default_Password = (Password == "!");
-    if (Get_Password_Type(user_id, filename) == 0 && !Default_Password) {
-		printf("Unknown password type\n");
-		return false;
-	}
-
-	int flags = android::os::IVold::STORAGE_FLAG_CE;
-
-	if (Default_Password) {
-		if (!fscrypt_unlock_user_key(user_id, 0, "!", "!")) {
-			printf("unlock_user_key returned fail\n");
-			return false;
-		}
-		if (!fscrypt_prepare_user_storage("", user_id, 0, flags)) {
-			printf("failed to fscrypt_prepare_user_storage\n");
-			return false;
-		}
-		printf("User %i Decrypted Successfully!\n", user_id);
-		return true;
-	}
-	if (stat("/data/system_de/0/spblob", &st) == 0) {
-		printf("Using synthetic password method\n");
-		return Decrypt_User_Synth_Pass(user_id, Password);
-	}
-	// printf("password filename is '%s'\n", filename.c_str());
-	if (stat(filename.c_str(), &st) != 0) {
-		printf("error stat'ing key file: %s\n", strerror(errno));
-		return false;
-	}
-	std::string handle;
-    if (!android::base::ReadFileToString(filename, &handle)) {
-		printf("Failed to read '%s'\n", filename.c_str());
-		return false;
-	}
-    bool should_reenroll;
-	bool request_reenroll = false;
-	android::sp<android::hardware::gatekeeper::V1_0::IGatekeeper> gk_device;
-	gk_device = ::android::hardware::gatekeeper::V1_0::IGatekeeper::getService();
-	if (gk_device == nullptr)
-		return false;
-	android::hardware::hidl_vec<uint8_t> curPwdHandle;
-	curPwdHandle.setToExternal(const_cast<uint8_t *>((const uint8_t *)handle.c_str()), st.st_size);
-	android::hardware::hidl_vec<uint8_t> enteredPwd;
-	enteredPwd.setToExternal(const_cast<uint8_t *>((const uint8_t *)Password.c_str()), Password.size());
-
-	android::hardware::Return<void> hwRet =
-		gk_device->verify(user_id, 0 /* challange */,
-						  curPwdHandle,
-						  enteredPwd,
-						  [&ret, &request_reenroll, &auth_token, &auth_token_len]
-							(const android::hardware::gatekeeper::V1_0::GatekeeperResponse &rsp) {
-								ret = static_cast<int>(rsp.code); // propagate errors
-								if (rsp.code >= android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::STATUS_OK) {
-									auth_token = new uint8_t[rsp.data.size()];
-									auth_token_len = rsp.data.size();
-									memcpy(auth_token, rsp.data.data(), auth_token_len);
-									request_reenroll = (rsp.code == android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::STATUS_REENROLL);
-									ret = 0; // all success states are reported as 0
-								} else if (rsp.code == android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::ERROR_RETRY_TIMEOUT && rsp.timeout > 0) {
-									ret = rsp.timeout;
-								}
-							}
-						 );
-	if (!hwRet.isOk()) {
-		return false;
-	}
-
-	char token_hex[(auth_token_len*2)+1];
-	token_hex[(auth_token_len*2)] = 0;
-	uint32_t i;
-	for (i=0;i<auth_token_len;i++) {
-		sprintf(&token_hex[2*i], "%02X", auth_token[i]);
-	}
-	// The secret is "Android FBE credential hash" plus appended 0x00 to reach 128 bytes then append the user's password then feed that to sha512sum
-	std::string secret = HashPassword(Password);
-	if (!fscrypt_unlock_user_key(user_id, 0, token_hex, secret.c_str())) {
-		printf("fscrypt_unlock_user_key returned fail\n");
-		return false;
-	}
-
-	if (!fscrypt_prepare_user_storage("", user_id, 0, flags)) {
-		printf("failed to fscrypt_prepare_user_storage\n");
-		return false;
-	}
-	printf("User %i Decrypted Successfully!\n", user_id);
-	return true;
-}
diff --git a/crypto/fscrypt/Decrypt.h b/crypto/fscrypt/Decrypt.h
deleted file mode 100755
index f397749..0000000
--- a/crypto/fscrypt/Decrypt.h
+++ /dev/null
@@ -1,37 +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 <stdbool.h>
-#include <sys/cdefs.h>
-
-#include <cutils/multiuser.h>
-
-#include <string>
-
-__BEGIN_DECLS
-
-// NOTE: keep in sync with StorageManager
-static constexpr int FLAG_STORAGE_DE = 1 << 0;
-static constexpr int FLAG_STORAGE_CE = 1 << 1;
-// For 9.0 Ext4CryptPie.cpp
-static constexpr int STORAGE_FLAG_DE = 1;
-static constexpr int STORAGE_FLAG_CE = 2;
-
-
-int Get_Password_Type(const userid_t user_id, std::string& filename);
-bool Decrypt_DE();
-bool Decrypt_User(const userid_t user_id, const std::string& Password);
-__END_DECLS
diff --git a/crypto/fscrypt/EncryptInplace.cpp b/crypto/fscrypt/EncryptInplace.cpp
deleted file mode 100644
index 9d304da..0000000
--- a/crypto/fscrypt/EncryptInplace.cpp
+++ /dev/null
@@ -1,630 +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.
- */
-
-#include "EncryptInplace.h"
-
-#include <ext4_utils/ext4.h>
-#include <ext4_utils/ext4_utils.h>
-#include <f2fs_sparseblock.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-
-#include <algorithm>
-
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-
-// HORRIBLE HACK, FIXME
-#include "cryptfs.h"
-
-// FIXME horrible cut-and-paste code
-static inline int unix_read(int fd, void* buff, int len) {
-    return TEMP_FAILURE_RETRY(read(fd, buff, len));
-}
-
-static inline int unix_write(int fd, const void* buff, int len) {
-    return TEMP_FAILURE_RETRY(write(fd, buff, len));
-}
-
-#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / CRYPT_SECTOR_SIZE)
-
-/* aligned 32K writes tends to make flash happy.
- * SD card association recommends it.
- */
-#ifndef CONFIG_HW_DISK_ENCRYPTION
-#define BLOCKS_AT_A_TIME 8
-#else
-#define BLOCKS_AT_A_TIME 1024
-#endif
-
-struct encryptGroupsData {
-    int realfd;
-    int cryptofd;
-    off64_t numblocks;
-    off64_t one_pct, cur_pct, new_pct;
-    off64_t blocks_already_done, tot_numblocks;
-    off64_t used_blocks_already_done, tot_used_blocks;
-    const char* real_blkdev;
-    const char* crypto_blkdev;
-    int count;
-    off64_t offset;
-    char* buffer;
-    off64_t last_written_sector;
-    int completed;
-    time_t time_started;
-    int remaining_time;
-    bool set_progress_properties;
-};
-
-static void update_progress(struct encryptGroupsData* data, int is_used) {
-    data->blocks_already_done++;
-
-    if (is_used) {
-        data->used_blocks_already_done++;
-    }
-    if (data->tot_used_blocks) {
-        data->new_pct = data->used_blocks_already_done / data->one_pct;
-    } else {
-        data->new_pct = data->blocks_already_done / data->one_pct;
-    }
-
-    if (!data->set_progress_properties) return;
-
-    if (data->new_pct > data->cur_pct) {
-        char buf[8];
-        data->cur_pct = data->new_pct;
-        snprintf(buf, sizeof(buf), "%" PRId64, data->cur_pct);
-        android::base::SetProperty("vold.encrypt_progress", buf);
-    }
-
-    if (data->cur_pct >= 5) {
-        struct timespec time_now;
-        if (clock_gettime(CLOCK_MONOTONIC, &time_now)) {
-            LOG(WARNING) << "Error getting time";
-        } else {
-            double elapsed_time = difftime(time_now.tv_sec, data->time_started);
-            off64_t remaining_blocks = data->tot_used_blocks - data->used_blocks_already_done;
-            int remaining_time =
-                (int)(elapsed_time * remaining_blocks / data->used_blocks_already_done);
-
-            // Change time only if not yet set, lower, or a lot higher for
-            // best user experience
-            if (data->remaining_time == -1 || remaining_time < data->remaining_time ||
-                remaining_time > data->remaining_time + 60) {
-                char buf[8];
-                snprintf(buf, sizeof(buf), "%d", remaining_time);
-                android::base::SetProperty("vold.encrypt_time_remaining", buf);
-                data->remaining_time = remaining_time;
-            }
-        }
-    }
-}
-
-static void log_progress(struct encryptGroupsData const* data, bool completed) {
-    // Precondition - if completed data = 0 else data != 0
-
-    // Track progress so we can skip logging blocks
-    static off64_t offset = -1;
-
-    // Need to close existing 'Encrypting from' log?
-    if (completed || (offset != -1 && data->offset != offset)) {
-        LOG(INFO) << "Encrypted to sector " << offset / info.block_size * CRYPT_SECTOR_SIZE;
-        offset = -1;
-    }
-
-    // Need to start new 'Encrypting from' log?
-    if (!completed && offset != data->offset) {
-        LOG(INFO) << "Encrypting from sector " << data->offset / info.block_size * CRYPT_SECTOR_SIZE;
-    }
-
-    // Update offset
-    if (!completed) {
-        offset = data->offset + (off64_t)data->count * info.block_size;
-    }
-}
-
-static int flush_outstanding_data(struct encryptGroupsData* data) {
-    if (data->count == 0) {
-        return 0;
-    }
-
-    LOG(DEBUG) << "Copying " << data->count << " blocks at offset " << data->offset;
-
-    if (pread64(data->realfd, data->buffer, info.block_size * data->count, data->offset) <= 0) {
-        LOG(ERROR) << "Error reading real_blkdev " << data->real_blkdev << " for inplace encrypt";
-        return -1;
-    }
-
-    if (pwrite64(data->cryptofd, data->buffer, info.block_size * data->count, data->offset) <= 0) {
-        LOG(ERROR) << "Error writing crypto_blkdev " << data->crypto_blkdev
-                   << " for inplace encrypt";
-        return -1;
-    } else {
-        log_progress(data, false);
-    }
-
-    data->count = 0;
-    data->last_written_sector =
-        (data->offset + data->count) / info.block_size * CRYPT_SECTOR_SIZE - 1;
-    return 0;
-}
-
-static int encrypt_groups(struct encryptGroupsData* data) {
-    unsigned int i;
-    u8* block_bitmap = 0;
-    unsigned int block;
-    off64_t ret;
-    int rc = -1;
-
-    data->buffer = (char*)malloc(info.block_size * BLOCKS_AT_A_TIME);
-    if (!data->buffer) {
-        LOG(ERROR) << "Failed to allocate crypto buffer";
-        goto errout;
-    }
-
-    block_bitmap = (u8*)malloc(info.block_size);
-    if (!block_bitmap) {
-        LOG(ERROR) << "failed to allocate block bitmap";
-        goto errout;
-    }
-
-    for (i = 0; i < aux_info.groups; ++i) {
-        LOG(INFO) << "Encrypting group " << i;
-
-        u32 first_block = aux_info.first_data_block + i * info.blocks_per_group;
-        u32 block_count = std::min(info.blocks_per_group, (u32)(aux_info.len_blocks - first_block));
-
-        off64_t offset = (u64)info.block_size * aux_info.bg_desc[i].bg_block_bitmap;
-
-        ret = pread64(data->realfd, block_bitmap, info.block_size, offset);
-        if (ret != (int)info.block_size) {
-            LOG(ERROR) << "failed to read all of block group bitmap " << i;
-            goto errout;
-        }
-
-        offset = (u64)info.block_size * first_block;
-
-        data->count = 0;
-
-        for (block = 0; block < block_count; block++) {
-            int used = (aux_info.bg_desc[i].bg_flags & EXT4_BG_BLOCK_UNINIT)
-                           ? 0
-                           : bitmap_get_bit(block_bitmap, block);
-            update_progress(data, used);
-            if (used) {
-                if (data->count == 0) {
-                    data->offset = offset;
-                }
-                data->count++;
-            } else {
-                if (flush_outstanding_data(data)) {
-                    goto errout;
-                }
-            }
-
-            offset += info.block_size;
-
-            /* Write data if we are aligned or buffer size reached */
-            if (offset % (info.block_size * BLOCKS_AT_A_TIME) == 0 ||
-                data->count == BLOCKS_AT_A_TIME) {
-                if (flush_outstanding_data(data)) {
-                    goto errout;
-                }
-            }
-        }
-        if (flush_outstanding_data(data)) {
-            goto errout;
-        }
-    }
-
-    data->completed = 1;
-    rc = 0;
-
-errout:
-    log_progress(0, true);
-    free(data->buffer);
-    free(block_bitmap);
-    return rc;
-}
-
-static int cryptfs_enable_inplace_ext4(const char* crypto_blkdev, const char* real_blkdev,
-                                       off64_t size, off64_t* size_already_done, off64_t tot_size,
-                                       off64_t previously_encrypted_upto,
-                                       bool set_progress_properties) {
-    u32 i;
-    struct encryptGroupsData data;
-    int rc;  // Can't initialize without causing warning -Wclobbered
-    int retries = RETRY_MOUNT_ATTEMPTS;
-    struct timespec time_started = {0};
-
-    if (previously_encrypted_upto > *size_already_done) {
-        LOG(DEBUG) << "Not fast encrypting since resuming part way through";
-        return -1;
-    }
-
-    memset(&data, 0, sizeof(data));
-    data.real_blkdev = real_blkdev;
-    data.crypto_blkdev = crypto_blkdev;
-    data.set_progress_properties = set_progress_properties;
-
-    LOG(DEBUG) << "Opening" << real_blkdev;
-    if ((data.realfd = open(real_blkdev, O_RDWR | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
-        rc = -1;
-        goto errout;
-    }
-
-    LOG(DEBUG) << "Opening" << crypto_blkdev;
-    // Wait until the block device appears.  Re-use the mount retry values since it is reasonable.
-    while ((data.cryptofd = open(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
-        if (--retries) {
-            PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev
-                        << " for ext4 inplace encrypt, retrying";
-            sleep(RETRY_MOUNT_DELAY_SECONDS);
-        } else {
-            PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev
-                        << " for ext4 inplace encrypt";
-            rc = ENABLE_INPLACE_ERR_DEV;
-            goto errout;
-        }
-    }
-
-    if (setjmp(setjmp_env)) {  // NOLINT
-        LOG(ERROR) << "Reading ext4 extent caused an exception";
-        rc = -1;
-        goto errout;
-    }
-
-    if (read_ext(data.realfd, 0) != 0) {
-        LOG(ERROR) << "Failed to read ext4 extent";
-        rc = -1;
-        goto errout;
-    }
-
-    data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
-    data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
-    data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
-
-    LOG(INFO) << "Encrypting ext4 filesystem in place...";
-
-    data.tot_used_blocks = data.numblocks;
-    for (i = 0; i < aux_info.groups; ++i) {
-        data.tot_used_blocks -= aux_info.bg_desc[i].bg_free_blocks_count;
-    }
-
-    data.one_pct = data.tot_used_blocks / 100;
-    data.cur_pct = 0;
-
-    if (clock_gettime(CLOCK_MONOTONIC, &time_started)) {
-        LOG(WARNING) << "Error getting time at start";
-        // Note - continue anyway - we'll run with 0
-    }
-    data.time_started = time_started.tv_sec;
-    data.remaining_time = -1;
-
-    rc = encrypt_groups(&data);
-    if (rc) {
-        LOG(ERROR) << "Error encrypting groups";
-        goto errout;
-    }
-
-    *size_already_done += data.completed ? size : data.last_written_sector;
-    rc = 0;
-
-errout:
-    close(data.realfd);
-    close(data.cryptofd);
-
-    return rc;
-}
-
-static void log_progress_f2fs(u64 block, bool completed) {
-    // Precondition - if completed data = 0 else data != 0
-
-    // Track progress so we can skip logging blocks
-    static u64 last_block = (u64)-1;
-
-    // Need to close existing 'Encrypting from' log?
-    if (completed || (last_block != (u64)-1 && block != last_block + 1)) {
-        LOG(INFO) << "Encrypted to block " << last_block;
-        last_block = -1;
-    }
-
-    // Need to start new 'Encrypting from' log?
-    if (!completed && (last_block == (u64)-1 || block != last_block + 1)) {
-        LOG(INFO) << "Encrypting from block " << block;
-    }
-
-    // Update offset
-    if (!completed) {
-        last_block = block;
-    }
-}
-
-static int encrypt_one_block_f2fs(u64 pos, void* data) {
-    struct encryptGroupsData* priv_dat = (struct encryptGroupsData*)data;
-
-    priv_dat->blocks_already_done = pos - 1;
-    update_progress(priv_dat, 1);
-
-    off64_t offset = pos * CRYPT_INPLACE_BUFSIZE;
-
-    if (pread64(priv_dat->realfd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
-        LOG(ERROR) << "Error reading real_blkdev " << priv_dat->crypto_blkdev
-                   << " for f2fs inplace encrypt";
-        return -1;
-    }
-
-    if (pwrite64(priv_dat->cryptofd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
-        LOG(ERROR) << "Error writing crypto_blkdev " << priv_dat->crypto_blkdev
-                   << " for f2fs inplace encrypt";
-        return -1;
-    } else {
-        log_progress_f2fs(pos, false);
-    }
-
-    return 0;
-}
-
-static int cryptfs_enable_inplace_f2fs(const char* crypto_blkdev, const char* real_blkdev,
-                                       off64_t size, off64_t* size_already_done, off64_t tot_size,
-                                       off64_t previously_encrypted_upto,
-                                       bool set_progress_properties) {
-    struct encryptGroupsData data;
-    struct f2fs_info* f2fs_info = NULL;
-    int rc = ENABLE_INPLACE_ERR_OTHER;
-    struct timespec time_started = {0};
-
-    if (previously_encrypted_upto > *size_already_done) {
-        LOG(DEBUG) << "Not fast encrypting since resuming part way through";
-        return ENABLE_INPLACE_ERR_OTHER;
-    }
-    memset(&data, 0, sizeof(data));
-    data.real_blkdev = real_blkdev;
-    data.crypto_blkdev = crypto_blkdev;
-    data.set_progress_properties = set_progress_properties;
-    data.realfd = -1;
-    data.cryptofd = -1;
-    if ((data.realfd = open64(real_blkdev, O_RDWR | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for f2fs inplace encrypt";
-        goto errout;
-    }
-    if ((data.cryptofd = open64(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev
-                    << " for f2fs inplace encrypt";
-        rc = ENABLE_INPLACE_ERR_DEV;
-        goto errout;
-    }
-
-    f2fs_info = generate_f2fs_info(data.realfd);
-    if (!f2fs_info) goto errout;
-
-    data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
-    data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
-    data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
-
-    data.tot_used_blocks = get_num_blocks_used(f2fs_info);
-
-    data.one_pct = data.tot_used_blocks / 100;
-    data.cur_pct = 0;
-    if (clock_gettime(CLOCK_MONOTONIC, &time_started)) {
-        LOG(WARNING) << "Error getting time at start";
-        // Note - continue anyway - we'll run with 0
-    }
-    data.time_started = time_started.tv_sec;
-    data.remaining_time = -1;
-
-
-    data.buffer = (char*)malloc(f2fs_info->block_size);
-    if (!data.buffer) {
-        LOG(ERROR) << "Failed to allocate crypto buffer";
-        goto errout;
-    }
-
-    data.count = 0;
-
-    /* Currently, this either runs to completion, or hits a nonrecoverable error */
-    rc = run_on_used_blocks(data.blocks_already_done, f2fs_info, &encrypt_one_block_f2fs, &data);
-
-    if (rc) {
-        LOG(ERROR) << "Error in running over f2fs blocks";
-        rc = ENABLE_INPLACE_ERR_OTHER;
-        goto errout;
-    }
-
-    *size_already_done += size;
-    rc = 0;
-
-errout:
-    if (rc) LOG(ERROR) << "Failed to encrypt f2fs filesystem on " << real_blkdev;
-
-    log_progress_f2fs(0, true);
-    free(f2fs_info);
-    free(data.buffer);
-    close(data.realfd);
-    close(data.cryptofd);
-
-    return rc;
-}
-
-static int cryptfs_enable_inplace_full(const char* crypto_blkdev, const char* real_blkdev,
-                                       off64_t size, off64_t* size_already_done, off64_t tot_size,
-                                       off64_t previously_encrypted_upto,
-                                       bool set_progress_properties) {
-    int realfd, cryptofd;
-    char* buf[CRYPT_INPLACE_BUFSIZE];
-    int rc = ENABLE_INPLACE_ERR_OTHER;
-    off64_t numblocks, i, remainder;
-    off64_t one_pct, cur_pct, new_pct;
-    off64_t blocks_already_done, tot_numblocks;
-
-    if ((realfd = open(real_blkdev, O_RDONLY | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
-        return ENABLE_INPLACE_ERR_OTHER;
-    }
-
-    if ((cryptofd = open(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
-        PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev << " for inplace encrypt";
-        close(realfd);
-        return ENABLE_INPLACE_ERR_DEV;
-    }
-
-    /* This is pretty much a simple loop of reading 4K, and writing 4K.
-     * The size passed in is the number of 512 byte sectors in the filesystem.
-     * So compute the number of whole 4K blocks we should read/write,
-     * and the remainder.
-     */
-    numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
-    remainder = size % CRYPT_SECTORS_PER_BUFSIZE;
-    tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
-    blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
-
-    LOG(ERROR) << "Encrypting filesystem in place...";
-
-    i = previously_encrypted_upto + 1 - *size_already_done;
-
-    if (lseek64(realfd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) {
-        PLOG(ERROR) << "Cannot seek to previously encrypted point on " << real_blkdev;
-        goto errout;
-    }
-
-    if (lseek64(cryptofd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) {
-        PLOG(ERROR) << "Cannot seek to previously encrypted point on " << crypto_blkdev;
-        goto errout;
-    }
-
-    for (; i < size && i % CRYPT_SECTORS_PER_BUFSIZE != 0; ++i) {
-        if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
-            PLOG(ERROR) << "Error reading initial sectors from real_blkdev " << real_blkdev
-                        << " for inplace encrypt";
-            goto errout;
-        }
-        if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) {
-            PLOG(ERROR) << "Error writing initial sectors to crypto_blkdev " << crypto_blkdev
-                        << " for inplace encrypt";
-            goto errout;
-        } else {
-            LOG(INFO) << "Encrypted 1 block at " << i;
-        }
-    }
-
-    one_pct = tot_numblocks / 100;
-    cur_pct = 0;
-    /* process the majority of the filesystem in blocks */
-    for (i /= CRYPT_SECTORS_PER_BUFSIZE; i < numblocks; i++) {
-        new_pct = (i + blocks_already_done) / one_pct;
-        if (set_progress_properties && new_pct > cur_pct) {
-            char property_buf[8];
-
-            cur_pct = new_pct;
-            snprintf(property_buf, sizeof(property_buf), "%" PRId64, cur_pct);
-            android::base::SetProperty("vold.encrypt_progress", property_buf);
-        }
-        if (unix_read(realfd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
-            PLOG(ERROR) << "Error reading real_blkdev " << real_blkdev << " for inplace encrypt";
-            goto errout;
-        }
-        if (unix_write(cryptofd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
-            PLOG(ERROR) << "Error writing crypto_blkdev " << crypto_blkdev << " for inplace encrypt";
-            goto errout;
-        } else {
-            LOG(DEBUG) << "Encrypted " << CRYPT_SECTORS_PER_BUFSIZE << " block at "
-                       << i * CRYPT_SECTORS_PER_BUFSIZE;
-        }
-    }
-
-    /* Do any remaining sectors */
-    for (i = 0; i < remainder; i++) {
-        if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
-            LOG(ERROR) << "Error reading final sectors from real_blkdev " << real_blkdev
-                       << " for inplace encrypt";
-            goto errout;
-        }
-        if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) {
-            LOG(ERROR) << "Error writing final sectors to crypto_blkdev " << crypto_blkdev
-                       << " for inplace encrypt";
-            goto errout;
-        } else {
-            LOG(INFO) << "Encrypted 1 block at next location";
-        }
-    }
-
-    *size_already_done += size;
-    rc = 0;
-
-errout:
-    close(realfd);
-    close(cryptofd);
-
-    return rc;
-}
-
-/* returns on of the ENABLE_INPLACE_* return codes */
-int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, off64_t size,
-                           off64_t* size_already_done, off64_t tot_size,
-                           off64_t previously_encrypted_upto, bool set_progress_properties) {
-    int rc_ext4, rc_f2fs, rc_full;
-    LOG(DEBUG) << "cryptfs_enable_inplace(" << crypto_blkdev << ", " << real_blkdev << ", " << size
-               << ", " << size_already_done << ", " << tot_size << ", " << previously_encrypted_upto
-               << ", " << set_progress_properties << ")";
-    if (previously_encrypted_upto) {
-        LOG(DEBUG) << "Continuing encryption from " << previously_encrypted_upto;
-    }
-
-    if (*size_already_done + size < previously_encrypted_upto) {
-        LOG(DEBUG) << "cryptfs_enable_inplace already done";
-        *size_already_done += size;
-        return 0;
-    }
-
-    /* TODO: identify filesystem type.
-     * As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
-     * then we will drop down to cryptfs_enable_inplace_f2fs.
-     * */
-    if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev, size, size_already_done,
-                                               tot_size, previously_encrypted_upto,
-                                               set_progress_properties)) == 0) {
-        LOG(DEBUG) << "cryptfs_enable_inplace_ext4 success";
-        return 0;
-    }
-    LOG(DEBUG) << "cryptfs_enable_inplace_ext4()=" << rc_ext4;
-
-    if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev, size, size_already_done,
-                                               tot_size, previously_encrypted_upto,
-                                               set_progress_properties)) == 0) {
-        LOG(DEBUG) << "cryptfs_enable_inplace_f2fs success";
-        return 0;
-    }
-    LOG(DEBUG) << "cryptfs_enable_inplace_f2fs()=" << rc_f2fs;
-
-    rc_full =
-        cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev, size, size_already_done, tot_size,
-                                    previously_encrypted_upto, set_progress_properties);
-    LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full;
-
-    /* Hack for b/17898962, the following is the symptom... */
-    if (rc_ext4 == ENABLE_INPLACE_ERR_DEV && rc_f2fs == ENABLE_INPLACE_ERR_DEV &&
-        rc_full == ENABLE_INPLACE_ERR_DEV) {
-        LOG(DEBUG) << "ENABLE_INPLACE_ERR_DEV";
-        return ENABLE_INPLACE_ERR_DEV;
-    }
-    return rc_full;
-}
diff --git a/crypto/fscrypt/EncryptInplace.h b/crypto/fscrypt/EncryptInplace.h
deleted file mode 100644
index a2b46cf..0000000
--- a/crypto/fscrypt/EncryptInplace.h
+++ /dev/null
@@ -1,36 +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 _ENCRYPT_INPLACE_H
-#define _ENCRYPT_INPLACE_H
-
-#include <sys/types.h>
-
-#define CRYPT_INPLACE_BUFSIZE 4096
-#define CRYPT_SECTOR_SIZE 512
-#define RETRY_MOUNT_ATTEMPTS 10
-#define RETRY_MOUNT_DELAY_SECONDS 1
-
-/* Return values for cryptfs_enable_inplace() */
-#define ENABLE_INPLACE_OK 0
-#define ENABLE_INPLACE_ERR_OTHER (-1)
-#define ENABLE_INPLACE_ERR_DEV (-2) /* crypto_blkdev issue */
-
-int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, off64_t size,
-                           off64_t* size_already_done, off64_t tot_size,
-                           off64_t previously_encrypted_upto, bool set_progress_properties);
-
-#endif
diff --git a/crypto/fscrypt/FsCrypt.cpp b/crypto/fscrypt/FsCrypt.cpp
deleted file mode 100755
index a2049a2..0000000
--- a/crypto/fscrypt/FsCrypt.cpp
+++ /dev/null
@@ -1,1048 +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 "FsCrypt.h"
-
-#include "KeyStorage.h"
-#include "KeyUtil.h"
-#include "Utils.h"
-#include "VoldUtil.h"
-
-#include <algorithm>
-#include <map>
-#include <optional>
-#include <set>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <selinux/android.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <private/android_filesystem_config.h>
-#include <private/android_projectid_config.h>
-
-#include "android/os/IVold.h"
-
-#define EMULATED_USES_SELINUX 0
-#define MANAGE_MISC_DIRS 0
-
-#include <cutils/fs.h>
-#include <cutils/properties.h>
-
-#include <fscrypt/fscrypt.h>
-#include <keyutils.h>
-#include <libdm/dm.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-
-#include "fscrypt-common.h"
-
-using android::base::Basename;
-using android::base::Realpath;
-using android::base::StartsWith;
-using android::base::StringPrintf;
-using android::fs_mgr::GetEntryForMountPoint;
-using ::BuildDataPath;
-using ::IsFilesystemSupported;
-using ::kEmptyAuthentication;
-using ::KeyBuffer;
-using ::KeyGeneration;
-using ::retrieveKey;
-using ::retrieveOrGenerateKey;
-using ::SetQuotaInherit;
-using ::SetQuotaProjectId;
-using ::writeStringToFile;
-using namespace android::fscrypt;
-using namespace android::dm;
-
-// Map user ids to encryption policies
-std::map<userid_t, EncryptionPolicy> s_de_policies;
-std::map<userid_t, EncryptionPolicy> s_ce_policies;
-std::string de_key_raw_ref;
-
-namespace {
-
-const std::string device_key_dir = std::string() + DATA_MNT_POINT + fscrypt_unencrypted_folder;
-const std::string device_key_path = device_key_dir + "/key";
-const std::string device_key_temp = device_key_dir + "/temp";
-
-const std::string user_key_dir = std::string() + DATA_MNT_POINT + "/misc/vold/user_keys";
-const std::string user_key_temp = user_key_dir + "/temp";
-const std::string prepare_subdirs_path = "/system/bin/vold_prepare_subdirs";
-
-const std::string systemwide_volume_key_dir =
-    std::string() + DATA_MNT_POINT + "/misc/vold/volume_keys";
-
-// Some users are ephemeral, don't try to wipe their keys from disk
-std::set<userid_t> s_ephemeral_users;
-
-}  // namespace
-
-// Returns KeyGeneration suitable for key as described in EncryptionOptions
-static KeyGeneration makeGen(const EncryptionOptions& options) {
-    return KeyGeneration{FSCRYPT_MAX_KEY_SIZE, true, options.use_hw_wrapped_key};
-}
-
-static bool fscrypt_is_emulated() {
-    return property_get_bool("persist.sys.emulate_fbe", false);
-}
-
-static const char* escape_empty(const std::string& value) {
-    return value.empty() ? "null" : value.c_str();
-}
-
-static std::string get_de_key_path(userid_t user_id) {
-    return StringPrintf("%s/de/%d", user_key_dir.c_str(), user_id);
-}
-
-static std::string get_ce_key_directory_path(userid_t user_id) {
-    return StringPrintf("%s/ce/%d", user_key_dir.c_str(), user_id);
-}
-
-// Returns the keys newest first
-static std::vector<std::string> get_ce_key_paths(const std::string& directory_path) {
-    auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(directory_path.c_str()), closedir);
-    if (!dirp) {
-        PLOG(ERROR) << "Unable to open ce key directory: " + directory_path;
-        return std::vector<std::string>();
-    }
-    std::vector<std::string> result;
-    for (;;) {
-        errno = 0;
-        auto const entry = readdir(dirp.get());
-        if (!entry) {
-            if (errno) {
-                PLOG(ERROR) << "Unable to read ce key directory: " + directory_path;
-                return std::vector<std::string>();
-            }
-            break;
-        }
-        if (entry->d_type != DT_DIR || entry->d_name[0] != 'c') {
-            LOG(INFO) << "Skipping non-key " << entry->d_name;
-            continue;
-        }
-        result.emplace_back(directory_path + "/" + entry->d_name);
-    }
-    std::sort(result.begin(), result.end());
-    std::reverse(result.begin(), result.end());
-    return result;
-}
-
-static std::string get_ce_key_current_path(const std::string& directory_path) {
-    return directory_path + "/current";
-}
-
-static bool get_ce_key_new_path(const std::string& directory_path,
-                                const std::vector<std::string>& paths, std::string* ce_key_path) {
-    if (paths.empty()) {
-        *ce_key_path = get_ce_key_current_path(directory_path);
-        return true;
-    }
-    for (unsigned int i = 0; i < UINT_MAX; i++) {
-        auto const candidate = StringPrintf("%s/cx%010u", directory_path.c_str(), i);
-        if (paths[0] < candidate) {
-            *ce_key_path = candidate;
-            return true;
-        }
-    }
-    return false;
-}
-
-// Discard all keys but the named one; rename it to canonical name.
-// No point in acting on errors in this; ignore them.
-static void fixate_user_ce_key(const std::string& directory_path, const std::string& to_fix,
-                               const std::vector<std::string>& paths) {
-    for (auto const other_path : paths) {
-        if (other_path != to_fix) {
-            ::destroyKey(other_path);
-        }
-    }
-    auto const current_path = get_ce_key_current_path(directory_path);
-    if (to_fix != current_path) {
-        LOG(INFO) << "Renaming " << to_fix << " to " << current_path;
-        if (rename(to_fix.c_str(), current_path.c_str()) != 0) {
-            PLOG(WARNING) << "Unable to rename " << to_fix << " to " << current_path;
-            return;
-        }
-    }
-    ::FsyncDirectory(directory_path);
-}
-
-static bool read_and_fixate_user_ce_key(userid_t user_id,
-                                        const ::KeyAuthentication& auth,
-                                        KeyBuffer* ce_key) {
-    auto const directory_path = get_ce_key_directory_path(user_id);
-    auto const paths = get_ce_key_paths(directory_path);
-    for (auto const ce_key_path : paths) {
-        LOG(INFO) << "Trying user CE key " << ce_key_path;
-        if (retrieveKey(ce_key_path, auth, ce_key, true)) {
-            LOG(INFO) << "Successfully retrieved key";
-            fixate_user_ce_key(directory_path, ce_key_path, paths);
-            return true;
-        }
-    }
-    LOG(ERROR) << "Failed to find working ce key for user " << user_id;
-    return false;
-}
-
-static bool IsEmmcStorage(const std::string& blk_device) {
-    // Handle symlinks.
-    std::string real_path;
-    if (!Realpath(blk_device, &real_path)) {
-        real_path = blk_device;
-    }
-
-    // Handle logical volumes.
-    auto& dm = DeviceMapper::Instance();
-    for (;;) {
-        auto parent = dm.GetParentBlockDeviceByPath(real_path);
-        if (!parent.has_value()) break;
-        real_path = *parent;
-    }
-
-    // Now we should have the "real" block device.
-    LOG(INFO) << "IsEmmcStorage(): blk_device = " << blk_device << ", real_path=" << real_path;
-    return StartsWith(Basename(real_path), "mmcblk");
-}
-
-// Retrieve the options to use for encryption policies on the /data filesystem.
-static bool get_data_file_encryption_options(EncryptionOptions* options) {
-    if (fstab_default.empty()) {
-        if (!ReadDefaultFstab(&fstab_default)) {
-            PLOG(ERROR) << "Failed to open default fstab";
-            return false;
-        }
-    }
-    auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
-    if (entry == nullptr) {
-        LOG(ERROR) << "No mount point entry for " << DATA_MNT_POINT;
-        return false;
-    }
-    if (!ParseOptions(entry->encryption_options, options)) {
-        LOG(ERROR) << "Unable to parse encryption options for " << DATA_MNT_POINT ": "
-                   << entry->encryption_options;
-        return false;
-    }
-    if (options->version == 1) {
-        options->use_hw_wrapped_key =
-            GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT)->fs_mgr_flags.wrapped_key;
-    }
-    if ((options->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) &&
-        !IsEmmcStorage(entry->blk_device)) {
-        LOG(ERROR) << "The emmc_optimized encryption flag is only allowed on eMMC storage.  Remove "
-                      "this flag from the device's fstab";
-        return false;
-    }
-    return true;
-}
-
-static bool install_storage_key(const std::string& mountpoint, const EncryptionOptions& options,
-                                const KeyBuffer& key, EncryptionPolicy* policy) {
-    KeyBuffer ephemeral_wrapped_key;
-    if (options.use_hw_wrapped_key) {
-        if (!exportWrappedStorageKey(key, &ephemeral_wrapped_key)) {
-            LOG(ERROR) << "Failed to get ephemeral wrapped key";
-            return false;
-        }
-    }
-    return installKey(mountpoint, options, options.use_hw_wrapped_key ? ephemeral_wrapped_key : key,
-                      policy);
-}
-
-// Retrieve the options to use for encryption policies on adoptable storage.
-static bool get_volume_file_encryption_options(EncryptionOptions* options) {
-    // If we give the empty string, libfscrypt will use the default (currently XTS)
-    auto contents_mode = android::base::GetProperty("ro.crypto.volume.contents_mode", "");
-    // HEH as default was always a mistake. Use the libfscrypt default (CTS)
-    // for devices launching on versions above Android 10.
-    auto first_api_level = GetFirstApiLevel();
-    constexpr uint64_t pre_gki_level = 29;
-    auto filenames_mode =
-            android::base::GetProperty("ro.crypto.volume.filenames_mode",
-                                       first_api_level > pre_gki_level ? "" : "aes-256-heh");
-    auto options_string = android::base::GetProperty("ro.crypto.volume.options",
-                                                     contents_mode + ":" + filenames_mode);
-    if (!ParseOptionsForApiLevel(first_api_level, options_string, options)) {
-        LOG(ERROR) << "Unable to parse volume encryption options: " << options_string;
-        return false;
-    }
-    if (options->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) {
-        LOG(ERROR) << "The emmc_optimized encryption flag is only allowed on eMMC storage.  Remove "
-                      "this flag from ro.crypto.volume.options";
-        return false;
-    }
-    return true;
-}
-
-bool is_metadata_wrapped_key_supported() {
-    if (fstab_default.empty()) {
-        if (!ReadDefaultFstab(&fstab_default)) {
-            PLOG(ERROR) << "Failed to open default fstab";
-            return false;
-        }
-    }
-    return GetEntryForMountPoint(&fstab_default, METADATA_MNT_POINT)->fs_mgr_flags.wrapped_key;
-}
-
-static bool read_and_install_user_ce_key(userid_t user_id,
-                                         const ::KeyAuthentication& auth) {
-    if (s_ce_policies.count(user_id) != 0) return true;
-    EncryptionOptions options;
-    if (!get_data_file_encryption_options(&options)) return false;
-    KeyBuffer ce_key;
-    if (!read_and_fixate_user_ce_key(user_id, auth, &ce_key)) return false;
-    EncryptionPolicy ce_policy;
-    if (!install_storage_key(DATA_MNT_POINT, options, ce_key, &ce_policy)) return false;
-    s_ce_policies[user_id] = ce_policy;
-    LOG(INFO) << "Installed ce key for user " << user_id;
-    return true;
-}
-
-static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid) {
-    LOG(INFO) << "Preparing: " << dir;
-    if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
-        PLOG(ERROR) << "Failed to prepare " << dir;
-        return false;
-    }
-    return true;
-}
-
-static bool destroy_dir(const std::string& dir) {
-    LOG(INFO) << "Destroying: " << dir;
-    if (rmdir(dir.c_str()) != 0 && errno != ENOENT) {
-        PLOG(ERROR) << "Failed to destroy " << dir;
-        return false;
-    }
-    return true;
-}
-
-// NB this assumes that there is only one thread listening for crypt commands, because
-// it creates keys in a fixed location.
-static bool create_and_install_user_keys(userid_t user_id, bool create_ephemeral) {
-    LOG(INFO) << "fscrypt::create_and_install_user_keys";
-    EncryptionOptions options;
-    if (!get_data_file_encryption_options(&options)) return false;
-    KeyBuffer de_key, ce_key;
-    if (!generateStorageKey(makeGen(options), &de_key)) return false;
-    if (!generateStorageKey(makeGen(options), &ce_key)) return false;
-    if (create_ephemeral) {
-        // If the key should be created as ephemeral, don't store it.
-        s_ephemeral_users.insert(user_id);
-    } else {
-        auto const directory_path = get_ce_key_directory_path(user_id);
-        if (!prepare_dir(directory_path, 0700, AID_ROOT, AID_ROOT)) return false;
-        auto const paths = get_ce_key_paths(directory_path);
-        std::string ce_key_path;
-        if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
-        if (!::storeKeyAtomically(ce_key_path, user_key_temp, kEmptyAuthentication,
-                                               ce_key))
-            return false;
-        fixate_user_ce_key(directory_path, ce_key_path, paths);
-        // Write DE key second; once this is written, all is good.
-        if (!::storeKeyAtomically(get_de_key_path(user_id), user_key_temp,
-                                               kEmptyAuthentication, de_key))
-            return false;
-    }
-    EncryptionPolicy de_policy;
-    if (!install_storage_key(DATA_MNT_POINT, options, de_key, &de_policy)) return false;
-    s_de_policies[user_id] = de_policy;
-    LOG(INFO) << "fscrypt::added de_policy";
-    EncryptionPolicy ce_policy;
-    if (!install_storage_key(DATA_MNT_POINT, options, ce_key, &ce_policy)) return false;
-    s_ce_policies[user_id] = ce_policy;
-    LOG(INFO) << "Created keys for user " << user_id;
-    return true;
-}
-
-bool lookup_policy(const std::map<userid_t, EncryptionPolicy>& key_map, userid_t user_id,
-                          EncryptionPolicy* policy) {
-    auto refi = key_map.find(user_id);
-    if (refi == key_map.end()) {
-        LOG(ERROR) << "Cannot find key for " << user_id;
-        return false;
-    }
-    *policy = refi->second;
-    return true;
-}
-
-static bool is_numeric(const char* name) {
-    for (const char* p = name; *p != '\0'; p++) {
-        if (!isdigit(*p)) return false;
-    }
-    return true;
-}
-
-static bool load_all_de_keys() {
-    LOG(INFO) << "fscrypt::load_all_de_keys";
-    EncryptionOptions options;
-    if (!get_data_file_encryption_options(&options)) return false;
-    auto de_dir = user_key_dir + "/de";
-    auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(de_dir.c_str()), closedir);
-    if (!dirp) {
-        PLOG(ERROR) << "Unable to read de key directory";
-        return false;
-    }
-    for (;;) {
-        errno = 0;
-        auto entry = readdir(dirp.get());
-        if (!entry) {
-            if (errno) {
-                PLOG(ERROR) << "Unable to read de key directory";
-                return false;
-            }
-            break;
-        }
-        if (entry->d_type != DT_DIR || !is_numeric(entry->d_name)) {
-            LOG(INFO) << "Skipping non-de-key " << entry->d_name;
-            continue;
-        }
-        userid_t user_id = std::stoi(entry->d_name);
-        auto key_path = de_dir + "/" + entry->d_name;
-        KeyBuffer de_key;
-        if (!retrieveKey(key_path, kEmptyAuthentication, &de_key, true)) return false;
-        EncryptionPolicy de_policy;
-        if (!install_storage_key(DATA_MNT_POINT, options, de_key, &de_policy)) return false;
-        auto ret = s_de_policies.insert({user_id, de_policy});
-        LOG(INFO) << "fscrypt::load_all_de_keys::s_de_policies::size::" << s_de_policies.size();
-        if (!ret.second && ret.first->second != de_policy) {
-            LOG(INFO) << "DE policy for user" << user_id << " changed";
-            return false;
-        }
-        LOG(INFO) << "Installed de key for user " << user_id;
-        std::string user_prop = "twrp.user." + std::to_string(user_id) + ".decrypt";
-        property_set(user_prop.c_str(), "0");
-    }
-    // fscrypt:TODO: go through all DE directories, ensure that all user dirs have the
-    // correct policy set on them, and that no rogue ones exist.
-    return true;
-}
-
-// Attempt to reinstall CE keys for users that we think are unlocked.
-static bool try_reload_ce_keys() {
-    for (const auto& it : s_ce_policies) {
-        if (!::reloadKeyFromSessionKeyring(DATA_MNT_POINT, it.second)) {
-            LOG(ERROR) << "Failed to load CE key from session keyring for user " << it.first;
-            return false;
-        }
-    }
-    return true;
-}
-
-bool fscrypt_initialize_systemwide_keys() {
-    LOG(INFO) << "fscrypt_initialize_systemwide_keys";
-
-    EncryptionOptions options;
-    if (!get_data_file_encryption_options(&options)) return false;
-
-    KeyBuffer device_key;
-    if (!retrieveOrGenerateKey(device_key_path, device_key_temp, kEmptyAuthentication,
-                               makeGen(options), &device_key))
-        return false;
-
-    EncryptionPolicy device_policy;
-    if (!install_storage_key(DATA_MNT_POINT, options, device_key, &device_policy)) return false;
-
-    std::string options_string;
-    if (!OptionsToString(device_policy.options, &options_string)) {
-        LOG(ERROR) << "Unable to serialize options";
-        return false;
-    }
-    std::string options_filename = std::string(DATA_MNT_POINT) + fscrypt_key_mode;
-    if (!::writeStringToFile(options_string, options_filename)) return false;
-
-    std::string ref_filename = std::string(DATA_MNT_POINT) + fscrypt_key_ref;
-    de_key_raw_ref = device_policy.key_raw_ref;
-    if (!::writeStringToFile(device_policy.key_raw_ref, ref_filename)) return false;
-    LOG(INFO) << "Wrote system DE key reference to:" << ref_filename;
-
-    KeyBuffer per_boot_key;
-    if (!generateStorageKey(makeGen(options), &per_boot_key)) return false;
-    EncryptionPolicy per_boot_policy;
-    if (!install_storage_key(DATA_MNT_POINT, options, per_boot_key, &per_boot_policy)) return false;
-    std::string per_boot_ref_filename = std::string("/data") + fscrypt_key_per_boot_ref;
-    if (!::writeStringToFile(per_boot_policy.key_raw_ref, per_boot_ref_filename))
-        return false;
-    LOG(INFO) << "Wrote per boot key reference to:" << per_boot_ref_filename;
-
-    if (!::FsyncDirectory(device_key_dir)) return false;
-    return true;
-}
-
-bool fscrypt_init_user0() {
-    if (fstab_default.empty()) {
-        if (!ReadDefaultFstab(&fstab_default)) {
-            PLOG(ERROR) << "Failed to open default fstab";
-            return -1;
-        }
-    }
-    LOG(INFO) << "fscrypt_init_user0";
-    if (fscrypt_is_native()) {
-        if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;
-        if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false;
-        if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false;
-        if (!::pathExists(get_de_key_path(0))) {
-            if (!create_and_install_user_keys(0, false)) return false;
-        }
-        // TODO: switch to loading only DE_0 here once framework makes
-        // explicit calls to install DE keys for secondary users
-        if (!load_all_de_keys()) return false;
-    }
-    // We can only safely prepare DE storage here, since CE keys are probably
-    // entangled with user credentials.  The framework will always prepare CE
-    // storage once CE keys are installed.
-    LOG(INFO) << "attempting fscrypt_prepare_user_storage";
-    if (!fscrypt_prepare_user_storage("", 0, 0, android::os::IVold::STORAGE_FLAG_DE)) {
-        LOG(ERROR) << "Failed to prepare user 0 storage";
-        return false;
-    }
-
-    // If this is a non-FBE device that recently left an emulated mode,
-    // restore user data directories to known-good state.
-    if (!fscrypt_is_native() && !fscrypt_is_emulated()) {
-        LOG(INFO) << "unlocking data media";
-        fscrypt_unlock_user_key(0, 0, "!", "!");
-    }
-
-    // In some scenarios (e.g. userspace reboot) we might unmount userdata
-    // without doing a hard reboot. If CE keys were stored in fs keyring then
-    // they will be lost after unmount. Attempt to re-install them.
-    if (fscrypt_is_native() && ::isFsKeyringSupported()) {
-        LOG(INFO) << "reloading ce keys";
-        if (!try_reload_ce_keys()) return false;
-    }
-
-    return true;
-}
-
-bool fscrypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral) {
-    LOG(INFO) << "fscrypt_vold_create_user_key for " << user_id << " serial " << serial;
-    if (!fscrypt_is_native()) {
-        return true; 
-    }
-    // FIXME test for existence of key that is not loaded yet
-    if (s_ce_policies.count(user_id) != 0) {
-        LOG(ERROR) << "Already exists, can't fscrypt_vold_create_user_key for " << user_id
-                   << " serial " << serial;
-        // FIXME should we fail the command?
-        return true;
-    }
-    if (!create_and_install_user_keys(user_id, ephemeral)) {
-        return false;
-    }
-    return true;
-}
-
-// "Lock" all encrypted directories whose key has been removed.  This is needed
-// in the case where the keys are being put in the session keyring (rather in
-// the newer filesystem-level keyrings), because removing a key from the session
-// keyring doesn't affect inodes in the kernel's inode cache whose per-file key
-// was already set up.  So to remove the per-file keys and make the files
-// "appear encrypted", these inodes must be evicted.
-//
-// To do this, sync() to clean all dirty inodes, then drop all reclaimable slab
-// objects systemwide.  This is overkill, but it's the best available method
-// currently.  Don't use drop_caches mode "3" because that also evicts pagecache
-// for in-use files; all files relevant here are already closed and sync'ed.
-static void drop_caches_if_needed() {
-    if (::isFsKeyringSupported()) {
-        return;
-    }
-    sync();
-    if (!writeStringToFile("2", "/proc/sys/vm/drop_caches")) {
-        PLOG(ERROR) << "Failed to drop caches during key eviction";
-    }
-}
-
-static bool evict_ce_key(userid_t user_id) {
-    bool success = true;
-    EncryptionPolicy policy;
-    // If we haven't loaded the CE key, no need to evict it.
-    if (lookup_policy(s_ce_policies, user_id, &policy)) {
-        success &= ::evictKey(DATA_MNT_POINT, policy);
-        drop_caches_if_needed();
-    }
-    s_ce_policies.erase(user_id);
-    return success;
-}
-
-bool fscrypt_destroy_user_key(userid_t user_id) {
-    LOG(INFO) << "fscrypt_destroy_user_key(" << user_id << ")";
-    if (!fscrypt_is_native()) {
-        return true;
-    }
-    bool success = true;
-    success &= evict_ce_key(user_id);
-    EncryptionPolicy de_policy;
-    success &= lookup_policy(s_de_policies, user_id, &de_policy) &&
-               ::evictKey(DATA_MNT_POINT, de_policy);
-    s_de_policies.erase(user_id);
-    auto it = s_ephemeral_users.find(user_id);
-    if (it != s_ephemeral_users.end()) {
-        s_ephemeral_users.erase(it);
-    } else {
-        for (auto const path : get_ce_key_paths(get_ce_key_directory_path(user_id))) {
-            success &= ::destroyKey(path);
-        }
-        auto de_key_path = get_de_key_path(user_id);
-        if (::pathExists(de_key_path)) {
-            success &= ::destroyKey(de_key_path);
-        } else {
-            LOG(INFO) << "Not present so not erasing: " << de_key_path;
-        }
-    }
-    return success;
-}
-
-static bool emulated_lock(const std::string& path) {
-    if (chmod(path.c_str(), 0000) != 0) {
-        PLOG(ERROR) << "Failed to chmod " << path;
-        return false;
-    }
-#if EMULATED_USES_SELINUX
-    if (setfilecon(path.c_str(), "u:object_r:storage_stub_file:s0") != 0) {
-        PLOG(WARNING) << "Failed to setfilecon " << path;
-        return false;
-    }
-#endif
-    return true;
-}
-
-static bool emulated_unlock(const std::string& path, mode_t mode) {
-    if (chmod(path.c_str(), mode) != 0) {
-        PLOG(ERROR) << "Failed to chmod " << path;
-        // FIXME temporary workaround for b/26713622
-        if (fscrypt_is_emulated()) return false;
-    }
-#if EMULATED_USES_SELINUX
-    if (selinux_android_restorecon(path.c_str(), SELINUX_ANDROID_RESTORECON_FORCE) != 0) {
-        PLOG(WARNING) << "Failed to restorecon " << path;
-        // FIXME temporary workaround for b/26713622
-        if (fscrypt_is_emulated()) return false;
-    }
-#endif
-    return true;
-}
-
-static bool parse_hex(const std::string& hex, std::string* result) {
-    if (hex == "!") {
-        *result = "";
-        return true;
-    }
-    if (::HexToStr(hex, *result) != 0) {
-        LOG(ERROR) << "Invalid FBE hex string";  // Don't log the string for security reasons
-        return false;
-    }
-    return true;
-}
-
-static std::optional<::KeyAuthentication> authentication_from_hex(
-        const std::string& token_hex, const std::string& secret_hex) {
-    std::string token, secret;
-    if (!parse_hex(token_hex, &token)) return std::optional<::KeyAuthentication>();
-    if (!parse_hex(secret_hex, &secret)) return std::optional<::KeyAuthentication>();
-    if (secret.empty()) {
-        return kEmptyAuthentication;
-    } else {
-        return ::KeyAuthentication(token, secret);
-    }
-}
-
-static std::string volkey_path(const std::string& misc_path, const std::string& volume_uuid) {
-    return misc_path + "/vold/volume_keys/" + volume_uuid + "/default";
-}
-
-static std::string volume_secdiscardable_path(const std::string& volume_uuid) {
-    return systemwide_volume_key_dir + "/" + volume_uuid + "/secdiscardable";
-}
-
-static bool read_or_create_volkey(const std::string& misc_path, const std::string& volume_uuid,
-                                  EncryptionPolicy* policy) {
-    auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
-    std::string secdiscardable_hash;
-    if (::pathExists(secdiscardable_path)) {
-        if (!readSecdiscardable(secdiscardable_path, &secdiscardable_hash))
-            return false;
-    } else {
-        if (fs_mkdirs(secdiscardable_path.c_str(), 0700) != 0) {
-            PLOG(ERROR) << "Creating directories for: " << secdiscardable_path;
-            return false;
-        }
-        if (!::createSecdiscardable(secdiscardable_path, &secdiscardable_hash))
-            return false;
-    }
-    auto key_path = volkey_path(misc_path, volume_uuid);
-    if (fs_mkdirs(key_path.c_str(), 0700) != 0) {
-        PLOG(ERROR) << "Creating directories for: " << key_path;
-        return false;
-    }
-    ::KeyAuthentication auth("", secdiscardable_hash);
-
-    EncryptionOptions options;
-    if (!get_volume_file_encryption_options(&options)) return false;
-    KeyBuffer key;
-    if (!retrieveOrGenerateKey(key_path, key_path + "_tmp", auth, makeGen(options), &key))
-        return false;
-    if (!install_storage_key(BuildDataPath(volume_uuid), options, key, policy)) return false;
-    return true;
-}
-
-static bool destroy_volkey(const std::string& misc_path, const std::string& volume_uuid) {
-    auto path = volkey_path(misc_path, volume_uuid);
-    if (!::pathExists(path)) return true;
-    return ::destroyKey(path);
-}
-
-static bool fscrypt_rewrap_user_key(userid_t user_id, int serial,
-                                    const ::KeyAuthentication& retrieve_auth,
-                                    const ::KeyAuthentication& store_auth) {
-    if (s_ephemeral_users.count(user_id) != 0) return true;
-    auto const directory_path = get_ce_key_directory_path(user_id);
-    KeyBuffer ce_key;
-    std::string ce_key_current_path = get_ce_key_current_path(directory_path);
-    if (retrieveKey(ce_key_current_path, retrieve_auth, &ce_key, true)) {
-        LOG(INFO) << "Successfully retrieved key";
-        // TODO(147732812): Remove this once Locksettingservice is fixed.
-        // Currently it calls fscrypt_clear_user_key_auth with a secret when lockscreen is
-        // changed from swipe to none or vice-versa
-    } else if (retrieveKey(ce_key_current_path, kEmptyAuthentication, &ce_key, true)) {
-        LOG(INFO) << "Successfully retrieved key with empty auth";
-    } else {
-        LOG(ERROR) << "Failed to retrieve key for user " << user_id;
-        return false;
-    }
-    auto const paths = get_ce_key_paths(directory_path);
-    std::string ce_key_path;
-    if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
-    if (!::storeKeyAtomically(ce_key_path, user_key_temp, store_auth, ce_key))
-        return false;
-    if (!::FsyncDirectory(directory_path)) return false;
-    return true;
-}
-
-bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
-                               const std::string& secret_hex) {
-    LOG(INFO) << "fscrypt_add_user_key_auth " << user_id << " serial=" << serial
-               << " token_present=" << (token_hex != "!");
-    if (!fscrypt_is_native()) return true;
-    auto auth = authentication_from_hex(token_hex, secret_hex);
-    if (!auth) return false;
-    return fscrypt_rewrap_user_key(user_id, serial, kEmptyAuthentication, *auth);
-}
-
-bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
-                                 const std::string& secret_hex) {
-    LOG(INFO) << "fscrypt_clear_user_key_auth " << user_id << " serial=" << serial
-               << " token_present=" << (token_hex != "!");
-    if (!fscrypt_is_native()) return true;
-    auto auth = authentication_from_hex(token_hex, secret_hex);
-    if (!auth) return false;
-    return fscrypt_rewrap_user_key(user_id, serial, *auth, kEmptyAuthentication);
-}
-
-bool fscrypt_fixate_newest_user_key_auth(userid_t user_id) {
-    LOG(INFO) << "fscrypt_fixate_newest_user_key_auth " << user_id;
-    if (!fscrypt_is_native()) return true;
-    if (s_ephemeral_users.count(user_id) != 0) return true;
-    auto const directory_path = get_ce_key_directory_path(user_id);
-    auto const paths = get_ce_key_paths(directory_path);
-    if (paths.empty()) {
-        LOG(ERROR) << "No ce keys present, cannot fixate for user " << user_id;
-        return false;
-    }
-    fixate_user_ce_key(directory_path, paths[0], paths);
-    return true;
-}
-
-// TODO: rename to 'install' for consistency, and take flags to know which keys to install
-bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& token_hex,
-                             const std::string& secret_hex) {
-    LOG(INFO) << "fscrypt_unlock_user_key " << user_id << " serial=" << serial
-               << " token_present=" << (token_hex != "!");
-    if (fscrypt_is_native()) {
-        if (s_ce_policies.count(user_id) != 0) {
-            LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
-            return true;
-        }
-        auto auth = authentication_from_hex(token_hex, secret_hex);
-        if (!auth) return false;
-        if (!read_and_install_user_ce_key(user_id, *auth)) {
-            LOG(ERROR) << "Couldn't read key for " << user_id;
-            return false;
-        }
-    } else {
-        // When in emulation mode, we just use chmod. However, we also
-        // unlock directories when not in emulation mode, to bring devices
-        // back into a known-good state.
-        if (!emulated_unlock(::BuildDataSystemCePath(user_id), 0771) ||
-            !emulated_unlock(::BuildDataMiscCePath(user_id), 01771) ||
-            !emulated_unlock(::BuildDataMediaCePath("", user_id), 0770) ||
-            !emulated_unlock(::BuildDataUserCePath("", user_id), 0771)) {
-            LOG(ERROR) << "Failed to unlock user " << user_id;
-            return false;
-        }
-    }
-    return true;
-}
-
-// TODO: rename to 'evict' for consistency
-bool fscrypt_lock_user_key(userid_t user_id) {
-    LOG(INFO) << "fscrypt_lock_user_key " << user_id;
-    if (fscrypt_is_native()) {
-        return evict_ce_key(user_id);
-    } else if (fscrypt_is_emulated()) {
-        // When in emulation mode, we just use chmod
-        if (!emulated_lock(::BuildDataSystemCePath(user_id)) ||
-            !emulated_lock(::BuildDataMiscCePath(user_id)) ||
-            !emulated_lock(::BuildDataMediaCePath("", user_id)) ||
-            !emulated_lock(::BuildDataUserCePath("", user_id))) {
-            LOG(ERROR) << "Failed to lock user " << user_id;
-            return false;
-        }
-    }
-
-    return true;
-}
-
-static bool prepare_subdirs(const std::string& action, const std::string& volume_uuid,
-                            userid_t user_id, int flags) {
-    if (0 != ::ForkExecvp(
-                 std::vector<std::string>{prepare_subdirs_path, action, volume_uuid,
-                                          std::to_string(user_id), std::to_string(flags)})) {
-        LOG(ERROR) << "vold_prepare_subdirs failed";
-        return false;
-    }
-    return true;
-}
-
-bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
-                                  int flags) {
-    LOG(INFO) << "fscrypt_prepare_user_storage for volume " << escape_empty(volume_uuid)
-               << ", user " << user_id << ", serial " << serial << ", flags " << flags;
-
-    if (flags & android::os::IVold::STORAGE_FLAG_DE) {
-        // DE_sys key
-        auto system_legacy_path = ::BuildDataSystemLegacyPath(user_id);
-        auto misc_legacy_path = ::BuildDataMiscLegacyPath(user_id);
-        auto profiles_de_path = ::BuildDataProfilesDePath(user_id);
-
-        // DE_n key
-        auto system_de_path = ::BuildDataSystemDePath(user_id);
-        auto misc_de_path = ::BuildDataMiscDePath(user_id);
-        auto vendor_de_path = ::BuildDataVendorDePath(user_id);
-        auto user_de_path = ::BuildDataUserDePath(volume_uuid, user_id);
-
-        if (volume_uuid.empty()) {
-            if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
-#if MANAGE_MISC_DIRS
-            if (!prepare_dir(misc_legacy_path, 0750, multiuser_get_uid(user_id, AID_SYSTEM),
-                             multiuser_get_uid(user_id, AID_EVERYBODY)))
-                return false;
-#endif
-            if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
-
-            if (!prepare_dir(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
-            if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false;
-            if (!prepare_dir(vendor_de_path, 0771, AID_ROOT, AID_ROOT)) return false;
-        }
-        if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
-        if (fscrypt_is_native()) {
-            EncryptionPolicy de_policy;
-            if (volume_uuid.empty()) {
-                if (!lookup_policy(s_de_policies, user_id, &de_policy)) return false;
-                if (!EnsurePolicy(de_policy, system_de_path))
-                	LOG(INFO) << "EnsurePolicy returned false for " << system_de_path;
-                if (!EnsurePolicy(de_policy, misc_de_path))
-                	LOG(INFO) << "EnsurePolicy returned false for " << misc_de_path;
-                if (!EnsurePolicy(de_policy, vendor_de_path))
-                	LOG(INFO) << "EnsurePolicy returned false for " << vendor_de_path;
-            } else {
-                if (!read_or_create_volkey(misc_de_path, volume_uuid, &de_policy)) return false;
-            }
-            if (!EnsurePolicy(de_policy, user_de_path))
-            	LOG(INFO) << "EnsurePolicy returned false for " << user_de_path;
-
-        }
-    }
-
-    if (flags & android::os::IVold::STORAGE_FLAG_CE) {
-        // CE_n key
-        auto system_ce_path = ::BuildDataSystemCePath(user_id);
-        auto misc_ce_path = ::BuildDataMiscCePath(user_id);
-        auto vendor_ce_path = ::BuildDataVendorCePath(user_id);
-        auto media_ce_path = ::BuildDataMediaCePath(volume_uuid, user_id);
-        auto user_ce_path = ::BuildDataUserCePath(volume_uuid, user_id);
-
-        if (volume_uuid.empty()) {
-            if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
-            if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false;
-            if (!prepare_dir(vendor_ce_path, 0771, AID_ROOT, AID_ROOT)) return false;
-        }
-        if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
-
-        if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
-
-        if (fscrypt_is_native()) {
-            EncryptionPolicy ce_policy;
-            if (volume_uuid.empty()) {
-                if (!lookup_policy(s_ce_policies, user_id, &ce_policy)) return false;
-                if (!EnsurePolicy(ce_policy, system_ce_path))
-                	LOG(INFO) << "EnsurePolicy returned false for " << system_ce_path;
-                if (!EnsurePolicy(ce_policy, misc_ce_path))
-                	LOG(INFO) << "EnsurePolicy returned false for " << misc_ce_path;
-                if (!EnsurePolicy(ce_policy, vendor_ce_path))
-                	LOG(INFO) << "EnsurePolicy returned false for " << vendor_ce_path;
-            } else {
-                if (!read_or_create_volkey(misc_ce_path, volume_uuid, &ce_policy)) return false;
-            }
-            if (!EnsurePolicy(ce_policy, media_ce_path))
-            	LOG(INFO) << "EnsurePolicy returned false for " << media_ce_path;
-            if (!EnsurePolicy(ce_policy, user_ce_path))
-            	LOG(INFO) << "EnsurePolicy returned false for " << user_ce_path;
-        }
-
-        if (volume_uuid.empty()) {
-            // Now that credentials have been installed, we can run restorecon
-            // over these paths
-            // NOTE: these paths need to be kept in sync with libselinux
-            ::RestoreconRecursive(system_ce_path);
-            ::RestoreconRecursive(vendor_ce_path);
-            ::RestoreconRecursive(misc_ce_path);
-        }
-    }
-    if (!prepare_subdirs("prepare", volume_uuid, user_id, flags)) return false;
-
-    return true;
-}
-
-bool fscrypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags) {
-    LOG(INFO) << "fscrypt_destroy_user_storage for volume " << escape_empty(volume_uuid)
-               << ", user " << user_id << ", flags " << flags;
-    bool res = true;
-
-    res &= prepare_subdirs("destroy", volume_uuid, user_id, flags);
-
-    if (flags & android::os::IVold::STORAGE_FLAG_CE) {
-        // CE_n key
-        auto system_ce_path = ::BuildDataSystemCePath(user_id);
-        auto misc_ce_path = ::BuildDataMiscCePath(user_id);
-        auto vendor_ce_path = ::BuildDataVendorCePath(user_id);
-        auto media_ce_path = ::BuildDataMediaCePath(volume_uuid, user_id);
-        auto user_ce_path = ::BuildDataUserCePath(volume_uuid, user_id);
-
-        res &= destroy_dir(media_ce_path);
-        res &= destroy_dir(user_ce_path);
-        if (volume_uuid.empty()) {
-            res &= destroy_dir(system_ce_path);
-            res &= destroy_dir(misc_ce_path);
-            res &= destroy_dir(vendor_ce_path);
-        } else {
-            if (fscrypt_is_native()) {
-                res &= destroy_volkey(misc_ce_path, volume_uuid);
-            }
-        }
-    }
-
-    if (flags & android::os::IVold::STORAGE_FLAG_DE) {
-        // DE_sys key
-        auto system_legacy_path = ::BuildDataSystemLegacyPath(user_id);
-        auto misc_legacy_path = ::BuildDataMiscLegacyPath(user_id);
-        auto profiles_de_path = ::BuildDataProfilesDePath(user_id);
-
-        // DE_n key
-        auto system_de_path = ::BuildDataSystemDePath(user_id);
-        auto misc_de_path = ::BuildDataMiscDePath(user_id);
-        auto vendor_de_path = ::BuildDataVendorDePath(user_id);
-        auto user_de_path = ::BuildDataUserDePath(volume_uuid, user_id);
-
-        res &= destroy_dir(user_de_path);
-        if (volume_uuid.empty()) {
-            res &= destroy_dir(system_legacy_path);
-#if MANAGE_MISC_DIRS
-            res &= destroy_dir(misc_legacy_path);
-#endif
-            res &= destroy_dir(profiles_de_path);
-            res &= destroy_dir(system_de_path);
-            res &= destroy_dir(misc_de_path);
-            res &= destroy_dir(vendor_de_path);
-        } else {
-            if (fscrypt_is_native()) {
-                res &= destroy_volkey(misc_de_path, volume_uuid);
-            }
-        }
-    }
-
-    return res;
-}
-
-static bool destroy_volume_keys(const std::string& directory_path, const std::string& volume_uuid) {
-    auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(directory_path.c_str()), closedir);
-    if (!dirp) {
-        PLOG(ERROR) << "Unable to open directory: " + directory_path;
-        return false;
-    }
-    bool res = true;
-    for (;;) {
-        errno = 0;
-        auto const entry = readdir(dirp.get());
-        if (!entry) {
-            if (errno) {
-                PLOG(ERROR) << "Unable to read directory: " + directory_path;
-                return false;
-            }
-            break;
-        }
-        if (entry->d_type != DT_DIR || entry->d_name[0] == '.') {
-            LOG(INFO) << "Skipping non-user " << entry->d_name;
-            continue;
-        }
-        res &= destroy_volkey(directory_path + "/" + entry->d_name, volume_uuid);
-    }
-    return res;
-}
-
-bool fscrypt_destroy_volume_keys(const std::string& volume_uuid) {
-    bool res = true;
-    LOG(INFO) << "fscrypt_destroy_volume_keys for volume " << escape_empty(volume_uuid);
-    auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
-    res &= ::runSecdiscardSingle(secdiscardable_path);
-    res &= destroy_volume_keys("/data/misc_ce", volume_uuid);
-    res &= destroy_volume_keys("/data/misc_de", volume_uuid);
-    return res;
-}
-
-bool lookup_key_ref(const std::map<userid_t, android::fscrypt::EncryptionPolicy>& key_map, userid_t user_id,
-                           std::string* raw_ref) {
-    auto refi = key_map.find(user_id);
-    if (refi == key_map.end()) {
-        LOG(ERROR) << "Cannot find key for " << user_id;
-        return false;
-    }
-    *raw_ref = refi->second.key_raw_ref;
-    return true;
-}
diff --git a/crypto/fscrypt/FsCrypt.h b/crypto/fscrypt/FsCrypt.h
deleted file mode 100755
index 0cb38c1..0000000
--- a/crypto/fscrypt/FsCrypt.h
+++ /dev/null
@@ -1,50 +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 <map>
-#include <string>
-
-#include <fscrypt/fscrypt.h>
-#include <cutils/multiuser.h>
-
-using namespace android::fscrypt;
-
-bool fscrypt_initialize_systemwide_keys();
-
-bool fscrypt_init_user0();
-bool fscrypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral);
-bool fscrypt_destroy_user_key(userid_t user_id);
-bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token,
-                               const std::string& secret);
-bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token,
-                                 const std::string& secret);
-bool fscrypt_fixate_newest_user_key_auth(userid_t user_id);
-
-bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& token,
-                             const std::string& secret);
-bool fscrypt_lock_user_key(userid_t user_id);
-
-bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
-                                  int flags);
-bool is_metadata_wrapped_key_supported();
-bool fscrypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags);
-
-bool fscrypt_destroy_volume_keys(const std::string& volume_uuid);
-
-bool lookup_key_ref(const std::map<userid_t, android::fscrypt::EncryptionPolicy>& key_map, userid_t user_id,
-                           std::string* raw_ref);
-bool lookup_policy(const std::map<userid_t, EncryptionPolicy>& key_map, userid_t user_id,
-                          EncryptionPolicy* policy);
\ No newline at end of file
diff --git a/crypto/fscrypt/HashPassword.cpp b/crypto/fscrypt/HashPassword.cpp
deleted file mode 100644
index 07ecb1f..0000000
--- a/crypto/fscrypt/HashPassword.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2016 Team Win Recovery 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.
- */
-
-/*
- * This computes the "secret" used by Android as one of the parameters
- * to decrypt File Based Encryption. The secret is prefixed with
- * "Android FBE credential hash" padded with 0s to 128 bytes then the
- * user's password is appended to the end of the 128 bytes. This string
- * is then hashed with sha512 and the sha512 value is then converted to
- * hex with upper-case characters.
- */
-
-#include <stdio.h>
-#include <string>
-#include <stdlib.h>
-#include <openssl/sha.h>
-#include <openssl/hmac.h>
-
-#include "HashPassword.h"
-
-#define PASS_PADDING_SIZE 128
-#define SHA512_HEX_SIZE SHA512_DIGEST_LENGTH * 2
-#define SHA256_HEX_SIZE SHA256_DIGEST_LENGTH * 2
-
-void* PersonalizedHashBinary(const char* prefix, const char* key, const size_t key_size) {
-	size_t size = PASS_PADDING_SIZE + key_size;
-	unsigned char* buffer = (unsigned char*)calloc(1, size);
-	if (!buffer) return NULL; // failed to malloc
-	memcpy((void*)buffer, (void*)prefix, strlen(prefix));
-	unsigned char* ptr = buffer + PASS_PADDING_SIZE;
-	memcpy((void*)ptr, key, key_size);
-	unsigned char hash[SHA512_DIGEST_LENGTH];
-	SHA512_CTX sha512;
-	SHA512_Init(&sha512);
-	SHA512_Update(&sha512, buffer, size);
-	SHA512_Final(hash, &sha512);
-	free(buffer);
-	void* ret = malloc(SHA512_DIGEST_LENGTH);
-	if (!ret) return NULL; // failed to malloc
-	memcpy(ret, (void*)&hash[0], SHA512_DIGEST_LENGTH);
-	return ret;
-}
-
-std::string PersonalizedHash(const char* prefix, const char* key, const size_t key_size) {
-	size_t size = PASS_PADDING_SIZE + key_size;
-	unsigned char* buffer = (unsigned char*)calloc(1, size);
-	if (!buffer) return ""; // failed to malloc
-	memcpy((void*)buffer, (void*)prefix, strlen(prefix));
-	unsigned char* ptr = buffer + PASS_PADDING_SIZE;
-	memcpy((void*)ptr, key, key_size);
-	unsigned char hash[SHA512_DIGEST_LENGTH];
-	SHA512_CTX sha512;
-	SHA512_Init(&sha512);
-	SHA512_Update(&sha512, buffer, size);
-	SHA512_Final(hash, &sha512);
-	int index = 0;
-	char hex_hash[SHA512_HEX_SIZE + 1];
-	for(index = 0; index < SHA512_DIGEST_LENGTH; index++)
-		sprintf(hex_hash + (index * 2), "%02X", hash[index]);
-	hex_hash[128] = 0;
-	std::string ret = hex_hash;
-	free(buffer);
-	return ret;
-}
-
-std::string PersonalizedHash(const char* prefix, const std::string& Password) {
-	return PersonalizedHash(prefix, Password.c_str(), Password.size());
-}
-
-std::string PersonalizedHashSP800(const char* label, const char* context, const char* key, const size_t key_size) {
-	HMAC_CTX ctx;
-	HMAC_CTX_init(&ctx);
-	HMAC_Init_ex(&ctx, key, key_size, EVP_sha256(), NULL);
-	unsigned int counter = 1;
-	endianswap(&counter);
-	HMAC_Update(&ctx, (const unsigned char*)&counter, 4);
-	HMAC_Update(&ctx, (const unsigned char*)label, strlen(label));
-	const unsigned char divider = 0;
-	HMAC_Update(&ctx, &divider, 1);
-	HMAC_Update(&ctx, (const unsigned char*)context, strlen(context));
-	unsigned int contextDisambiguation = strlen(context) * 8;
-	endianswap(&contextDisambiguation);
-	HMAC_Update(&ctx, (const unsigned char*)&contextDisambiguation, 4);
-	unsigned int finalValue = 256;
-	endianswap(&finalValue);
-	HMAC_Update(&ctx, (const unsigned char*)&finalValue, 4);
-
-	unsigned char output[SHA256_DIGEST_LENGTH];
-	unsigned int out_size = 0;
-	HMAC_Final(&ctx, output, &out_size);
-
-	int index = 0;
-	char hex_hash[SHA256_HEX_SIZE + 1];
-	for(index = 0; index < SHA256_DIGEST_LENGTH; index++)
-		sprintf(hex_hash + (index * 2), "%02x", output[index]);
-	hex_hash[SHA256_HEX_SIZE] = 0;
-	std::string ret = hex_hash;
-	return ret;
-}
-
-std::string HashPassword(const std::string& Password) {
-	const char* prefix = FBE_PERSONALIZATION;
-	return PersonalizedHash(prefix, Password);
-}
diff --git a/crypto/fscrypt/HashPassword.h b/crypto/fscrypt/HashPassword.h
deleted file mode 100644
index 73880b1..0000000
--- a/crypto/fscrypt/HashPassword.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2016 Team Win Recovery 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 __HASH_PASSWORD_H
-#define __HASH_PASSWORD_H
-
-#include <string>
-
-#define FBE_PERSONALIZATION "Android FBE credential hash"
-#define PERSONALISATION_WEAVER_KEY "weaver-key"
-#define PERSONALISATION_WEAVER_PASSWORD "weaver-pwd"
-#define PERSONALISATION_APPLICATION_ID "application-id"
-#define PERSONALIZATION_FBE_KEY "fbe-key"
-#define PERSONALIZATION_USER_GK_AUTH "user-gk-authentication"
-#define PERSONALISATION_SECDISCARDABLE "secdiscardable-transform"
-#define PERSONALISATION_CONTEXT "android-synthetic-password-personalization-context"
-
-void* PersonalizedHashBinary(const char* prefix, const char* key, const size_t key_size);
-
-std::string PersonalizedHash(const char* prefix, const char* key, const size_t key_size);
-std::string PersonalizedHash(const char* prefix, const std::string& Password);
-std::string PersonalizedHashSP800(const char* label, const char* context, const char* key, const size_t key_size);
-std::string HashPassword(const std::string& Password);
-
-template <class T>
-void endianswap(T *objp) {
-	unsigned char *memp = reinterpret_cast<unsigned char*>(objp);
-	std::reverse(memp, memp + sizeof(T));
-}
-
-#endif
diff --git a/crypto/fscrypt/KeyBuffer.cpp b/crypto/fscrypt/KeyBuffer.cpp
deleted file mode 100644
index e7aede5..0000000
--- a/crypto/fscrypt/KeyBuffer.cpp
+++ /dev/null
@@ -1,37 +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 "KeyBuffer.h"
-
-#include <algorithm>
-#include <cstring>
-
-namespace android {
-namespace vold {
-
-KeyBuffer operator+(KeyBuffer&& lhs, const KeyBuffer& rhs) {
-    std::copy(rhs.begin(), rhs.end(), std::back_inserter(lhs));
-    return std::move(lhs);
-}
-
-KeyBuffer operator+(KeyBuffer&& lhs, const char* rhs) {
-    std::copy(rhs, rhs + strlen(rhs), std::back_inserter(lhs));
-    return std::move(lhs);
-}
-
-}  // namespace vold
-}  // namespace android
-
diff --git a/crypto/fscrypt/KeyBuffer.h b/crypto/fscrypt/KeyBuffer.h
deleted file mode 100644
index 2de9ac9..0000000
--- a/crypto/fscrypt/KeyBuffer.h
+++ /dev/null
@@ -1,58 +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 ANDROID_VOLD_KEYBUFFER_H
-#define ANDROID_VOLD_KEYBUFFER_H
-
-#include <cstring>
-#include <memory>
-#include <vector>
-
-
-/**
- * Variant of memset() that should never be optimized away. Borrowed from keymaster code.
- */
-#ifdef __clang__
-#define OPTNONE __attribute__((optnone))
-#else  // not __clang__
-#define OPTNONE __attribute__((optimize("O0")))
-#endif  // not __clang__
-inline OPTNONE void* memset_s(void* s, int c, size_t n) {
-    if (!s)
-        return s;
-    return memset(s, c, n);
-}
-#undef OPTNONE
-
-// Allocator that delegates useful work to standard one but zeroes data before deallocating.
-class ZeroingAllocator : public std::allocator<char> {
-    public:
-    void deallocate(pointer p, size_type n)
-    {
-        memset_s(p, 0, n);
-        std::allocator<char>::deallocate(p, n);
-    }
-};
-
-// Char vector that zeroes memory when deallocating.
-using KeyBuffer = std::vector<char, ZeroingAllocator>;
-
-// Convenience methods to concatenate key buffers.
-KeyBuffer operator+(KeyBuffer&& lhs, const KeyBuffer& rhs);
-KeyBuffer operator+(KeyBuffer&& lhs, const char* rhs);
-
-#endif
-
diff --git a/crypto/fscrypt/KeyStorage.cpp b/crypto/fscrypt/KeyStorage.cpp
deleted file mode 100755
index 8afc579..0000000
--- a/crypto/fscrypt/KeyStorage.cpp
+++ /dev/null
@@ -1,647 +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.
- */
-
-#include "KeyStorage.h"
-
-#include "Checkpoint.h"
-#include "Keymaster.h"
-#include "ScryptParameters.h"
-#include "Utils.h"
-
-#include <thread>
-#include <vector>
-
-#include <errno.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/unique_fd.h>
-
-#include <cutils/properties.h>
-
-#include <hardware/hw_auth_token.h>
-#include <keymasterV4_1/authorization_set.h>
-#include <keymasterV4_1/keymaster_utils.h>
-
-extern "C" {
-
-#include "crypto_scrypt.h"
-}
-
-const KeyAuthentication kEmptyAuthentication{"", ""};
-
-static constexpr size_t AES_KEY_BYTES = 32;
-static constexpr size_t GCM_NONCE_BYTES = 12;
-static constexpr size_t GCM_MAC_BYTES = 16;
-static constexpr size_t SALT_BYTES = 1 << 4;
-static constexpr size_t SECDISCARDABLE_BYTES = 1 << 14;
-static constexpr size_t STRETCHED_BYTES = 1 << 6;
-
-static constexpr uint32_t AUTH_TIMEOUT = 30;  // Seconds
-
-static const std::string kPkmBlob("pKMblob\x00", 8);
-
-static const char* kCurrentVersion = "1";
-static const char* kRmPath = "/system/bin/rm";
-static const char* kSecdiscardPath = "/system/bin/secdiscard";
-static const char* kStretch_none = "none";
-static const char* kStretch_nopassword = "nopassword";
-static const std::string kStretchPrefix_scrypt = "scrypt ";
-static const char* kHashPrefix_secdiscardable = "Android secdiscardable SHA512";
-static const char* kHashPrefix_keygen = "Android key wrapping key generation SHA512";
-static const char* kFn_encrypted_key = "encrypted_key";
-static const char* kFn_keymaster_key_blob = "keymaster_key_blob";
-static const char* kFn_keymaster_key_blob_upgraded = "keymaster_key_blob_upgraded";
-static const char* kFn_salt = "salt";
-static const char* kFn_secdiscardable = "secdiscardable";
-static const char* kFn_stretching = "stretching";
-static const char* kFn_version = "version";
-
-static bool checkSize(const std::string& kind, size_t actual, size_t expected) {
-    if (actual != expected) {
-        LOG(ERROR) << "Wrong number of bytes in " << kind << ", expected " << expected << " got "
-                   << actual;
-        return false;
-    }
-    return true;
-}
-
-static void hashWithPrefix(char const* prefix, const std::string& tohash, std::string* res) {
-    SHA512_CTX c;
-
-    SHA512_Init(&c);
-    // Personalise the hashing by introducing a fixed prefix.
-    // Hashing applications should use personalization except when there is a
-    // specific reason not to; see section 4.11 of https://www.schneier.com/skein1.3.pdf
-    std::string hashingPrefix = prefix;
-    hashingPrefix.resize(SHA512_CBLOCK);
-    SHA512_Update(&c, hashingPrefix.data(), hashingPrefix.size());
-    SHA512_Update(&c, tohash.data(), tohash.size());
-    res->assign(SHA512_DIGEST_LENGTH, '\0');
-    SHA512_Final(reinterpret_cast<uint8_t*>(&(*res)[0]), &c);
-}
-
-static bool generateKeymasterKey(Keymaster& keymaster, const KeyAuthentication& auth,
-                                 const std::string& appId, std::string* key) {
-    auto paramBuilder = km::AuthorizationSetBuilder()
-                            .AesEncryptionKey(AES_KEY_BYTES * 8)
-                            .GcmModeMinMacLen(GCM_MAC_BYTES * 8)
-                            .Authorization(km::TAG_APPLICATION_ID, km::support::blob2hidlVec(appId));
-    if (auth.token.empty()) {
-        LOG(DEBUG) << "Creating key that doesn't need auth token";
-        paramBuilder.Authorization(km::TAG_NO_AUTH_REQUIRED);
-    } else {
-        LOG(DEBUG) << "Auth token required for key";
-        if (auth.token.size() != sizeof(hw_auth_token_t)) {
-            LOG(ERROR) << "Auth token should be " << sizeof(hw_auth_token_t) << " bytes, was "
-                       << auth.token.size() << " bytes";
-            return false;
-        }
-        const hw_auth_token_t* at = reinterpret_cast<const hw_auth_token_t*>(auth.token.data());
-        auto user_id = at->user_id;  // Make a copy because at->user_id is unaligned.
-        paramBuilder.Authorization(km::TAG_USER_SECURE_ID, user_id);
-        paramBuilder.Authorization(km::TAG_USER_AUTH_TYPE, km::HardwareAuthenticatorType::PASSWORD);
-        paramBuilder.Authorization(km::TAG_AUTH_TIMEOUT, AUTH_TIMEOUT);
-    }
-
-    auto paramsWithRollback = paramBuilder;
-    paramsWithRollback.Authorization(km::TAG_ROLLBACK_RESISTANCE);
-
-    // Generate rollback-resistant key if possible.
-    return keymaster.generateKey(paramsWithRollback, key) ||
-           keymaster.generateKey(paramBuilder, key);
-}
-
-bool generateWrappedStorageKey(KeyBuffer* key) {
-    Keymaster keymaster;
-    if (!keymaster) return false;
-    std::string key_temp;
-    auto paramBuilder = km::AuthorizationSetBuilder().AesEncryptionKey(AES_KEY_BYTES * 8);
-    km::KeyParameter param1;
-    param1.tag = static_cast<::android::hardware::keymaster::V4_0::Tag>(
-        android::hardware::keymaster::V4_0::KM_TAG_FBE_ICE);
-    param1.f.boolValue = true;
-    paramBuilder.push_back(param1);
-    if (!keymaster.generateKey(paramBuilder, &key_temp)) return false;
-    *key = KeyBuffer(key_temp.size());
-    memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
-    return true;
-}
-
-bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key) {
-    Keymaster keymaster;
-    if (!keymaster) return false;
-    std::string key_temp;
-
-    auto ret = keymaster.exportKey(kmKey, &key_temp);
-    if (ret != km::ErrorCode::OK) {
-        if (ret == km::ErrorCode::KEY_REQUIRES_UPGRADE) {
-           std::string kmKeyStr(reinterpret_cast<const char*>(kmKey.data()), kmKey.size());
-           std::string Keystr;
-           if (!keymaster.upgradeKey(kmKeyStr, km::AuthorizationSet(), &Keystr)) return false;
-           KeyBuffer upgradedKey = KeyBuffer(Keystr.size());
-           memcpy(reinterpret_cast<void*>(upgradedKey.data()), Keystr.c_str(), upgradedKey.size());
-           ret = keymaster.exportKey(upgradedKey, &key_temp);
-           if (ret != km::ErrorCode::OK) return false;
-        } else {
-           return false;
-        }
-    }    *key = KeyBuffer(key_temp.size());
-    memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
-    return true;
-}
-
-static std::pair<km::AuthorizationSet, km::HardwareAuthToken> beginParams(
-    const KeyAuthentication& auth, const std::string& appId) {
-    auto paramBuilder = km::AuthorizationSetBuilder()
-                            .GcmModeMacLen(GCM_MAC_BYTES * 8)
-                            .Authorization(km::TAG_APPLICATION_ID, km::support::blob2hidlVec(appId));
-    km::HardwareAuthToken authToken;
-    if (!auth.token.empty()) {
-        LOG(INFO) << "Supplying auth token to Keymaster";
-        authToken = km::support::hidlVec2AuthToken(km::support::blob2hidlVec(auth.token));
-    }
-    return {paramBuilder, authToken};
-}
-
-static bool readFileToString(const std::string& filename, std::string* result) {
-    if (!android::base::ReadFileToString(filename, result)) {
-        PLOG(ERROR) << "Failed to read from " << filename;
-        return false;
-    }
-    return true;
-}
-
-static bool readRandomBytesOrLog(size_t count, std::string* out) {
-    auto status = ReadRandomBytes(count, *out);
-    if (status != android::OK) {
-        LOG(ERROR) << "Random read failed with status: " << status;
-        return false;
-    }
-    return true;
-}
-
-bool createSecdiscardable(const std::string& filename, std::string* hash) {
-    std::string secdiscardable;
-    if (!readRandomBytesOrLog(SECDISCARDABLE_BYTES, &secdiscardable)) return false;
-    if (!writeStringToFile(secdiscardable, filename)) return false;
-    hashWithPrefix(kHashPrefix_secdiscardable, secdiscardable, hash);
-    return true;
-}
-
-bool readSecdiscardable(const std::string& filename, std::string* hash) {
-    std::string secdiscardable;
-    if (!readFileToString(filename, &secdiscardable)) return false;
-    hashWithPrefix(kHashPrefix_secdiscardable, secdiscardable, hash);
-    return true;
-}
-
-static void deferedKmDeleteKey(const std::string& kmkey) {
-    while (!android::base::WaitForProperty("vold.checkpoint_committed", "1")) {
-        LOG(ERROR) << "Wait for boot timed out";
-    }
-    Keymaster keymaster;
-    if (!keymaster || !keymaster.deleteKey(kmkey)) {
-        LOG(ERROR) << "Defered Key deletion failed during upgrade";
-    }
-}
-
-bool kmDeleteKey(Keymaster& keymaster, const std::string& kmKey) {
-    bool needs_cp = cp_needsCheckpoint();
-
-    if (needs_cp) {
-        std::thread(deferedKmDeleteKey, kmKey).detach();
-        LOG(INFO) << "Deferring Key deletion during upgrade";
-        return true;
-    } else {
-        return keymaster.deleteKey(kmKey);
-    }
-}
-
-static KeymasterOperation begin(Keymaster& keymaster, const std::string& dir,
-                                km::KeyPurpose purpose, const km::AuthorizationSet& keyParams,
-                                const km::AuthorizationSet& opParams,
-                                const km::HardwareAuthToken& authToken,
-                                km::AuthorizationSet* outParams, bool keepOld) {
-    auto kmKeyPath = dir + "/" + kFn_keymaster_key_blob;
-    std::string kmKey;
-    if (!readFileToString(kmKeyPath, &kmKey)) return KeymasterOperation();
-    // In A12 keymaster_key_blob format changed:
-    // it have useless for us bytes in beginning, so remove them to correctly handle key
-    if (!kmKey.compare(0, kPkmBlob.size(), kPkmBlob))
-        kmKey.erase(0, kPkmBlob.size());
-    km::AuthorizationSet inParams(keyParams);
-    inParams.append(opParams.begin(), opParams.end());
-    for (;;) {
-        auto opHandle = keymaster.begin(purpose, kmKey, inParams, authToken, outParams);
-        if (opHandle) {
-            return opHandle;
-        }
-        if (opHandle.errorCode() != km::ErrorCode::KEY_REQUIRES_UPGRADE) return opHandle;
-        LOG(DEBUG) << "Upgrading key: " << dir;
-        std::string newKey;
-        if (!keymaster.upgradeKey(kmKey, keyParams, &newKey)) return KeymasterOperation();
-        auto newKeyPath = dir + "/" + kFn_keymaster_key_blob_upgraded;
-        if (!writeStringToFile(newKey, newKeyPath)) return KeymasterOperation();
-        if (!keepOld) {
-            if (rename(newKeyPath.c_str(), kmKeyPath.c_str()) != 0) {
-                PLOG(ERROR) << "Unable to move upgraded key to location: " << kmKeyPath;
-                return KeymasterOperation();
-            }
-            if (!::FsyncDirectory(dir)) {
-                LOG(ERROR) << "Key dir sync failed: " << dir;
-                return KeymasterOperation();
-            }
-            if (!kmDeleteKey(keymaster, kmKey)) {
-                LOG(ERROR) << "Key deletion failed during upgrade, continuing anyway: " << dir;
-            }
-        }
-        kmKey = newKey;
-        LOG(INFO) << "Key upgraded: " << dir;
-    }
-}
-
-static bool encryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
-                                    const km::AuthorizationSet& keyParams,
-                                    const km::HardwareAuthToken& authToken, const KeyBuffer& message,
-                                    std::string* ciphertext, bool keepOld) {
-    km::AuthorizationSet opParams;
-    km::AuthorizationSet outParams;
-    auto opHandle = begin(keymaster, dir, km::KeyPurpose::ENCRYPT, keyParams, opParams, authToken,
-                          &outParams, keepOld);
-    if (!opHandle) return false;
-    auto nonceBlob = outParams.GetTagValue(km::TAG_NONCE);
-    if (!nonceBlob.isOk()) {
-        LOG(ERROR) << "GCM encryption but no nonce generated";
-        return false;
-    }
-    // nonceBlob here is just a pointer into existing data, must not be freed
-    std::string nonce(reinterpret_cast<const char*>(&nonceBlob.value()[0]),
-                      nonceBlob.value().size());
-    if (!checkSize("nonce", nonce.size(), GCM_NONCE_BYTES)) return false;
-    std::string body;
-    if (!opHandle.updateCompletely(message, &body)) return false;
-
-    std::string mac;
-    if (!opHandle.finish(&mac)) return false;
-    if (!checkSize("mac", mac.size(), GCM_MAC_BYTES)) return false;
-    *ciphertext = nonce + body + mac;
-    return true;
-}
-
-static bool decryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
-                                    const km::AuthorizationSet& keyParams,
-                                    const km::HardwareAuthToken& authToken,
-                                    const std::string& ciphertext, KeyBuffer* message,
-                                    bool keepOld) {
-    auto nonce = ciphertext.substr(0, GCM_NONCE_BYTES);
-    auto bodyAndMac = ciphertext.substr(GCM_NONCE_BYTES);
-    auto opParams = km::AuthorizationSetBuilder().Authorization(km::TAG_NONCE,
-                                                                km::support::blob2hidlVec(nonce));
-    auto opHandle = begin(keymaster, dir, km::KeyPurpose::DECRYPT, keyParams, opParams, authToken,
-                          nullptr, keepOld);
-    if (!opHandle) return false;
-    if (!opHandle.updateCompletely(bodyAndMac, message)) return false;
-    if (!opHandle.finish(nullptr)) return false;
-    return true;
-}
-
-static std::string getStretching(const KeyAuthentication& auth) {
-    if (!auth.usesKeymaster()) {
-        return kStretch_none;
-    } else if (auth.secret.empty()) {
-        return kStretch_nopassword;
-    } else {
-        char paramstr[PROPERTY_VALUE_MAX];
-
-        property_get(SCRYPT_PROP, paramstr, SCRYPT_DEFAULTS);
-        return std::string() + kStretchPrefix_scrypt + paramstr;
-    }
-}
-
-static bool stretchingNeedsSalt(const std::string& stretching) {
-    return stretching != kStretch_nopassword && stretching != kStretch_none;
-}
-
-static bool stretchSecret(const std::string& stretching, const std::string& secret,
-                          const std::string& salt, std::string* stretched) {
-    if (stretching == kStretch_nopassword) {
-        if (!secret.empty()) {
-            LOG(WARNING) << "Password present but stretching is nopassword";
-            // Continue anyway
-        }
-        stretched->clear();
-    } else if (stretching == kStretch_none) {
-        *stretched = secret;
-    } else if (std::equal(kStretchPrefix_scrypt.begin(), kStretchPrefix_scrypt.end(),
-                          stretching.begin())) {
-        int Nf, rf, pf;
-        if (!parse_scrypt_parameters(stretching.substr(kStretchPrefix_scrypt.size()).c_str(), &Nf,
-                                     &rf, &pf)) {
-            LOG(ERROR) << "Unable to parse scrypt params in stretching: " << stretching;
-            return false;
-        }
-        stretched->assign(STRETCHED_BYTES, '\0');
-        if (crypto_scrypt(reinterpret_cast<const uint8_t*>(secret.data()), secret.size(),
-                          reinterpret_cast<const uint8_t*>(salt.data()), salt.size(), 1 << Nf,
-                          1 << rf, 1 << pf, reinterpret_cast<uint8_t*>(&(*stretched)[0]),
-                          stretched->size()) != 0) {
-            LOG(ERROR) << "scrypt failed with params: " << stretching;
-            return false;
-        }
-    } else {
-        LOG(ERROR) << "Unknown stretching type: " << stretching;
-        return false;
-    }
-    return true;
-}
-
-static bool generateAppId(const KeyAuthentication& auth, const std::string& stretching,
-                          const std::string& salt, const std::string& secdiscardable_hash,
-                          std::string* appId) {
-    std::string stretched;
-    if (!stretchSecret(stretching, auth.secret, salt, &stretched)) return false;
-    *appId = secdiscardable_hash + stretched;
-    return true;
-}
-
-static void logOpensslError() {
-    LOG(ERROR) << "Openssl error: " << ERR_get_error();
-}
-
-static bool encryptWithoutKeymaster(const std::string& preKey, const KeyBuffer& plaintext,
-                                    std::string* ciphertext) {
-    std::string key;
-    hashWithPrefix(kHashPrefix_keygen, preKey, &key);
-    key.resize(AES_KEY_BYTES);
-    if (!readRandomBytesOrLog(GCM_NONCE_BYTES, ciphertext)) return false;
-    auto ctx = std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)>(
-        EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free);
-    if (!ctx) {
-        logOpensslError();
-        return false;
-    }
-    if (1 != EVP_EncryptInit_ex(ctx.get(), EVP_aes_256_gcm(), NULL,
-                                reinterpret_cast<const uint8_t*>(key.data()),
-                                reinterpret_cast<const uint8_t*>(ciphertext->data()))) {
-        logOpensslError();
-        return false;
-    }
-    ciphertext->resize(GCM_NONCE_BYTES + plaintext.size() + GCM_MAC_BYTES);
-    int outlen;
-    if (1 != EVP_EncryptUpdate(
-                 ctx.get(), reinterpret_cast<uint8_t*>(&(*ciphertext)[0] + GCM_NONCE_BYTES),
-                 &outlen, reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size())) {
-        logOpensslError();
-        return false;
-    }
-    if (outlen != static_cast<int>(plaintext.size())) {
-        LOG(ERROR) << "GCM ciphertext length should be " << plaintext.size() << " was " << outlen;
-        return false;
-    }
-    if (1 != EVP_EncryptFinal_ex(
-                 ctx.get(),
-                 reinterpret_cast<uint8_t*>(&(*ciphertext)[0] + GCM_NONCE_BYTES + plaintext.size()),
-                 &outlen)) {
-        logOpensslError();
-        return false;
-    }
-    if (outlen != 0) {
-        LOG(ERROR) << "GCM EncryptFinal should be 0, was " << outlen;
-        return false;
-    }
-    if (1 != EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, GCM_MAC_BYTES,
-                                 reinterpret_cast<uint8_t*>(&(*ciphertext)[0] + GCM_NONCE_BYTES +
-                                                            plaintext.size()))) {
-        logOpensslError();
-        return false;
-    }
-    return true;
-}
-
-static bool decryptWithoutKeymaster(const std::string& preKey, const std::string& ciphertext,
-                                    KeyBuffer* plaintext) {
-    if (ciphertext.size() < GCM_NONCE_BYTES + GCM_MAC_BYTES) {
-        LOG(ERROR) << "GCM ciphertext too small: " << ciphertext.size();
-        return false;
-    }
-    std::string key;
-    hashWithPrefix(kHashPrefix_keygen, preKey, &key);
-    key.resize(AES_KEY_BYTES);
-    auto ctx = std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)>(
-        EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free);
-    if (!ctx) {
-        logOpensslError();
-        return false;
-    }
-    if (1 != EVP_DecryptInit_ex(ctx.get(), EVP_aes_256_gcm(), NULL,
-                                reinterpret_cast<const uint8_t*>(key.data()),
-                                reinterpret_cast<const uint8_t*>(ciphertext.data()))) {
-        logOpensslError();
-        return false;
-    }
-    *plaintext = KeyBuffer(ciphertext.size() - GCM_NONCE_BYTES - GCM_MAC_BYTES);
-    int outlen;
-    if (1 != EVP_DecryptUpdate(ctx.get(), reinterpret_cast<uint8_t*>(&(*plaintext)[0]), &outlen,
-                               reinterpret_cast<const uint8_t*>(ciphertext.data() + GCM_NONCE_BYTES),
-                               plaintext->size())) {
-        logOpensslError();
-        return false;
-    }
-    if (outlen != static_cast<int>(plaintext->size())) {
-        LOG(ERROR) << "GCM plaintext length should be " << plaintext->size() << " was " << outlen;
-        return false;
-    }
-    if (1 != EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, GCM_MAC_BYTES,
-                                 const_cast<void*>(reinterpret_cast<const void*>(
-                                     ciphertext.data() + GCM_NONCE_BYTES + plaintext->size())))) {
-        logOpensslError();
-        return false;
-    }
-    if (1 != EVP_DecryptFinal_ex(ctx.get(),
-                                 reinterpret_cast<uint8_t*>(&(*plaintext)[0] + plaintext->size()),
-                                 &outlen)) {
-        logOpensslError();
-        return false;
-    }
-    if (outlen != 0) {
-        LOG(ERROR) << "GCM EncryptFinal should be 0, was " << outlen;
-        return false;
-    }
-    return true;
-}
-
-bool pathExists(const std::string& path) {
-    return access(path.c_str(), F_OK) == 0;
-}
-
-bool storeKey(const std::string& dir, const KeyAuthentication& auth, const KeyBuffer& key) {
-    if (TEMP_FAILURE_RETRY(mkdir(dir.c_str(), 0700)) == -1) {
-        PLOG(ERROR) << "key mkdir " << dir;
-        return false;
-    }
-    if (!writeStringToFile(kCurrentVersion, dir + "/" + kFn_version)) return false;
-    std::string secdiscardable_hash;
-    if (!createSecdiscardable(dir + "/" + kFn_secdiscardable, &secdiscardable_hash)) return false;
-    std::string stretching = getStretching(auth);
-    if (!writeStringToFile(stretching, dir + "/" + kFn_stretching)) return false;
-    std::string salt;
-    if (stretchingNeedsSalt(stretching)) {
-        if (ReadRandomBytes(SALT_BYTES, salt) != android::OK) {
-            LOG(ERROR) << "Random read failed";
-            return false;
-        }
-        if (!writeStringToFile(salt, dir + "/" + kFn_salt)) return false;
-    }
-    std::string appId;
-    if (!generateAppId(auth, stretching, salt, secdiscardable_hash, &appId)) return false;
-    std::string encryptedKey;
-    if (auth.usesKeymaster()) {
-        Keymaster keymaster;
-        if (!keymaster) return false;
-        std::string kmKey;
-        if (!generateKeymasterKey(keymaster, auth, appId, &kmKey)) return false;
-        if (!writeStringToFile(kmKey, dir + "/" + kFn_keymaster_key_blob)) return false;
-        km::AuthorizationSet keyParams;
-        km::HardwareAuthToken authToken;
-        std::tie(keyParams, authToken) = beginParams(auth, appId);
-        if (!encryptWithKeymasterKey(keymaster, dir, keyParams, authToken, key, &encryptedKey,
-                                     false))
-            return false;
-    } else {
-        if (!encryptWithoutKeymaster(appId, key, &encryptedKey)) return false;
-    }
-    if (!writeStringToFile(encryptedKey, dir + "/" + kFn_encrypted_key)) return false;
-    if (!FsyncDirectory(dir)) return false;
-    return true;
-}
-
-bool storeKeyAtomically(const std::string& key_path, const std::string& tmp_path,
-                        const KeyAuthentication& auth, const KeyBuffer& key) {
-    if (pathExists(key_path)) {
-        LOG(ERROR) << "Already exists, cannot create key at: " << key_path;
-        return false;
-    }
-    if (pathExists(tmp_path)) {
-        LOG(DEBUG) << "Already exists, destroying: " << tmp_path;
-        destroyKey(tmp_path);  // May be partially created so ignore errors
-    }
-    if (!::storeKey(tmp_path, auth, key)) return false;
-    if (rename(tmp_path.c_str(), key_path.c_str()) != 0) {
-        PLOG(ERROR) << "Unable to move new key to location: " << key_path;
-        return false;
-    }
-    LOG(DEBUG) << "Created key: " << key_path;
-    return true;
-}
-
-bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, KeyBuffer* key,
-                 bool keepOld) {
-    std::string version;
-    if (!readFileToString(dir + "/" + kFn_version, &version)) return false;
-    if (version != kCurrentVersion) {
-        LOG(ERROR) << "Version mismatch, expected " << kCurrentVersion << " got " << version;
-        return false;
-    }
-    std::string secdiscardable_hash;
-    if (!readSecdiscardable(dir + "/" + kFn_secdiscardable, &secdiscardable_hash)) return false;
-    std::string stretching;
-    if (!readFileToString(dir + "/" + kFn_stretching, &stretching)) return false;
-    std::string salt;
-    if (stretchingNeedsSalt(stretching)) {
-        if (!readFileToString(dir + "/" + kFn_salt, &salt)) return false;
-    }
-    std::string appId;
-    if (!generateAppId(auth, stretching, salt, secdiscardable_hash, &appId)) return false;
-    std::string encryptedMessage;
-    if (!readFileToString(dir + "/" + kFn_encrypted_key, &encryptedMessage)) return false;
-    if (auth.usesKeymaster()) {
-        Keymaster keymaster;
-        if (!keymaster) return false;
-        km::AuthorizationSet keyParams;
-        km::HardwareAuthToken authToken;
-        std::tie(keyParams, authToken) = beginParams(auth, appId);
-        if (!decryptWithKeymasterKey(keymaster, dir, keyParams, authToken, encryptedMessage, key,
-                                     keepOld))
-            return false;
-    } else {
-        if (!decryptWithoutKeymaster(appId, encryptedMessage, key)) return false;
-    }
-    return true;
-}
-
-static bool deleteKey(const std::string& dir) {
-    std::string kmKey;
-    if (!readFileToString(dir + "/" + kFn_keymaster_key_blob, &kmKey)) return false;
-    // In A12 keymaster_key_blob format changed:
-    // it have useless for us bytes in beginning, so remove them to correctly handle key
-    if (!kmKey.compare(0, kPkmBlob.size(), kPkmBlob))
-        kmKey.erase(0, kPkmBlob.size());
-    Keymaster keymaster;
-    if (!keymaster) return false;
-    if (!keymaster.deleteKey(kmKey)) return false;
-    return true;
-}
-
-bool runSecdiscardSingle(const std::string& file) {
-    if (ForkExecvp(std::vector<std::string>{kSecdiscardPath, "--", file}) != 0) {
-        LOG(ERROR) << "secdiscard failed";
-        return false;
-    }
-    return true;
-}
-
-static bool recursiveDeleteKey(const std::string& dir) {
-    if (ForkExecvp(std::vector<std::string>{kRmPath, "-rf", dir}) != 0) {
-        LOG(ERROR) << "recursive delete failed";
-        return false;
-    }
-    return true;
-}
-
-bool destroyKey(const std::string& dir) {
-    bool success = true;
-    // Try each thing, even if previous things failed.
-    bool uses_km = pathExists(dir + "/" + kFn_keymaster_key_blob);
-    if (uses_km) {
-        success &= deleteKey(dir);
-    }
-    auto secdiscard_cmd = std::vector<std::string>{
-        kSecdiscardPath,
-        "--",
-        dir + "/" + kFn_encrypted_key,
-        dir + "/" + kFn_secdiscardable,
-    };
-    if (uses_km) {
-        secdiscard_cmd.emplace_back(dir + "/" + kFn_keymaster_key_blob);
-    }
-    if (ForkExecvp(secdiscard_cmd) != 0) {
-        LOG(ERROR) << "secdiscard failed";
-        success = false;
-    }
-    success &= recursiveDeleteKey(dir);
-    return success;
-}
diff --git a/crypto/fscrypt/KeyStorage.h b/crypto/fscrypt/KeyStorage.h
deleted file mode 100755
index 2c88820..0000000
--- a/crypto/fscrypt/KeyStorage.h
+++ /dev/null
@@ -1,75 +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 ANDROID_VOLD_KEYSTORAGE_H
-#define ANDROID_VOLD_KEYSTORAGE_H
-
-#include "KeyBuffer.h"
-
-#include <string>
-
-
-// Represents the information needed to decrypt a disk encryption key.
-// If "token" is nonempty, it is passed in as a required Gatekeeper auth token.
-// If "token" and "secret" are nonempty, "secret" is appended to the application-specific
-// binary needed to unlock.
-// If only "secret" is nonempty, it is used to decrypt in a non-Keymaster process.
-class KeyAuthentication {
-  public:
-    KeyAuthentication(const std::string& t, const std::string& s) : token{t}, secret{s} {};
-
-    bool usesKeymaster() const { return !token.empty() || secret.empty(); };
-
-    const std::string token;
-    const std::string secret;
-};
-
-extern const KeyAuthentication kEmptyAuthentication;
-
-// Checks if path "path" exists.
-bool pathExists(const std::string& path);
-
-bool createSecdiscardable(const std::string& path, std::string* hash);
-bool readSecdiscardable(const std::string& path, std::string* hash);
-
-// Create a directory at the named path, and store "key" in it,
-// in such a way that it can only be retrieved via Keymaster and
-// can be securely deleted.
-// It's safe to move/rename the directory after creation.
-bool storeKey(const std::string& dir, const KeyAuthentication& auth, const KeyBuffer& key);
-
-// Create a directory at the named path, and store "key" in it as storeKey
-// This version creates the key in "tmp_path" then atomically renames "tmp_path"
-// to "key_path" thereby ensuring that the key is either stored entirely or
-// not at all.
-bool storeKeyAtomically(const std::string& key_path, const std::string& tmp_path,
-                        const KeyAuthentication& auth, const KeyBuffer& key);
-
-// Retrieve the key from the named directory.
-bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, KeyBuffer* key,
-                 bool keepOld);
-
-// Securely destroy the key stored in the named directory and delete the directory.
-bool destroyKey(const std::string& dir);
-
-bool runSecdiscardSingle(const std::string& file);
-
-// Generate wrapped storage key using keymaster. Uses STORAGE_KEY tag in keymaster.
-bool generateWrappedStorageKey(KeyBuffer* key);
-// Export the per-boot boot wrapped storage key using keymaster.
-bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key);
-
-#endif
diff --git a/crypto/fscrypt/KeyUtil.cpp b/crypto/fscrypt/KeyUtil.cpp
deleted file mode 100755
index b7119a6..0000000
--- a/crypto/fscrypt/KeyUtil.cpp
+++ /dev/null
@@ -1,445 +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.
- */
-
-#include "KeyUtil.h"
-
-#include <iomanip>
-#include <sstream>
-#include <string>
-
-#include <fcntl.h>
-#include <linux/fscrypt.h>
-#include <openssl/sha.h>
-#include <sys/ioctl.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <keyutils.h>
-
-#include <fscrypt_uapi.h>
-#include "FsCrypt.h"
-#include "KeyStorage.h"
-#include "Utils.h"
-
-
-const KeyGeneration neverGen() {
-    return KeyGeneration{0, false, false};
-}
-
-static bool randomKey(size_t size, KeyBuffer* key) {
-    *key = KeyBuffer(size);
-    if (ReadRandomBytes(key->size(), key->data()) != 0) {
-        // TODO status_t plays badly with PLOG, fix it.
-        LOG(ERROR) << "Random read failed";
-        return false;
-    }
-    return true;
-}
-
-bool generateStorageKey(const KeyGeneration& gen, KeyBuffer* key) {
-    if (!gen.allow_gen) return false;
-    if (gen.use_hw_wrapped_key) {
-        if (gen.keysize != FSCRYPT_MAX_KEY_SIZE) {
-            LOG(ERROR) << "Cannot generate a wrapped key " << gen.keysize << " bytes long";
-            return false;
-        }
-        return generateWrappedStorageKey(key);
-    } else {
-        return randomKey(gen.keysize, key);
-    }
-}
-
-// Return true if the kernel supports the ioctls to add/remove fscrypt keys
-// directly to/from the filesystem.
-bool isFsKeyringSupported(void) {
-    static bool initialized = false;
-    static bool supported;
-
-    if (!initialized) {
-        android::base::unique_fd fd(open("/data", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
-
-        // FS_IOC_ADD_ENCRYPTION_KEY with a NULL argument will fail with ENOTTY
-        // if the ioctl isn't supported.  Otherwise it will fail with another
-        // error code such as EFAULT.
-        errno = 0;
-        (void)ioctl(fd, FS_IOC_ADD_ENCRYPTION_KEY, NULL);
-        if (errno == ENOTTY) {
-            LOG(INFO) << "Kernel doesn't support FS_IOC_ADD_ENCRYPTION_KEY.  Falling back to "
-                         "session keyring";
-            supported = false;
-        } else {
-            if (errno != EFAULT) {
-                PLOG(WARNING) << "Unexpected error from FS_IOC_ADD_ENCRYPTION_KEY";
-            }
-            LOG(INFO) << "Detected support for FS_IOC_ADD_ENCRYPTION_KEY";
-            supported = true;
-            android::base::SetProperty("ro.crypto.uses_fs_ioc_add_encryption_key", "true");
-        }
-        // There's no need to check for FS_IOC_REMOVE_ENCRYPTION_KEY, since it's
-        // guaranteed to be available if FS_IOC_ADD_ENCRYPTION_KEY is.  There's
-        // also no need to check for support on external volumes separately from
-        // /data, since either the kernel supports the ioctls on all
-        // fscrypt-capable filesystems or it doesn't.
-
-        initialized = true;
-    }
-    return supported;
-}
-
-// Get raw keyref - used to make keyname and to pass to ioctl
-static std::string generateKeyRef(const uint8_t* key, int length) {
-    SHA512_CTX c;
-
-    SHA512_Init(&c);
-    SHA512_Update(&c, key, length);
-    unsigned char key_ref1[SHA512_DIGEST_LENGTH];
-    SHA512_Final(key_ref1, &c);
-
-    SHA512_Init(&c);
-    SHA512_Update(&c, key_ref1, SHA512_DIGEST_LENGTH);
-    unsigned char key_ref2[SHA512_DIGEST_LENGTH];
-    SHA512_Final(key_ref2, &c);
-
-    static_assert(FSCRYPT_KEY_DESCRIPTOR_SIZE <= SHA512_DIGEST_LENGTH,
-                  "Hash too short for descriptor");
-    return std::string((char*)key_ref2, FSCRYPT_KEY_DESCRIPTOR_SIZE);
-}
-
-static bool fillKey(const KeyBuffer& key, fscrypt_key* fs_key) {
-    if (key.size() != FSCRYPT_MAX_KEY_SIZE) {
-        LOG(ERROR) << "Wrong size key " << key.size();
-        return false;
-    }
-    static_assert(FSCRYPT_MAX_KEY_SIZE == sizeof(fs_key->raw), "Mismatch of max key sizes");
-    fs_key->mode = 0;  // unused by kernel
-    memcpy(fs_key->raw, key.data(), key.size());
-    fs_key->size = key.size();
-    return true;
-}
-
-static char const* const NAME_PREFIXES[] = {"ext4", "f2fs", "fscrypt", nullptr};
-
-static std::string keyrefstring(const std::string& raw_ref) {
-    std::ostringstream o;
-    for (unsigned char i : raw_ref) {
-        o << std::hex << std::setw(2) << std::setfill('0') << (int)i;
-    }
-    return o.str();
-}
-
-static std::string buildLegacyKeyName(const std::string& prefix, const std::string& raw_ref) {
-    return prefix + ":" + keyrefstring(raw_ref);
-}
-
-// Get the ID of the keyring we store all fscrypt keys in when the kernel is too
-// old to support FS_IOC_ADD_ENCRYPTION_KEY and FS_IOC_REMOVE_ENCRYPTION_KEY.
-static bool fscryptKeyring(key_serial_t* device_keyring) {
-    *device_keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring", "fscrypt", 0);
-    if (*device_keyring == -1) {
-        PLOG(ERROR) << "Unable to find device keyring";
-        return false;
-    }
-    return true;
-}
-
-// Add an encryption key of type "logon" to the global session keyring.
-static bool installKeyLegacy(const KeyBuffer& key, const std::string& raw_ref) {
-    // Place fscrypt_key into automatically zeroing buffer.
-    KeyBuffer fsKeyBuffer(sizeof(fscrypt_key));
-    fscrypt_key& fs_key = *reinterpret_cast<fscrypt_key*>(fsKeyBuffer.data());
-
-    if (!fillKey(key, &fs_key)) return false;
-    key_serial_t device_keyring;
-    if (!fscryptKeyring(&device_keyring)) return false;
-    for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
-        auto ref = buildLegacyKeyName(*name_prefix, raw_ref);
-        key_serial_t key_id =
-            add_key("logon", ref.c_str(), (void*)&fs_key, sizeof(fs_key), device_keyring);
-        if (key_id == -1) {
-            PLOG(ERROR) << "Failed to insert key into keyring " << device_keyring;
-            return false;
-        }
-        LOG(INFO) << "Added key " << key_id << " (" << ref << ") to keyring " << device_keyring
-                   << " in process " << getpid();
-    }
-    return true;
-}
-
-// Installs fscrypt-provisioning key into session level kernel keyring.
-// This allows for the given key to be installed back into filesystem keyring.
-// For more context see reloadKeyFromSessionKeyring.
-static bool installProvisioningKey(const KeyBuffer& key, const std::string& ref,
-                                   const fscrypt_key_specifier& key_spec) {
-    key_serial_t device_keyring;
-    if (!fscryptKeyring(&device_keyring)) return false;
-
-    // Place fscrypt_provisioning_key_payload into automatically zeroing buffer.
-    KeyBuffer buf(sizeof(fscrypt_provisioning_key_payload) + key.size(), 0);
-    fscrypt_provisioning_key_payload& provisioning_key =
-            *reinterpret_cast<fscrypt_provisioning_key_payload*>(buf.data());
-    memcpy(provisioning_key.raw, key.data(), key.size());
-    provisioning_key.type = key_spec.type;
-
-    key_serial_t key_id = add_key("fscrypt-provisioning", ref.c_str(), (void*)&provisioning_key,
-                                  buf.size(), device_keyring);
-    if (key_id == -1) {
-        PLOG(ERROR) << "Failed to insert fscrypt-provisioning key for " << ref
-                    << " into session keyring";
-        return false;
-    }
-    LOG(INFO) << "Added fscrypt-provisioning key for " << ref << " to session keyring";
-    return true;
-}
-
-// Build a struct fscrypt_key_specifier for use in the key management ioctls.
-static bool buildKeySpecifier(fscrypt_key_specifier* spec, const EncryptionPolicy& policy) {
-    switch (policy.options.version) {
-        case 1:
-            if (policy.key_raw_ref.size() != FSCRYPT_KEY_DESCRIPTOR_SIZE) {
-                LOG(ERROR) << "Invalid key specifier size for v1 encryption policy: "
-                           << policy.key_raw_ref.size();
-                return false;
-            }
-            spec->type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR;
-            memcpy(spec->u.descriptor, policy.key_raw_ref.c_str(), FSCRYPT_KEY_DESCRIPTOR_SIZE);
-            return true;
-        case 2:
-            if (policy.key_raw_ref.size() != FSCRYPT_KEY_IDENTIFIER_SIZE) {
-                LOG(ERROR) << "Invalid key specifier size for v2 encryption policy: "
-                           << policy.key_raw_ref.size();
-                return false;
-            }
-            spec->type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
-            memcpy(spec->u.identifier, policy.key_raw_ref.c_str(), FSCRYPT_KEY_IDENTIFIER_SIZE);
-            return true;
-        default:
-            LOG(ERROR) << "Invalid encryption policy version: " << policy.options.version;
-            return false;
-    }
-}
-
-// Installs key into keyring of a filesystem mounted on |mountpoint|.
-//
-// It's callers responsibility to fill key specifier, and either arg->raw or arg->key_id.
-//
-// In case arg->key_spec.type equals to FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER
-// arg->key_spec.u.identifier will be populated with raw key reference generated
-// by kernel.
-//
-// For documentation on difference between arg->raw and arg->key_id see
-// https://www.kernel.org/doc/html/latest/filesystems/fscrypt.html#fs-ioc-add-encryption-key
-static bool installFsKeyringKey(const std::string& mountpoint, const EncryptionOptions& options,
-                                fscrypt_add_key_arg* arg) {
-    if (options.use_hw_wrapped_key) arg->flags |= FSCRYPT_ADD_KEY_FLAG_WRAPPED;
-
-    android::base::unique_fd fd(open(mountpoint.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open " << mountpoint << " to install key";
-        return false;
-    }
-
-    if (ioctl(fd, FS_IOC_ADD_ENCRYPTION_KEY, arg) != 0) {
-        PLOG(ERROR) << "Failed to install fscrypt key to " << mountpoint;
-        return false;
-    }
-
-    return true;
-}
-
-bool installKey(const std::string& mountpoint, const EncryptionOptions& options,
-                const KeyBuffer& key, EncryptionPolicy* policy) {
-    policy->options = options;
-    // Put the fscrypt_add_key_arg in an automatically-zeroing buffer, since we
-    // have to copy the raw key into it.
-    KeyBuffer arg_buf(sizeof(struct fscrypt_add_key_arg) + key.size(), 0);
-    struct fscrypt_add_key_arg* arg = (struct fscrypt_add_key_arg*)arg_buf.data();
-
-    // Initialize the "key specifier", which is like a name for the key.
-    switch (options.version) {
-        case 1:
-            // A key for a v1 policy is specified by an arbitrary 8-byte
-            // "descriptor", which must be provided by userspace.  We use the
-            // first 8 bytes from the double SHA-512 of the key itself.
-            if (options.use_hw_wrapped_key) {
-                // When wrapped key is supported, only the first 32 bytes are
-                // the same per boot. The second 32 bytes can change as the ephemeral
-                // key is different.
-                policy->key_raw_ref = generateKeyRef((const uint8_t*)key.data(), key.size()/2);
-            } else {
-                policy->key_raw_ref = generateKeyRef((const uint8_t*)key.data(), key.size());
-            }
-            if (!isFsKeyringSupported()) {
-                return installKeyLegacy(key, policy->key_raw_ref);
-            }
-            if (!buildKeySpecifier(&arg->key_spec, *policy)) {
-                return false;
-            }
-            break;
-        case 2:
-            // A key for a v2 policy is specified by an 16-byte "identifier",
-            // which is a cryptographic hash of the key itself which the kernel
-            // computes and returns.  Any user-provided value is ignored; we
-            // just need to set the specifier type to indicate that we're adding
-            // this type of key.
-            arg->key_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
-            break;
-        default:
-            LOG(ERROR) << "Invalid encryption policy version: " << options.version;
-            return false;
-    }
-
-    arg->raw_size = key.size();
-    memcpy(arg->raw, key.data(), key.size());
-
-    if (!installFsKeyringKey(mountpoint, options, arg)) return false;
-
-    if (arg->key_spec.type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
-        // Retrieve the key identifier that the kernel computed.
-        policy->key_raw_ref =
-                std::string((char*)arg->key_spec.u.identifier, FSCRYPT_KEY_IDENTIFIER_SIZE);
-    }
-    std::string ref = keyrefstring(policy->key_raw_ref);
-    LOG(INFO) << "Installed fscrypt key with ref " << ref << " to " << mountpoint;
-
-    if (!installProvisioningKey(key, ref, arg->key_spec)) return false;
-    return true;
-}
-
-// Remove an encryption key of type "logon" from the global session keyring.
-static bool evictKeyLegacy(const std::string& raw_ref) {
-    key_serial_t device_keyring;
-    if (!fscryptKeyring(&device_keyring)) return false;
-    bool success = true;
-    for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
-        auto ref = buildLegacyKeyName(*name_prefix, raw_ref);
-        auto key_serial = keyctl_search(device_keyring, "logon", ref.c_str(), 0);
-
-        // Unlink the key from the keyring.  Prefer unlinking to revoking or
-        // invalidating, since unlinking is actually no less secure currently, and
-        // it avoids bugs in certain kernel versions where the keyring key is
-        // referenced from places it shouldn't be.
-        if (keyctl_unlink(key_serial, device_keyring) != 0) {
-            PLOG(ERROR) << "Failed to unlink key with serial " << key_serial << " ref " << ref;
-            success = false;
-        } else {
-            LOG(ERROR) << "Unlinked key with serial " << key_serial << " ref " << ref;
-        }
-    }
-    return success;
-}
-
-static bool evictProvisioningKey(const std::string& ref) {
-    key_serial_t device_keyring;
-    if (!fscryptKeyring(&device_keyring)) {
-        return false;
-    }
-
-    auto key_serial = keyctl_search(device_keyring, "fscrypt-provisioning", ref.c_str(), 0);
-    if (key_serial == -1 && errno != ENOKEY) {
-        PLOG(ERROR) << "Error searching session keyring for fscrypt-provisioning key for " << ref;
-        return false;
-    }
-
-    if (key_serial != -1 && keyctl_unlink(key_serial, device_keyring) != 0) {
-        PLOG(ERROR) << "Failed to unlink fscrypt-provisioning key for " << ref
-                    << " from session keyring";
-        return false;
-    }
-    return true;
-}
-
-bool evictKey(const std::string& mountpoint, const EncryptionPolicy& policy) {
-    if (policy.options.version == 1 && !isFsKeyringSupported()) {
-        return evictKeyLegacy(policy.key_raw_ref);
-    }
-
-    android::base::unique_fd fd(open(mountpoint.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open " << mountpoint << " to evict key";
-        return false;
-    }
-
-    struct fscrypt_remove_key_arg arg;
-    memset(&arg, 0, sizeof(arg));
-
-    if (!buildKeySpecifier(&arg.key_spec, policy)) {
-        return false;
-    }
-
-    std::string ref = keyrefstring(policy.key_raw_ref);
-
-    if (ioctl(fd, FS_IOC_REMOVE_ENCRYPTION_KEY, &arg) != 0) {
-        PLOG(ERROR) << "Failed to evict fscrypt key with ref " << ref << " from " << mountpoint;
-        return false;
-    }
-
-    LOG(ERROR) << "Evicted fscrypt key with ref " << ref << " from " << mountpoint;
-    if (arg.removal_status_flags & FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS) {
-        // Should never happen because keys are only added/removed as root.
-        LOG(ERROR) << "Unexpected case: key with ref " << ref << " is still added by other users!";
-    } else if (arg.removal_status_flags & FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY) {
-        LOG(ERROR) << "Files still open after removing key with ref " << ref
-                   << ".  These files were not locked!";
-    }
-
-    if (!evictProvisioningKey(ref)) return false;
-    return true;
-}
-
-bool retrieveOrGenerateKey(const std::string& key_path, const std::string& tmp_path,
-                           const KeyAuthentication& key_authentication, const KeyGeneration& gen,
-                           KeyBuffer* key, bool keepOld) {
-    if (pathExists(key_path)) {
-        LOG(INFO) << "Key exists, using: " << key_path;
-        if (!retrieveKey(key_path, key_authentication, key, keepOld)) return false;
-    } else {
-        if (!gen.allow_gen) {
-            LOG(ERROR) << "No key found in " << key_path;
-            return false;
-        }
-        LOG(INFO) << "Creating new key in " << key_path;
-        if (!::generateStorageKey(gen, key)) return false;
-        if (!storeKeyAtomically(key_path, tmp_path, key_authentication, *key)) return false;
-    }
-    return true;
-}
-
-bool reloadKeyFromSessionKeyring(const std::string& mountpoint, const EncryptionPolicy& policy) {
-    key_serial_t device_keyring;
-    if (!fscryptKeyring(&device_keyring)) {
-        return false;
-    }
-
-    std::string ref = keyrefstring(policy.key_raw_ref);
-    auto key_serial = keyctl_search(device_keyring, "fscrypt-provisioning", ref.c_str(), 0);
-    if (key_serial == -1) {
-        PLOG(ERROR) << "Failed to find fscrypt-provisioning key for " << ref
-                    << " in session keyring";
-        return false;
-    }
-
-    LOG(INFO) << "Installing fscrypt-provisioning key for " << ref << " back into " << mountpoint
-               << " fs-keyring";
-
-    struct fscrypt_add_key_arg arg;
-    memset(&arg, 0, sizeof(arg));
-    if (!buildKeySpecifier(&arg.key_spec, policy)) return false;
-    arg.key_id = key_serial;
-    if (!installFsKeyringKey(mountpoint, policy.options, &arg)) return false;
-
-    return true;
-}
diff --git a/crypto/fscrypt/KeyUtil.h b/crypto/fscrypt/KeyUtil.h
deleted file mode 100755
index dcfcde8..0000000
--- a/crypto/fscrypt/KeyUtil.h
+++ /dev/null
@@ -1,83 +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 ANDROID_VOLD_KEYUTIL_H
-#define ANDROID_VOLD_KEYUTIL_H
-
-#include "KeyBuffer.h"
-#include "KeyStorage.h"
-
-#include <fscrypt/fscrypt.h>
-
-#include <memory>
-#include <string>
-
-
-using namespace android::fscrypt;
-
-// Description of how to generate a key when needed.
-struct KeyGeneration {
-    size_t keysize;
-    bool allow_gen;
-    bool use_hw_wrapped_key;
-};
-
-// Generate a key as specified in KeyGeneration
-bool generateStorageKey(const KeyGeneration& gen, KeyBuffer* key);
-
-// Returns a key with allow_gen false so generateStorageKey returns false;
-// this is used to indicate to retrieveOrGenerateKey that a key should not
-// be generated.
-const KeyGeneration neverGen();
-
-bool isFsKeyringSupported(void);
-
-// Install a file-based encryption key to the kernel, for use by encrypted files
-// on the specified filesystem using the specified encryption policy version.
-//
-// For v1 policies, we use FS_IOC_ADD_ENCRYPTION_KEY if the kernel supports it.
-// Otherwise we add the key to the global session keyring as a "logon" key.
-//
-// For v2 policies, we always use FS_IOC_ADD_ENCRYPTION_KEY; it's the only way
-// the kernel supports.
-//
-// If kernel supports FS_IOC_ADD_ENCRYPTION_KEY, also installs key of
-// fscrypt-provisioning type to the global session keyring. This makes it
-// possible to unmount and then remount mountpoint without losing the file-based
-// key.
-//
-// Returns %true on success, %false on failure.  On success also sets *policy
-// to the EncryptionPolicy used to refer to this key.
-bool installKey(const std::string& mountpoint, const EncryptionOptions& options,
-                const KeyBuffer& key, EncryptionPolicy* policy);
-
-// Evict a file-based encryption key from the kernel.
-//
-// This undoes the effect of installKey().
-//
-// If the kernel doesn't support the filesystem-level keyring, the caller is
-// responsible for dropping caches.
-bool evictKey(const std::string& mountpoint, const EncryptionPolicy& policy);
-
-bool retrieveOrGenerateKey(const std::string& key_path, const std::string& tmp_path,
-                           const KeyAuthentication& key_authentication, const KeyGeneration& gen,
-                           KeyBuffer* key, bool keepOld = true);
-
-// Re-installs a file-based encryption key of fscrypt-provisioning type from the
-// global session keyring back into fs keyring of the mountpoint.
-bool reloadKeyFromSessionKeyring(const std::string& mountpoint, const EncryptionPolicy& policy);
-
-#endif
diff --git a/crypto/fscrypt/Keymaster.cpp b/crypto/fscrypt/Keymaster.cpp
deleted file mode 100755
index c5b7bc3..0000000
--- a/crypto/fscrypt/Keymaster.cpp
+++ /dev/null
@@ -1,377 +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.
- */
-
-#include "Keymaster.h"
-
-#include <android-base/logging.h>
-#include <keymasterV4_1/authorization_set.h>
-#include <keymasterV4_1/keymaster_utils.h>
-
-
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::keymaster::V4_0::SecurityLevel;
-
-KeymasterOperation::~KeymasterOperation() {
-    if (mDevice) mDevice->abort(mOpHandle);
-}
-
-bool KeymasterOperation::updateCompletely(const char* input, size_t inputLen,
-                                          const std::function<void(const char*, size_t)> consumer) {
-    uint32_t inputConsumed = 0;
-
-    km::ErrorCode km_error;
-    auto hidlCB = [&](km::ErrorCode ret, uint32_t inputConsumedDelta,
-                      const hidl_vec<km::KeyParameter>& /*ignored*/,
-                      const hidl_vec<uint8_t>& _output) {
-        km_error = ret;
-        if (km_error != km::ErrorCode::OK) return;
-        inputConsumed += inputConsumedDelta;
-        consumer(reinterpret_cast<const char*>(&_output[0]), _output.size());
-    };
-
-    while (inputConsumed != inputLen) {
-        size_t toRead = static_cast<size_t>(inputLen - inputConsumed);
-        auto inputBlob = km::support::blob2hidlVec(
-            reinterpret_cast<const uint8_t*>(&input[inputConsumed]), toRead);
-        auto error = mDevice->update(mOpHandle, hidl_vec<km::KeyParameter>(), inputBlob,
-                                     km::HardwareAuthToken(), km::VerificationToken(), hidlCB);
-        if (!error.isOk()) {
-            LOG(ERROR) << "update failed: " << error.description();
-            mDevice = nullptr;
-            return false;
-        }
-        if (km_error != km::ErrorCode::OK) {
-            LOG(ERROR) << "update failed, code " << int32_t(km_error);
-            mDevice = nullptr;
-            return false;
-        }
-        if (inputConsumed > inputLen) {
-            LOG(ERROR) << "update reported too much input consumed";
-            mDevice = nullptr;
-            return false;
-        }
-    }
-    return true;
-}
-
-bool KeymasterOperation::finish(std::string* output) {
-    km::ErrorCode km_error;
-    auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<km::KeyParameter>& /*ignored*/,
-                      const hidl_vec<uint8_t>& _output) {
-        km_error = ret;
-        if (km_error != km::ErrorCode::OK) return;
-        if (output) output->assign(reinterpret_cast<const char*>(&_output[0]), _output.size());
-    };
-    auto error = mDevice->finish(mOpHandle, hidl_vec<km::KeyParameter>(), hidl_vec<uint8_t>(),
-                                 hidl_vec<uint8_t>(), km::HardwareAuthToken(),
-                                 km::VerificationToken(), hidlCb);
-    mDevice = nullptr;
-    if (!error.isOk()) {
-        LOG(ERROR) << "finish failed: " << error.description();
-        return false;
-    }
-    if (km_error != km::ErrorCode::OK) {
-        LOG(ERROR) << "finish failed, code " << int32_t(km_error);
-        return false;
-    }
-    return true;
-}
-
-/* static */ bool Keymaster::hmacKeyGenerated = false;
-
-Keymaster::Keymaster() {
-    auto devices = KmDevice::enumerateAvailableDevices();
-    if (!hmacKeyGenerated) {
-        KmDevice::performHmacKeyAgreement(devices);
-        hmacKeyGenerated = true;
-    }
-    for (auto& dev : devices) {
-        // Do not use StrongBox for device encryption / credential encryption.  If a security chip
-        // is present it will have Weaver, which already strengthens CE.  We get no additional
-        // benefit from using StrongBox here, so skip it.
-        if (dev->halVersion().securityLevel != SecurityLevel::STRONGBOX) {
-            mDevice = std::move(dev);
-            break;
-        }
-    }
-    if (!mDevice) return;
-    auto& version = mDevice->halVersion();
-    LOG(INFO) << "Using " << version.keymasterName << " from " << version.authorName
-              << " for encryption.  Security level: " << toString(version.securityLevel)
-              << ", HAL: " << mDevice->descriptor() << "/" << mDevice->instanceName();
-}
-
-bool Keymaster::generateKey(const km::AuthorizationSet& inParams, std::string* key) {
-    km::ErrorCode km_error;
-    auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
-                      const km::KeyCharacteristics& /*ignored*/) {
-        km_error = ret;
-        if (km_error != km::ErrorCode::OK) return;
-        if (key) key->assign(reinterpret_cast<const char*>(&keyBlob[0]), keyBlob.size());
-    };
-
-    auto error = mDevice->generateKey(inParams.hidl_data(), hidlCb);
-    if (!error.isOk()) {
-        LOG(ERROR) << "generate_key failed: " << error.description();
-        return false;
-    }
-    if (km_error != km::ErrorCode::OK) {
-        LOG(ERROR) << "generate_key failed, code " << int32_t(km_error);
-        return false;
-    }
-    return true;
-}
-
-km::ErrorCode Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) {
-    auto kmKeyBlob = km::support::blob2hidlVec(std::string(kmKey.data(), kmKey.size()));
-    km::ErrorCode km_error;
-    auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& exportedKeyBlob) {
-        km_error = ret;
-        if (km_error != km::ErrorCode::OK) return;
-        if (key)
-            key->assign(reinterpret_cast<const char*>(&exportedKeyBlob[0]), exportedKeyBlob.size());
-    };
-    auto error = mDevice->exportKey(km::KeyFormat::RAW, kmKeyBlob, {}, {}, hidlCb);
-    if (!error.isOk()) {
-        LOG(ERROR) << "export_key failed: " << error.description();
-        return km::ErrorCode::UNKNOWN_ERROR;
-    }
-    if (km_error != km::ErrorCode::OK) {
-        LOG(ERROR) << "export_key failed, code " << int32_t(km_error);
-        return km_error;
-    }
-    return km::ErrorCode::OK;
-}
-
-bool Keymaster::deleteKey(const std::string& key) {
-    auto keyBlob = km::support::blob2hidlVec(key);
-    auto error = mDevice->deleteKey(keyBlob);
-    if (!error.isOk()) {
-        LOG(ERROR) << "delete_key failed: " << error.description();
-        return false;
-    }
-    if (error != km::ErrorCode::OK) {
-        LOG(ERROR) << "delete_key failed, code " << int32_t(km::ErrorCode(error));
-        return false;
-    }
-    return true;
-}
-
-bool Keymaster::upgradeKey(const std::string& oldKey, const km::AuthorizationSet& inParams,
-                           std::string* newKey) {
-    auto oldKeyBlob = km::support::blob2hidlVec(oldKey);
-    km::ErrorCode km_error;
-    auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
-        km_error = ret;
-        if (km_error != km::ErrorCode::OK) return;
-        if (newKey)
-            newKey->assign(reinterpret_cast<const char*>(&upgradedKeyBlob[0]),
-                           upgradedKeyBlob.size());
-    };
-    auto error = mDevice->upgradeKey(oldKeyBlob, inParams.hidl_data(), hidlCb);
-    if (!error.isOk()) {
-        LOG(ERROR) << "upgrade_key failed: " << error.description();
-        return false;
-    }
-    if (km_error != km::ErrorCode::OK) {
-        LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error);
-        return false;
-    }
-    return true;
-}
-
-KeymasterOperation Keymaster::begin(km::KeyPurpose purpose, const std::string& key,
-                                    const km::AuthorizationSet& inParams,
-                                    const km::HardwareAuthToken& authToken,
-                                    km::AuthorizationSet* outParams) {
-    auto keyBlob = km::support::blob2hidlVec(key);
-    uint64_t mOpHandle;
-    km::ErrorCode km_error;
-
-    auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<km::KeyParameter>& _outParams,
-                      uint64_t operationHandle) {
-        km_error = ret;
-        if (km_error != km::ErrorCode::OK) return;
-        if (outParams) *outParams = _outParams;
-        mOpHandle = operationHandle;
-    };
-
-    auto error = mDevice->begin(purpose, keyBlob, inParams.hidl_data(), authToken, hidlCb);
-    if (!error.isOk()) {
-        LOG(ERROR) << "begin failed: " << error.description();
-        return KeymasterOperation(km::ErrorCode::UNKNOWN_ERROR);
-    }
-    if (km_error != km::ErrorCode::OK) {
-        LOG(ERROR) << "begin failed, code " << int32_t(km_error);
-        return KeymasterOperation(km_error);
-    }
-    return KeymasterOperation(mDevice.get(), mOpHandle);
-}
-
-bool Keymaster::isSecure() {
-    return mDevice->halVersion().securityLevel != km::SecurityLevel::SOFTWARE;
-}
-
-void Keymaster::earlyBootEnded() {
-    auto devices = KmDevice::enumerateAvailableDevices();
-    for (auto& dev : devices) {
-        auto error = dev->earlyBootEnded();
-        if (!error.isOk()) {
-            LOG(ERROR) << "earlyBootEnded call failed: " << error.description() << " for "
-                       << dev->halVersion().keymasterName;
-        }
-        km::V4_1_ErrorCode km_error = error;
-        if (km_error != km::V4_1_ErrorCode::OK && km_error != km::V4_1_ErrorCode::UNIMPLEMENTED) {
-            LOG(ERROR) << "Error reporting early boot ending to keymaster: "
-                       << static_cast<int32_t>(km_error) << " for "
-                       << dev->halVersion().keymasterName;
-        }
-    }
-}
-
-int keymaster_compatibility_cryptfs_scrypt() {
-    Keymaster dev;
-    if (!dev) {
-        LOG(ERROR) << "Failed to initiate keymaster session";
-        return -1;
-    }
-    return dev.isSecure();
-}
-
-static bool write_string_to_buf(const std::string& towrite, uint8_t* buffer, uint32_t buffer_size,
-                                uint32_t* out_size) {
-    if (!buffer || !out_size) {
-        LOG(ERROR) << "Missing target pointers";
-        return false;
-    }
-    *out_size = towrite.size();
-    if (buffer_size < towrite.size()) {
-        LOG(ERROR) << "Buffer too small " << buffer_size << " < " << towrite.size();
-        return false;
-    }
-    memset(buffer, '\0', buffer_size);
-    std::copy(towrite.begin(), towrite.end(), buffer);
-    return true;
-}
-
-static km::AuthorizationSet keyParams(uint32_t rsa_key_size, uint64_t rsa_exponent,
-                                      uint32_t ratelimit) {
-    return km::AuthorizationSetBuilder()
-        .RsaSigningKey(rsa_key_size, rsa_exponent)
-        .NoDigestOrPadding()
-        .Authorization(km::TAG_BLOB_USAGE_REQUIREMENTS, km::KeyBlobUsageRequirements::STANDALONE)
-        .Authorization(km::TAG_NO_AUTH_REQUIRED)
-        .Authorization(km::TAG_MIN_SECONDS_BETWEEN_OPS, ratelimit);
-}
-
-int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
-                                            uint32_t ratelimit, uint8_t* key_buffer,
-                                            uint32_t key_buffer_size, uint32_t* key_out_size) {
-    if (key_out_size) {
-        *key_out_size = 0;
-    }
-    Keymaster dev;
-    if (!dev) {
-        LOG(ERROR) << "Failed to initiate keymaster session";
-        return -1;
-    }
-    std::string key;
-    if (!dev.generateKey(keyParams(rsa_key_size, rsa_exponent, ratelimit), &key)) return -1;
-    if (!write_string_to_buf(key, key_buffer, key_buffer_size, key_out_size)) return -1;
-    return 0;
-}
-
-int keymaster_upgrade_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
-                                             uint32_t ratelimit, const uint8_t* key_blob,
-                                             size_t key_blob_size, uint8_t* key_buffer,
-                                             uint32_t key_buffer_size, uint32_t* key_out_size) {
-    if (key_out_size) {
-        *key_out_size = 0;
-    }
-    Keymaster dev;
-    if (!dev) {
-        LOG(ERROR) << "Failed to initiate keymaster session";
-        return -1;
-    }
-    std::string old_key(reinterpret_cast<const char*>(key_blob), key_blob_size);
-    std::string new_key;
-    if (!dev.upgradeKey(old_key, keyParams(rsa_key_size, rsa_exponent, ratelimit), &new_key))
-        return -1;
-    if (!write_string_to_buf(new_key, key_buffer, key_buffer_size, key_out_size)) return -1;
-    return 0;
-}
-
-KeymasterSignResult keymaster_sign_object_for_cryptfs_scrypt(
-    const uint8_t* key_blob, size_t key_blob_size, uint32_t ratelimit, const uint8_t* object,
-    const size_t object_size, uint8_t** signature_buffer, size_t* signature_buffer_size) {
-    Keymaster dev;
-    if (!dev) {
-        LOG(ERROR) << "Failed to initiate keymaster session";
-        return KeymasterSignResult::error;
-    }
-    if (!key_blob || !object || !signature_buffer || !signature_buffer_size) {
-        LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
-        return KeymasterSignResult::error;
-    }
-
-    km::AuthorizationSet outParams;
-    std::string key(reinterpret_cast<const char*>(key_blob), key_blob_size);
-    std::string input(reinterpret_cast<const char*>(object), object_size);
-    std::string output;
-    KeymasterOperation op;
-
-    auto paramBuilder = km::AuthorizationSetBuilder().NoDigestOrPadding();
-    while (true) {
-        op = dev.begin(km::KeyPurpose::SIGN, key, paramBuilder, km::HardwareAuthToken(), &outParams);
-        if (op.errorCode() == km::ErrorCode::KEY_RATE_LIMIT_EXCEEDED) {
-            sleep(ratelimit);
-            continue;
-        } else
-            break;
-    }
-
-    if (op.errorCode() == km::ErrorCode::KEY_REQUIRES_UPGRADE) {
-        LOG(ERROR) << "Keymaster key requires upgrade";
-        return KeymasterSignResult::upgrade;
-    }
-
-    if (op.errorCode() != km::ErrorCode::OK) {
-        LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode());
-        return KeymasterSignResult::error;
-    }
-
-    if (!op.updateCompletely(input, &output)) {
-        LOG(ERROR) << "Error sending data to keymaster signature transaction: "
-                   << uint32_t(op.errorCode());
-        return KeymasterSignResult::error;
-    }
-
-    if (!op.finish(&output)) {
-        LOG(ERROR) << "Error finalizing keymaster signature transaction: "
-                   << int32_t(op.errorCode());
-        return KeymasterSignResult::error;
-    }
-
-    *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size()));
-    if (*signature_buffer == nullptr) {
-        LOG(ERROR) << "Error allocation buffer for keymaster signature";
-        return KeymasterSignResult::error;
-    }
-    *signature_buffer_size = output.size();
-    std::copy(output.data(), output.data() + output.size(), *signature_buffer);
-    return KeymasterSignResult::ok;
-}
diff --git a/crypto/fscrypt/Keymaster.h b/crypto/fscrypt/Keymaster.h
deleted file mode 100644
index 6f74db4..0000000
--- a/crypto/fscrypt/Keymaster.h
+++ /dev/null
@@ -1,171 +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 ANDROID_VOLD_KEYMASTER_H
-#define ANDROID_VOLD_KEYMASTER_H
-
-#include "KeyBuffer.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <android-base/macros.h>
-#include <keymasterV4_1/Keymaster.h>
-#include <keymasterV4_1/authorization_set.h>
-
-namespace km {
-
-using namespace ::android::hardware::keymaster::V4_1;
-
-// Surprisingly -- to me, at least -- this is totally fine.  You can re-define symbols that were
-// brought in via a using directive (the "using namespace") above.  In general this seems like a
-// dangerous thing to rely on, but in this case its implications are simple and straightforward:
-// km::ErrorCode refers to the 4.0 ErrorCode, though we pull everything else from 4.1.
-using ErrorCode = ::android::hardware::keymaster::V4_0::ErrorCode;
-using V4_1_ErrorCode = ::android::hardware::keymaster::V4_1::ErrorCode;
-
-}  // namespace km
-
-using KmDevice = km::support::Keymaster;
-
-// C++ wrappers to the Keymaster hidl interface.
-// This is tailored to the needs of KeyStorage, but could be extended to be
-// a more general interface.
-
-// Wrapper for a Keymaster operation handle representing an
-// ongoing Keymaster operation.  Aborts the operation
-// in the destructor if it is unfinished. Methods log failures
-// to LOG(ERROR).
-class KeymasterOperation {
-  public:
-    ~KeymasterOperation();
-    // Is this instance valid? This is false if creation fails, and becomes
-    // false on finish or if an update fails.
-    explicit operator bool() const { return mError == km::ErrorCode::OK; }
-    km::ErrorCode errorCode() const { return mError; }
-    // Call "update" repeatedly until all of the input is consumed, and
-    // concatenate the output. Return true on success.
-    template <class TI, class TO>
-    bool updateCompletely(TI& input, TO* output) {
-        if (output) output->clear();
-        return updateCompletely(input.data(), input.size(), [&](const char* b, size_t n) {
-            if (output) std::copy(b, b + n, std::back_inserter(*output));
-        });
-    }
-
-    // Finish and write the output to this string, unless pointer is null.
-    bool finish(std::string* output);
-    // Move constructor
-    KeymasterOperation(KeymasterOperation&& rhs) { *this = std::move(rhs); }
-    // Construct an object in an error state for error returns
-    KeymasterOperation() : mDevice{nullptr}, mOpHandle{0}, mError{km::ErrorCode::UNKNOWN_ERROR} {}
-    // Move Assignment
-    KeymasterOperation& operator=(KeymasterOperation&& rhs) {
-        mDevice = rhs.mDevice;
-        rhs.mDevice = nullptr;
-
-        mOpHandle = rhs.mOpHandle;
-        rhs.mOpHandle = 0;
-
-        mError = rhs.mError;
-        rhs.mError = km::ErrorCode::UNKNOWN_ERROR;
-
-        return *this;
-    }
-
-  private:
-    KeymasterOperation(KmDevice* d, uint64_t h)
-        : mDevice{d}, mOpHandle{h}, mError{km::ErrorCode::OK} {}
-    KeymasterOperation(km::ErrorCode error) : mDevice{nullptr}, mOpHandle{0}, mError{error} {}
-
-    bool updateCompletely(const char* input, size_t inputLen,
-                          const std::function<void(const char*, size_t)> consumer);
-
-    KmDevice* mDevice;
-    uint64_t mOpHandle;
-    km::ErrorCode mError;
-    DISALLOW_COPY_AND_ASSIGN(KeymasterOperation);
-    friend class Keymaster;
-};
-
-// Wrapper for a Keymaster device for methods that start a KeymasterOperation or are not
-// part of one.
-class Keymaster {
-  public:
-    Keymaster();
-    // false if we failed to open the keymaster device.
-    explicit operator bool() { return mDevice.get() != nullptr; }
-    // Generate a key in the keymaster from the given params.
-    bool generateKey(const km::AuthorizationSet& inParams, std::string* key);
-    // Exports a keymaster key with STORAGE_KEY tag wrapped with a per-boot ephemeral key
-    km::ErrorCode exportKey(const KeyBuffer& kmKey, std::string* key);
-    // If the keymaster supports it, permanently delete a key.
-    bool deleteKey(const std::string& key);
-    // Replace stored key blob in response to KM_ERROR_KEY_REQUIRES_UPGRADE.
-    bool upgradeKey(const std::string& oldKey, const km::AuthorizationSet& inParams,
-                    std::string* newKey);
-    // Begin a new cryptographic operation, collecting output parameters if pointer is non-null
-    KeymasterOperation begin(km::KeyPurpose purpose, const std::string& key,
-                             const km::AuthorizationSet& inParams,
-                             const km::HardwareAuthToken& authToken,
-                             km::AuthorizationSet* outParams);
-    bool isSecure();
-
-    // Tell all Keymaster instances that early boot has ended and early boot-only keys can no longer
-    // be created or used.
-    static void earlyBootEnded();
-
-  private:
-    android::sp<KmDevice> mDevice;
-    DISALLOW_COPY_AND_ASSIGN(Keymaster);
-    static bool hmacKeyGenerated;
-};
-
-// FIXME no longer needed now cryptfs is in C++.
-
-/*
- * The following functions provide C bindings to keymaster services
- * needed by cryptfs scrypt. The compatibility check checks whether
- * the keymaster implementation is considered secure, i.e., TEE backed.
- * The create_key function generates an RSA key for signing.
- * The sign_object function signes an object with the given keymaster
- * key.
- */
-
-/* Return values for keymaster_sign_object_for_cryptfs_scrypt */
-
-enum class KeymasterSignResult {
-    ok = 0,
-    error = -1,
-    upgrade = -2,
-};
-
-int keymaster_compatibility_cryptfs_scrypt();
-int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
-                                            uint32_t ratelimit, uint8_t* key_buffer,
-                                            uint32_t key_buffer_size, uint32_t* key_out_size);
-
-int keymaster_upgrade_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
-                                             uint32_t ratelimit, const uint8_t* key_blob,
-                                             size_t key_blob_size, uint8_t* key_buffer,
-                                             uint32_t key_buffer_size, uint32_t* key_out_size);
-
-KeymasterSignResult keymaster_sign_object_for_cryptfs_scrypt(
-    const uint8_t* key_blob, size_t key_blob_size, uint32_t ratelimit, const uint8_t* object,
-    const size_t object_size, uint8_t** signature_buffer, size_t* signature_buffer_size);
-
-#endif
diff --git a/crypto/fscrypt/MetadataCrypt.cpp b/crypto/fscrypt/MetadataCrypt.cpp
deleted file mode 100755
index 853e81e..0000000
--- a/crypto/fscrypt/MetadataCrypt.cpp
+++ /dev/null
@@ -1,387 +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.
- */
-
-#include "MetadataCrypt.h"
-#include "KeyBuffer.h"
-
-#include <algorithm>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include <fcntl.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-#include <cutils/fs.h>
-#include <fs_mgr.h>
-#include <libdm/dm.h>
-
-#include "Checkpoint.h"
-#include "CryptoType.h"
-#include "EncryptInplace.h"
-#include "FsCrypt.h"
-#include "KeyStorage.h"
-#include "KeyUtil.h"
-#include "Keymaster.h"
-#include "Utils.h"
-#include "VoldUtil.h"
-
-#define TABLE_LOAD_RETRIES 10
-
-
-using android::fs_mgr::FstabEntry;
-using android::fs_mgr::GetEntryForMountPoint;
-using ::KeyBuffer;
-using namespace android::dm;
-
-// Parsed from metadata options
-struct CryptoOptions {
-    struct CryptoType cipher = invalid_crypto_type;
-    bool use_legacy_options_format = false;
-    bool set_dun = true;  // Non-legacy driver always sets DUN
-    bool use_hw_wrapped_key = false;
-};
-
-static const std::string kDmNameUserdata = "userdata";
-
-static const char* kFn_keymaster_key_blob = "keymaster_key_blob";
-static const char* kFn_keymaster_key_blob_upgraded = "keymaster_key_blob_upgraded";
-
-// The first entry in this table is the default crypto type.
-constexpr CryptoType supported_crypto_types[] = {aes_256_xts, adiantum};
-
-static_assert(validateSupportedCryptoTypes(64, supported_crypto_types,
-                                           array_length(supported_crypto_types)),
-              "We have a CryptoType which was incompletely constructed.");
-
-constexpr CryptoType legacy_aes_256_xts =
-        CryptoType().set_config_name("aes-256-xts").set_kernel_name("AES-256-XTS").set_keysize(64);
-
-static_assert(isValidCryptoType(64, legacy_aes_256_xts),
-              "We have a CryptoType which was incompletely constructed.");
-
-// Returns KeyGeneration suitable for key as described in CryptoOptions
-const KeyGeneration makeGen(const CryptoOptions& options) {
-    return KeyGeneration{options.cipher.get_keysize(), true, options.use_hw_wrapped_key};
-}
-
-static bool mount_via_fs_mgr(const char* mount_point, const char* blk_device) {
-    // We're about to mount data not verified by verified boot.  Tell Keymaster instances that early
-    // boot has ended.
-    ::Keymaster::earlyBootEnded();
-
-    // fs_mgr_do_mount runs fsck. Use setexeccon to run trusted
-    // partitions in the fsck domain.
-    if (setexeccon(::sFsckContext)) {
-        PLOG(ERROR) << "Failed to setexeccon";
-        return false;
-    }
-
-    if (fstab_default.empty()) {
-        if (!ReadDefaultFstab(&fstab_default)) {
-            PLOG(ERROR) << "Failed to open default fstab";
-            return -1;
-        }
-    }
-    auto mount_rc = fs_mgr_do_mount(&fstab_default, const_cast<char*>(mount_point),
-                                    const_cast<char*>(blk_device), nullptr,
-                                    ::cp_needsCheckpoint(), true);
-    if (setexeccon(nullptr)) {
-        PLOG(ERROR) << "Failed to clear setexeccon";
-        return false;
-    }
-    if (mount_rc != 0) {
-        LOG(ERROR) << "fs_mgr_do_mount failed with rc " << mount_rc;
-        return false;
-    }
-    LOG(INFO) << "mount_via_fs_mgr::Mounted " << mount_point;
-    return true;
-}
-
-// Note: It is possible to orphan a key if it is removed before deleting
-// Update this once keymaster APIs change, and we have a proper commit.
-static void commit_key(const std::string& dir) {
-    while (!android::base::WaitForProperty("vold.checkpoint_committed", "1")) {
-        LOG(ERROR) << "Wait for boot timed out";
-    }
-    Keymaster keymaster;
-    auto keyPath = dir + "/" + kFn_keymaster_key_blob;
-    auto newKeyPath = dir + "/" + kFn_keymaster_key_blob_upgraded;
-    std::string key;
-
-    if (!android::base::ReadFileToString(keyPath, &key)) {
-        LOG(ERROR) << "Failed to read old key: " << dir;
-        return;
-    }
-    if (rename(newKeyPath.c_str(), keyPath.c_str()) != 0) {
-        PLOG(ERROR) << "Unable to move upgraded key to location: " << keyPath;
-        return;
-    }
-    if (!keymaster.deleteKey(key)) {
-        LOG(ERROR) << "Key deletion failed during upgrade, continuing anyway: " << dir;
-    }
-    LOG(INFO) << "Old Key deleted: " << dir;
-}
-
-static bool read_key(const std::string& metadata_key_dir, const KeyGeneration& gen,
-                     KeyBuffer* key) {
-    if (metadata_key_dir.empty()) {
-        LOG(ERROR) << "Failed to get metadata_key_dir";
-        return false;
-    }
-    std::string sKey;
-    auto dir = metadata_key_dir + "/key";
-    LOG(INFO) << "metadata_key_dir/key: " << dir;
-    if (fs_mkdirs(dir.c_str(), 0700)) {
-        PLOG(ERROR) << "Creating directories: " << dir;
-        return false;
-    }
-    auto temp = metadata_key_dir + "/tmp";
-    auto newKeyPath = dir + "/" + kFn_keymaster_key_blob_upgraded;
-    /* If we have a leftover upgraded key, delete it.
-     * We either failed an update and must return to the old key,
-     * or we rebooted before commiting the keys in a freak accident.
-     * Either way, we can re-upgrade the key if we need to.
-     */
-
-    Keymaster keymaster;
-    if (pathExists(newKeyPath)) {
-        if (!android::base::ReadFileToString(newKeyPath, &sKey))
-            LOG(ERROR) << "Failed to read incomplete key: " << dir;
-        else if (!keymaster.deleteKey(sKey))
-            LOG(ERROR) << "Incomplete key deletion failed, continuing anyway: " << dir;
-        else
-            unlink(newKeyPath.c_str());
-    }
-    bool needs_cp = cp_needsCheckpoint();
-    if (!retrieveOrGenerateKey(dir, temp, kEmptyAuthentication, gen, key, true)) return false;
-    if (needs_cp && pathExists(newKeyPath)) std::thread(commit_key, dir).detach();
-    return true;
-}
-
-static bool get_number_of_sectors(const std::string& real_blkdev, uint64_t* nr_sec) {
-    if (::GetBlockDev512Sectors(real_blkdev, nr_sec) != android::OK) {
-        PLOG(ERROR) << "Unable to measure size of " << real_blkdev;
-        return false;
-    }
-    return true;
-}
-
-static bool create_crypto_blk_dev(const std::string& dm_name, const std::string& blk_device,
-                                  const KeyBuffer& key, const CryptoOptions& options,
-                                  std::string* crypto_blkdev, uint64_t* nr_sec) {
-    if (!get_number_of_sectors(blk_device, nr_sec)) return false;
-    // TODO(paulcrowley): don't hardcode that DmTargetDefaultKey uses 4096-byte
-    // sectors
-    *nr_sec &= ~7;
-
-    KeyBuffer module_key;
-    if (options.use_hw_wrapped_key) {
-        if (!exportWrappedStorageKey(key, &module_key)) {
-            LOG(ERROR) << "Failed to get ephemeral wrapped key";
-            return false;
-        }
-    } else {
-        module_key = key;
-    }
-
-    KeyBuffer hex_key_buffer;
-    if (::StrToHex(module_key, hex_key_buffer) != android::OK) {
-        LOG(ERROR) << "Failed to turn key to hex";
-        return false;
-    }
-    std::string hex_key(hex_key_buffer.data(), hex_key_buffer.size());
-
-    auto target = std::make_unique<DmTargetDefaultKey>(0, *nr_sec, options.cipher.get_kernel_name(),
-                                                       hex_key, blk_device, 0);
-    if (options.use_legacy_options_format) target->SetUseLegacyOptionsFormat();
-    if (options.set_dun) target->SetSetDun();
-    if (options.use_hw_wrapped_key) target->SetWrappedKeyV0();
-
-    DmTable table;
-    table.AddTarget(std::move(target));
-
-    auto& dm = DeviceMapper::Instance();
-    for (int i = 0;; i++) {
-        if (dm.CreateDevice(dm_name, table)) {
-            break;
-        }
-        if (i + 1 >= TABLE_LOAD_RETRIES) {
-            PLOG(ERROR) << "Could not create default-key device " << dm_name;
-            return false;
-        }
-        PLOG(INFO) << "Could not create default-key device, retrying";
-        usleep(500000);
-    }
-
-    if (!dm.GetDmDevicePathByName(dm_name, crypto_blkdev)) {
-        LOG(ERROR) << "Cannot retrieve default-key device status " << dm_name;
-        return false;
-    }
-    std::stringstream ss;
-    ss << *crypto_blkdev;
-    LOG(INFO) << "Created device: " << ss.str();
-    return true;
-}
-
-static const CryptoType& lookup_cipher(const std::string& cipher_name) {
-    if (cipher_name.empty()) return supported_crypto_types[0];
-    for (size_t i = 0; i < array_length(supported_crypto_types); i++) {
-        if (cipher_name == supported_crypto_types[i].get_config_name()) {
-            return supported_crypto_types[i];
-        }
-    }
-    return invalid_crypto_type;
-}
-
-static bool parse_options(const std::string& options_string, CryptoOptions* options) {
-    auto parts = android::base::Split(options_string, ":");
-    if (parts.size() < 1 || parts.size() > 2) {
-        LOG(ERROR) << "Invalid metadata encryption option: " << options_string;
-        return false;
-    }
-    std::string cipher_name = parts[0];
-    options->cipher = lookup_cipher(cipher_name);
-    if (options->cipher.get_kernel_name() == nullptr) {
-        LOG(ERROR) << "No metadata cipher named " << cipher_name << " found";
-        return false;
-    }
-
-    if (parts.size() == 2) {
-        if (parts[1] == "wrappedkey_v0") {
-            options->use_hw_wrapped_key = true;
-        } else {
-            LOG(ERROR) << "Invalid metadata encryption flag: " << parts[1];
-            return false;
-        }
-    }
-    return true;
-}
-
-bool fscrypt_mount_metadata_encrypted(const std::string& blk_device, const std::string& mount_point,
-                                      bool needs_encrypt) {
-    LOG(INFO) << "fscrypt_mount_metadata_encrypted: " << mount_point << " " << needs_encrypt;
-    auto encrypted_state = android::base::GetProperty("ro.crypto.state", "");
-    if (encrypted_state != "" && encrypted_state != "encrypted") {
-        LOG(ERROR) << "fscrypt_enable_crypto got unexpected starting state: " << encrypted_state;
-        return false;
-    }
-    if (fstab_default.empty()) {
-        if (!ReadDefaultFstab(&fstab_default)) {
-            PLOG(ERROR) << "Failed to open default fstab";
-            return -1;
-        }
-    }
-    auto data_rec = GetEntryForMountPoint(&fstab_default, mount_point);
-    if (!data_rec) {
-        LOG(ERROR) << "Failed to get data_rec for " << mount_point;
-        return false;
-    }
-
-    constexpr unsigned int pre_gki_level = 29;
-    unsigned int options_format_version = android::base::GetUintProperty<unsigned int>(
-            "ro.crypto.dm_default_key.options_format.version",
-            (GetFirstApiLevel() <= pre_gki_level ? 1 : 2));
-
-    CryptoOptions options;
-    if (options_format_version == 1) {
-        if (!data_rec->metadata_encryption.empty()) {
-            LOG(ERROR) << "metadata_encryption options cannot be set in legacy mode";
-            return false;
-        }
-        options.cipher = legacy_aes_256_xts;
-        options.use_legacy_options_format = true;
-        if (is_metadata_wrapped_key_supported()) {
-            options.use_hw_wrapped_key = true;
-            LOG(INFO) << "metadata_wrapped_key_true";
-        }
-        options.set_dun = android::base::GetBoolProperty("ro.crypto.set_dun", false);
-        if (!options.set_dun && data_rec->fs_mgr_flags.checkpoint_blk) {
-            LOG(ERROR)
-                    << "Block checkpoints and metadata encryption require ro.crypto.set_dun option";
-            return false;
-        }
-    } else if (options_format_version == 2) {
-        if (!parse_options(data_rec->metadata_encryption, &options)) return false;
-    } else {
-        LOG(ERROR) << "Unknown options_format_version: " << options_format_version;
-        return false;
-    }
-    auto gen = needs_encrypt ? makeGen(options) : neverGen();
-    KeyBuffer key;
-    if (!read_key(data_rec->metadata_key_dir, gen, &key)) return false;
-
-    std::string crypto_blkdev;
-    uint64_t nr_sec;
-    if (!create_crypto_blk_dev(kDmNameUserdata, blk_device, key, options, &crypto_blkdev, &nr_sec))
-        return false;
-
-    // FIXME handle the corrupt case
-    if (needs_encrypt) {
-        LOG(INFO) << "Beginning inplace encryption, nr_sec: " << nr_sec;
-        off64_t size_already_done = 0;
-        auto rc = cryptfs_enable_inplace(crypto_blkdev.data(), blk_device.data(), nr_sec,
-                                         &size_already_done, nr_sec, 0, false);
-        if (rc != 0) {
-            LOG(ERROR) << "Inplace crypto failed with code: " << rc;
-            return false;
-        }
-        if (static_cast<uint64_t>(size_already_done) != nr_sec) {
-            LOG(ERROR) << "Inplace crypto only got up to sector: " << size_already_done;
-            return false;
-        }
-        LOG(INFO) << "Inplace encryption complete";
-    }
-
-    LOG(INFO) << "Mounting metadata-encrypted filesystem:" << mount_point;
-    mount_via_fs_mgr(mount_point.c_str(), crypto_blkdev.c_str());
-    android::base::SetProperty("ro.crypto.fs_crypto_blkdev", crypto_blkdev);
-
-    // Record that there's at least one fstab entry with metadata encryption
-    if (!android::base::SetProperty("ro.crypto.metadata.enabled", "true")) {
-        LOG(WARNING) << "failed to set ro.crypto.metadata.enabled";  // This isn't fatal
-    }
-    return true;
-}
-
-static bool get_volume_options(CryptoOptions* options) {
-    return parse_options(android::base::GetProperty("ro.crypto.volume.metadata.encryption", ""),
-                         options);
-}
-
-bool defaultkey_volume_keygen(KeyGeneration* gen) {
-    CryptoOptions options;
-    if (!get_volume_options(&options)) return false;
-    *gen = makeGen(options);
-    return true;
-}
-
-bool defaultkey_setup_ext_volume(const std::string& label, const std::string& blk_device,
-                                 const KeyBuffer& key, std::string* out_crypto_blkdev) {
-    LOG(ERROR) << "defaultkey_setup_ext_volume: " << label << " " << blk_device;
-
-    CryptoOptions options;
-    if (!get_volume_options(&options)) return false;
-    uint64_t nr_sec;
-    return create_crypto_blk_dev(label, blk_device, key, options, out_crypto_blkdev, &nr_sec);
-}
diff --git a/crypto/fscrypt/MetadataCrypt.h b/crypto/fscrypt/MetadataCrypt.h
deleted file mode 100644
index 0370664..0000000
--- a/crypto/fscrypt/MetadataCrypt.h
+++ /dev/null
@@ -1,35 +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 _METADATA_CRYPT_H
-#define _METADATA_CRYPT_H
-
-#include <string>
-
-#include "KeyBuffer.h"
-#include "KeyUtil.h"
-
-
-bool fscrypt_mount_metadata_encrypted(const std::string& block_device,
-                                      const std::string& mount_point, bool needs_encrypt);
-
-bool defaultkey_volume_keygen(KeyGeneration* gen);
-
-bool defaultkey_setup_ext_volume(const std::string& label, const std::string& blk_device,
-                                 const KeyBuffer& key,
-                                 std::string* out_crypto_blkdev);
-
-#endif
diff --git a/crypto/fscrypt/Process.cpp b/crypto/fscrypt/Process.cpp
deleted file mode 100644
index 277d6a3..0000000
--- a/crypto/fscrypt/Process.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2008 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 <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <fts.h>
-#include <poll.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <fstream>
-#include <mntent.h>
-#include <unordered_set>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include "Process.h"
-
-using android::base::StringPrintf;
-
-namespace android {
-namespace vold {
-
-static bool checkMaps(const std::string& path, const std::string& prefix) {
-    bool found = false;
-    auto file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
-    if (!file) {
-        return false;
-    }
-
-    char* buf = nullptr;
-    size_t len = 0;
-    while (getline(&buf, &len, file.get()) != -1) {
-        std::string line(buf);
-        std::string::size_type pos = line.find('/');
-        if (pos != std::string::npos) {
-            line = line.substr(pos);
-            if (android::base::StartsWith(line, prefix)) {
-                LOG(WARNING) << "Found map " << path << " referencing " << line;
-                found = true;
-                break;
-            }
-        }
-    }
-    free(buf);
-
-    return found;
-}
-
-static bool checkSymlink(const std::string& path, const std::string& prefix) {
-    std::string res;
-    if (android::base::Readlink(path, &res)) {
-        if (android::base::StartsWith(res, prefix)) {
-            LOG(WARNING) << "Found symlink " << path << " referencing " << res;
-            return true;
-        }
-    }
-    return false;
-}
-
-// TODO: Refactor the code with KillProcessesWithOpenFiles().
-int KillProcessesWithMounts(const std::string& prefix, int signal) {
-    std::unordered_set<pid_t> pids;
-
-    auto proc_d = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/proc"), closedir);
-    if (!proc_d) {
-        PLOG(ERROR) << "Failed to open proc";
-        return -1;
-    }
-
-    struct dirent* proc_de;
-    while ((proc_de = readdir(proc_d.get())) != nullptr) {
-        // We only care about valid PIDs
-        pid_t pid;
-        if (proc_de->d_type != DT_DIR) continue;
-        if (!android::base::ParseInt(proc_de->d_name, &pid)) continue;
-
-        // Look for references to prefix
-        std::string mounts_file(StringPrintf("/proc/%d/mounts", pid));
-        auto fp = std::unique_ptr<FILE, int (*)(FILE*)>(
-                setmntent(mounts_file.c_str(), "r"), endmntent);
-        if (!fp) {
-            PLOG(WARNING) << "Failed to open " << mounts_file;
-            continue;
-        }
-
-        // Check if obb directory is mounted, and get all packages of mounted app data directory.
-        mntent* mentry;
-        while ((mentry = getmntent(fp.get())) != nullptr) {
-            if (android::base::StartsWith(mentry->mnt_dir, prefix)) {
-                pids.insert(pid);
-                break;
-            }
-        }
-    }
-    if (signal != 0) {
-        for (const auto& pid : pids) {
-            LOG(WARNING) << "Killing pid "<< pid << " with signal " << strsignal(signal) <<
-                    " because it has a mount with prefix " << prefix;
-            kill(pid, signal);
-        }
-    }
-    return pids.size();
-}
-
-int KillProcessesWithOpenFiles(const std::string& prefix, int signal) {
-    std::unordered_set<pid_t> pids;
-
-    auto proc_d = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/proc"), closedir);
-    if (!proc_d) {
-        PLOG(ERROR) << "Failed to open proc";
-        return -1;
-    }
-
-    struct dirent* proc_de;
-    while ((proc_de = readdir(proc_d.get())) != nullptr) {
-        // We only care about valid PIDs
-        pid_t pid;
-        if (proc_de->d_type != DT_DIR) continue;
-        if (!android::base::ParseInt(proc_de->d_name, &pid)) continue;
-
-        // Look for references to prefix
-        bool found = false;
-        auto path = StringPrintf("/proc/%d", pid);
-        found |= checkMaps(path + "/maps", prefix);
-        found |= checkSymlink(path + "/cwd", prefix);
-        found |= checkSymlink(path + "/root", prefix);
-        found |= checkSymlink(path + "/exe", prefix);
-
-        auto fd_path = path + "/fd";
-        auto fd_d = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(fd_path.c_str()), closedir);
-        if (!fd_d) {
-            PLOG(WARNING) << "Failed to open " << fd_path;
-        } else {
-            struct dirent* fd_de;
-            while ((fd_de = readdir(fd_d.get())) != nullptr) {
-                if (fd_de->d_type != DT_LNK) continue;
-                found |= checkSymlink(fd_path + "/" + fd_de->d_name, prefix);
-            }
-        }
-
-        if (found) {
-            pids.insert(pid);
-        }
-    }
-    if (signal != 0) {
-        for (const auto& pid : pids) {
-            LOG(WARNING) << "Sending " << strsignal(signal) << " to " << pid;
-            kill(pid, signal);
-        }
-    }
-    return pids.size();
-}
-
-}  // namespace vold
-}  // namespace android
diff --git a/crypto/fscrypt/Process.h b/crypto/fscrypt/Process.h
deleted file mode 100644
index 1c59812..0000000
--- a/crypto/fscrypt/Process.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008 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 _PROCESS_H
-#define _PROCESS_H
-
-namespace android {
-namespace vold {
-
-int KillProcessesWithOpenFiles(const std::string& path, int signal);
-int KillProcessesWithMounts(const std::string& path, int signal);
-
-}  // namespace vold
-}  // namespace android
-
-#endif
diff --git a/crypto/fscrypt/ScryptParameters.cpp b/crypto/fscrypt/ScryptParameters.cpp
deleted file mode 100644
index 669809b..0000000
--- a/crypto/fscrypt/ScryptParameters.cpp
+++ /dev/null
@@ -1,50 +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.
- */
-
-#include "ScryptParameters.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-bool parse_scrypt_parameters(const char* paramstr, int *Nf, int *rf, int *pf) {
-    int params[3];
-    char *token;
-    char *saveptr;
-    int i;
-
-    /*
-     * The token we're looking for should be three integers separated by
-     * colons (e.g., "12:8:1"). Scan the property to make sure it matches.
-     */
-    for (i = 0, token = strtok_r(const_cast<char *>(paramstr), ":", &saveptr);
-            token != nullptr && i < 3;
-            i++, token = strtok_r(nullptr, ":", &saveptr)) {
-        char *endptr;
-        params[i] = strtol(token, &endptr, 10);
-
-        /*
-         * Check that there was a valid number and it's 8-bit.
-         */
-        if ((*token == '\0') || (*endptr != '\0') || params[i] < 0 || params[i] > 255) {
-            return false;
-        }
-    }
-    if (token != nullptr) {
-        return false;
-    }
-    *Nf = params[0]; *rf = params[1]; *pf = params[2];
-    return true;
-}
diff --git a/crypto/fscrypt/ScryptParameters.h b/crypto/fscrypt/ScryptParameters.h
deleted file mode 100644
index 1b43ea5..0000000
--- a/crypto/fscrypt/ScryptParameters.h
+++ /dev/null
@@ -1,32 +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 ANDROID_VOLD_SCRYPT_PARAMETERS_H
-#define ANDROID_VOLD_SCRYPT_PARAMETERS_H
-
-#include <stdbool.h>
-#include <sys/cdefs.h>
-
-#define SCRYPT_PROP "ro.crypto.scrypt_params"
-#define SCRYPT_DEFAULTS "15:3:1"
-
-__BEGIN_DECLS
-
-bool parse_scrypt_parameters(const char* paramstr, int *Nf, int *rf, int *pf);
-
-__END_DECLS
-
-#endif
diff --git a/crypto/fscrypt/Utils.cpp b/crypto/fscrypt/Utils.cpp
deleted file mode 100755
index 3b0eda0..0000000
--- a/crypto/fscrypt/Utils.cpp
+++ /dev/null
@@ -1,1622 +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 "Utils.h"
-
-#include "Process.h"
-#include "sehandle.h"
-
-#include <android-base/chrono_utils.h>
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-#include <cutils/fs.h>
-#include <logwrap/logwrap.h>
-#include <private/android_filesystem_config.h>
-#include <private/android_projectid_config.h>
-
-#include <dirent.h>
-#include <fcntl.h>
-#include <linux/fs.h>
-#include <linux/posix_acl.h>
-#include <linux/posix_acl_xattr.h>
-#include <mntent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/sysmacros.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/xattr.h>
-#include <unistd.h>
-
-#include <filesystem>
-#include <list>
-#include <mutex>
-#include <regex>
-#include <thread>
-
-#ifndef UMOUNT_NOFOLLOW
-#define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */
-#endif
-
-using namespace std::chrono_literals;
-using android::base::EndsWith;
-using android::base::ReadFileToString;
-using android::base::StartsWith;
-using android::base::StringPrintf;
-using android::base::unique_fd;
-
-struct selabel_handle* sehandle;
-
-security_context_t sBlkidContext = nullptr;
-security_context_t sBlkidUntrustedContext = nullptr;
-security_context_t sFsckContext = nullptr;
-security_context_t sFsckUntrustedContext = nullptr;
-
-bool sSleepOnUnmount = true;
-
-static const char* kBlkidPath = "/system/bin/blkid";
-static const char* kKeyPath = "/data/misc/vold";
-
-static const char* kProcDevices = "/proc/devices";
-static const char* kProcFilesystems = "/proc/filesystems";
-
-static const char* kAndroidDir = "/Android/";
-static const char* kAppDataDir = "/Android/data/";
-static const char* kAppMediaDir = "/Android/media/";
-static const char* kAppObbDir = "/Android/obb/";
-
-static const char* kMediaProviderCtx = "u:r:mediaprovider:";
-static const char* kMediaProviderAppCtx = "u:r:mediaprovider_app:";
-
-// Lock used to protect process-level SELinux changes from racing with each
-// other between multiple threads.
-static std::mutex kSecurityLock;
-
-std::string GetFuseMountPathForUser(userid_t user_id, const std::string& relative_upper_path) {
-    return StringPrintf("/mnt/user/%d/%s", user_id, relative_upper_path.c_str());
-}
-
-android::status_t CreateDeviceNode(const std::string& path, dev_t dev) {
-    std::lock_guard<std::mutex> lock(kSecurityLock);
-    const char* cpath = path.c_str();
-    android::status_t res = 0;
-
-    char* secontext = nullptr;
-    if (sehandle) {
-        if (!selabel_lookup(sehandle, &secontext, cpath, S_IFBLK)) {
-            setfscreatecon(secontext);
-        }
-    }
-
-    mode_t mode = 0660 | S_IFBLK;
-    if (mknod(cpath, mode, dev) < 0) {
-        if (errno != EEXIST) {
-            PLOG(ERROR) << "Failed to create device node for " << major(dev) << ":" << minor(dev)
-                        << " at " << path;
-            res = -errno;
-        }
-    }
-
-    if (secontext) {
-        setfscreatecon(nullptr);
-        freecon(secontext);
-    }
-
-    return res;
-}
-
-android::status_t DestroyDeviceNode(const std::string& path) {
-    const char* cpath = path.c_str();
-    if (TEMP_FAILURE_RETRY(unlink(cpath))) {
-        return -errno;
-    } else {
-        return android::OK;
-    }
-}
-
-// Sets a default ACL on the directory.
-int SetDefaultAcl(const std::string& path, mode_t mode, uid_t uid, gid_t gid,
-                  std::vector<gid_t> additionalGids) {
-    if (IsSdcardfsUsed()) {
-        // sdcardfs magically takes care of this
-        return android::OK;
-    }
-
-    size_t num_entries = 3 + (additionalGids.size() > 0 ? additionalGids.size() + 1 : 0);
-    size_t size = sizeof(posix_acl_xattr_header) + num_entries * sizeof(posix_acl_xattr_entry);
-    auto buf = std::make_unique<uint8_t[]>(size);
-
-    posix_acl_xattr_header* acl_header = reinterpret_cast<posix_acl_xattr_header*>(buf.get());
-    acl_header->a_version = POSIX_ACL_XATTR_VERSION;
-
-    posix_acl_xattr_entry* entry =
-            reinterpret_cast<posix_acl_xattr_entry*>(buf.get() + sizeof(posix_acl_xattr_header));
-
-    int tag_index = 0;
-
-    entry[tag_index].e_tag = ACL_USER_OBJ;
-    // The existing mode_t mask has the ACL in the lower 9 bits:
-    // the lowest 3 for "other", the next 3 the group, the next 3 for the owner
-    // Use the mode_t masks to get these bits out, and shift them to get the
-    // correct value per entity.
-    //
-    // Eg if mode_t = 0700, rwx for the owner, then & S_IRWXU >> 6 results in 7
-    entry[tag_index].e_perm = (mode & S_IRWXU) >> 6;
-    entry[tag_index].e_id = uid;
-    tag_index++;
-
-    entry[tag_index].e_tag = ACL_GROUP_OBJ;
-    entry[tag_index].e_perm = (mode & S_IRWXG) >> 3;
-    entry[tag_index].e_id = gid;
-    tag_index++;
-
-    if (additionalGids.size() > 0) {
-        for (gid_t additional_gid : additionalGids) {
-            entry[tag_index].e_tag = ACL_GROUP;
-            entry[tag_index].e_perm = (mode & S_IRWXG) >> 3;
-            entry[tag_index].e_id = additional_gid;
-            tag_index++;
-        }
-
-        entry[tag_index].e_tag = ACL_MASK;
-        entry[tag_index].e_perm = (mode & S_IRWXG) >> 3;
-        entry[tag_index].e_id = 0;
-        tag_index++;
-    }
-
-    entry[tag_index].e_tag = ACL_OTHER;
-    entry[tag_index].e_perm = mode & S_IRWXO;
-    entry[tag_index].e_id = 0;
-
-    int ret = setxattr(path.c_str(), XATTR_NAME_POSIX_ACL_DEFAULT, acl_header, size, 0);
-
-    if (ret != 0) {
-        PLOG(ERROR) << "Failed to set default ACL on " << path;
-    }
-
-    return ret;
-}
-
-int SetQuotaInherit(const std::string& path) {
-    unsigned long flags;
-
-    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open " << path << " to set project id inheritance.";
-        return -1;
-    }
-
-    int ret = ioctl(fd, FS_IOC_GETFLAGS, &flags);
-    if (ret == -1) {
-        PLOG(ERROR) << "Failed to get flags for " << path << " to set project id inheritance.";
-        return ret;
-    }
-
-    flags |= FS_PROJINHERIT_FL;
-
-    ret = ioctl(fd, FS_IOC_SETFLAGS, &flags);
-    if (ret == -1) {
-        PLOG(ERROR) << "Failed to set flags for " << path << " to set project id inheritance.";
-        return ret;
-    }
-
-    return 0;
-}
-
-int SetQuotaProjectId(const std::string& path, long projectId) {
-    struct fsxattr fsx;
-
-    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open " << path << " to set project id.";
-        return -1;
-    }
-
-    int ret = ioctl(fd, FS_IOC_FSGETXATTR, &fsx);
-    if (ret == -1) {
-        PLOG(ERROR) << "Failed to get extended attributes for " << path << " to get project id.";
-        return ret;
-    }
-
-    fsx.fsx_projid = projectId;
-    return ioctl(fd, FS_IOC_FSSETXATTR, &fsx);
-}
-
-int PrepareDirWithProjectId(const std::string& path, mode_t mode, uid_t uid, gid_t gid,
-                            long projectId) {
-    int ret = fs_prepare_dir(path.c_str(), mode, uid, gid);
-
-    if (ret != 0) {
-        return ret;
-    }
-
-    if (!IsSdcardfsUsed()) {
-        ret = SetQuotaProjectId(path, projectId);
-    }
-
-    return ret;
-}
-
-static int FixupAppDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid, long projectId) {
-    namespace fs = std::filesystem;
-
-    // Setup the directory itself correctly
-    int ret = PrepareDirWithProjectId(path, mode, uid, gid, projectId);
-    if (ret != android::OK) {
-        return ret;
-    }
-
-    // Fixup all of its file entries
-    for (const auto& itEntry : fs::directory_iterator(path)) {
-        ret = lchown(itEntry.path().c_str(), uid, gid);
-        if (ret != 0) {
-            return ret;
-        }
-
-        ret = chmod(itEntry.path().c_str(), mode);
-        if (ret != 0) {
-            return ret;
-        }
-
-        if (!IsSdcardfsUsed()) {
-            ret = SetQuotaProjectId(itEntry.path(), projectId);
-            if (ret != 0) {
-                return ret;
-            }
-        }
-    }
-
-    return android::OK;
-}
-
-int PrepareAppDirFromRoot(const std::string& path, const std::string& root, int appUid,
-                          bool fixupExisting) {
-    long projectId;
-    size_t pos;
-    int ret = 0;
-    bool sdcardfsSupport = IsSdcardfsUsed();
-
-    // Make sure the Android/ directories exist and are setup correctly
-    ret = PrepareAndroidDirs(root);
-    if (ret != 0) {
-        LOG(ERROR) << "Failed to prepare Android/ directories.";
-        return ret;
-    }
-
-    // Now create the application-specific subdir(s)
-    // path is something like /data/media/0/Android/data/com.foo/files
-    // First, chop off the volume root, eg /data/media/0
-    std::string pathFromRoot = path.substr(root.length());
-
-    uid_t uid = appUid;
-    gid_t gid = AID_MEDIA_RW;
-    std::vector<gid_t> additionalGids;
-    std::string appDir;
-
-    // Check that the next part matches one of the allowed Android/ dirs
-    if (StartsWith(pathFromRoot, kAppDataDir)) {
-        appDir = kAppDataDir;
-        if (!sdcardfsSupport) {
-            gid = AID_EXT_DATA_RW;
-            // Also add the app's own UID as a group; since apps belong to a group
-            // that matches their UID, this ensures that they will always have access to
-            // the files created in these dirs, even if they are created by other processes
-            additionalGids.push_back(uid);
-        }
-    } else if (StartsWith(pathFromRoot, kAppMediaDir)) {
-        appDir = kAppMediaDir;
-        if (!sdcardfsSupport) {
-            gid = AID_MEDIA_RW;
-        }
-    } else if (StartsWith(pathFromRoot, kAppObbDir)) {
-        appDir = kAppObbDir;
-        if (!sdcardfsSupport) {
-            gid = AID_EXT_OBB_RW;
-            // See comments for kAppDataDir above
-            additionalGids.push_back(uid);
-        }
-    } else {
-        LOG(ERROR) << "Invalid application directory: " << path;
-        return -EINVAL;
-    }
-
-    // mode = 770, plus sticky bit on directory to inherit GID when apps
-    // create subdirs
-    mode_t mode = S_IRWXU | S_IRWXG | S_ISGID;
-    // the project ID for application-specific directories is directly
-    // derived from their uid
-
-    // Chop off the generic application-specific part, eg /Android/data/
-    // this leaves us with something like com.foo/files/
-    std::string leftToCreate = pathFromRoot.substr(appDir.length());
-    if (!EndsWith(leftToCreate, "/")) {
-        leftToCreate += "/";
-    }
-    std::string pathToCreate = root + appDir;
-    int depth = 0;
-    // Derive initial project ID
-    if (appDir == kAppDataDir || appDir == kAppMediaDir) {
-        projectId = uid - AID_APP_START + PROJECT_ID_EXT_DATA_START;
-    } else if (appDir == kAppObbDir) {
-        projectId = uid - AID_APP_START + PROJECT_ID_EXT_OBB_START;
-    }
-
-    while ((pos = leftToCreate.find('/')) != std::string::npos) {
-        std::string component = leftToCreate.substr(0, pos + 1);
-        leftToCreate = leftToCreate.erase(0, pos + 1);
-        pathToCreate = pathToCreate + component;
-
-        if (appDir == kAppDataDir && depth == 1 && component == "cache/") {
-            // All dirs use the "app" project ID, except for the cache dirs in
-            // Android/data, eg Android/data/com.foo/cache
-            // Note that this "sticks" - eg subdirs of this dir need the same
-            // project ID.
-            projectId = uid - AID_APP_START + PROJECT_ID_EXT_CACHE_START;
-        }
-
-        if (fixupExisting && access(pathToCreate.c_str(), F_OK) == 0) {
-            // Fixup all files in this existing directory with the correct UID/GID
-            // and project ID.
-            ret = FixupAppDir(pathToCreate, mode, uid, gid, projectId);
-        } else {
-            ret = PrepareDirWithProjectId(pathToCreate, mode, uid, gid, projectId);
-        }
-
-        if (ret != 0) {
-            return ret;
-        }
-
-        if (depth == 0) {
-            // Set the default ACL on the top-level application-specific directories,
-            // to ensure that even if applications run with a umask of 0077,
-            // new directories within these directories will allow the GID
-            // specified here to write; this is necessary for apps like
-            // installers and MTP, that require access here.
-            //
-            // See man (5) acl for more details.
-            ret = SetDefaultAcl(pathToCreate, mode, uid, gid, additionalGids);
-            if (ret != 0) {
-                return ret;
-            }
-
-            if (!sdcardfsSupport) {
-                // Set project ID inheritance, so that future subdirectories inherit the
-                // same project ID
-                ret = SetQuotaInherit(pathToCreate);
-                if (ret != 0) {
-                    return ret;
-                }
-            }
-        }
-
-        depth++;
-    }
-
-    return android::OK;
-}
-
-android::status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid) {
-    std::lock_guard<std::mutex> lock(kSecurityLock);
-    const char* cpath = path.c_str();
-
-    char* secontext = nullptr;
-    if (sehandle) {
-        if (!selabel_lookup(sehandle, &secontext, cpath, S_IFDIR)) {
-            setfscreatecon(secontext);
-        }
-    }
-
-    int res = fs_prepare_dir(cpath, mode, uid, gid);
-
-    if (secontext) {
-        setfscreatecon(nullptr);
-        freecon(secontext);
-    }
-
-    if (res == 0) {
-        return android::OK;
-    } else {
-        return -errno;
-    }
-}
-
-android::status_t ForceUnmount(const std::string& path) {
-    const char* cpath = path.c_str();
-    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
-        return android::OK;
-    }
-    // Apps might still be handling eject request, so wait before
-    // we start sending signals
-    if (sSleepOnUnmount) sleep(5);
-
-    android::vold::KillProcessesWithOpenFiles(path, SIGINT);
-    if (sSleepOnUnmount) sleep(5);
-    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
-        return android::OK;
-    }
-
-    android::vold::KillProcessesWithOpenFiles(path, SIGTERM);
-    if (sSleepOnUnmount) sleep(5);
-    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
-        return android::OK;
-    }
-
-    android::vold::KillProcessesWithOpenFiles(path, SIGKILL);
-    if (sSleepOnUnmount) sleep(5);
-    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
-        return android::OK;
-    }
-    PLOG(INFO) << "ForceUnmount failed";
-    return -errno;
-}
-
-android::status_t KillProcessesWithMountPrefix(const std::string& path) {
-    if (android::vold::KillProcessesWithMounts(path, SIGINT) == 0) {
-        return android::OK;
-    }
-    if (sSleepOnUnmount) sleep(5);
-
-    if (android::vold::KillProcessesWithMounts(path, SIGTERM) == 0) {
-        return android::OK;
-    }
-    if (sSleepOnUnmount) sleep(5);
-
-    if (android::vold::KillProcessesWithMounts(path, SIGKILL) == 0) {
-        return android::OK;
-    }
-    if (sSleepOnUnmount) sleep(5);
-
-    // Send SIGKILL a second time to determine if we've
-    // actually killed everyone mount
-    if (android::vold::KillProcessesWithMounts(path, SIGKILL) == 0) {
-        return android::OK;
-    }
-    PLOG(ERROR) << "Failed to kill processes using " << path;
-    return -EBUSY;
-}
-
-android::status_t KillProcessesUsingPath(const std::string& path) {
-    if (android::vold::KillProcessesWithOpenFiles(path, SIGINT) == 0) {
-        return android::OK;
-    }
-    if (sSleepOnUnmount) sleep(5);
-
-    if (android::vold::KillProcessesWithOpenFiles(path, SIGTERM) == 0) {
-        return android::OK;
-    }
-    if (sSleepOnUnmount) sleep(5);
-
-    if (android::vold::KillProcessesWithOpenFiles(path, SIGKILL) == 0) {
-        return android::OK;
-    }
-    if (sSleepOnUnmount) sleep(5);
-
-    // Send SIGKILL a second time to determine if we've
-    // actually killed everyone with open files
-    if (android::vold::KillProcessesWithOpenFiles(path, SIGKILL) == 0) {
-        return android::OK;
-    }
-    PLOG(ERROR) << "Failed to kill processes using " << path;
-    return -EBUSY;
-}
-
-android::status_t BindMount(const std::string& source, const std::string& target) {
-    if (UnmountTree(target) < 0) {
-        return -errno;
-    }
-    if (TEMP_FAILURE_RETRY(mount(source.c_str(), target.c_str(), nullptr, MS_BIND, nullptr)) < 0) {
-        PLOG(ERROR) << "Failed to bind mount " << source << " to " << target;
-        return -errno;
-    }
-    return android::OK;
-}
-
-android::status_t Symlink(const std::string& target, const std::string& linkpath) {
-    if (Unlink(linkpath) < 0) {
-        return -errno;
-    }
-    if (TEMP_FAILURE_RETRY(symlink(target.c_str(), linkpath.c_str())) < 0) {
-        PLOG(ERROR) << "Failed to create symlink " << linkpath << " to " << target;
-        return -errno;
-    }
-    return android::OK;
-}
-
-android::status_t Unlink(const std::string& linkpath) {
-    if (TEMP_FAILURE_RETRY(unlink(linkpath.c_str())) < 0 && errno != EINVAL && errno != ENOENT) {
-        PLOG(ERROR) << "Failed to unlink " << linkpath;
-        return -errno;
-    }
-    return android::OK;
-}
-
-android::status_t CreateDir(const std::string& dir, mode_t mode) {
-    struct stat sb;
-    if (TEMP_FAILURE_RETRY(stat(dir.c_str(), &sb)) == 0) {
-        if (S_ISDIR(sb.st_mode)) {
-            return android::OK;
-        } else if (TEMP_FAILURE_RETRY(unlink(dir.c_str())) == -1) {
-            PLOG(ERROR) << "Failed to unlink " << dir;
-            return -errno;
-        }
-    } else if (errno != ENOENT) {
-        PLOG(ERROR) << "Failed to stat " << dir;
-        return -errno;
-    }
-    if (TEMP_FAILURE_RETRY(mkdir(dir.c_str(), mode)) == -1 && errno != EEXIST) {
-        PLOG(ERROR) << "Failed to mkdir " << dir;
-        return -errno;
-    }
-    return android::OK;
-}
-
-bool FindValue(const std::string& raw, const std::string& key, std::string* value) {
-    auto qual = key + "=\"";
-    size_t start = 0;
-    while (true) {
-        start = raw.find(qual, start);
-        if (start == std::string::npos) return false;
-        if (start == 0 || raw[start - 1] == ' ') {
-            break;
-        }
-        start += 1;
-    }
-    start += qual.length();
-
-    auto end = raw.find("\"", start);
-    if (end == std::string::npos) return false;
-
-    *value = raw.substr(start, end - start);
-    return true;
-}
-
-static android::status_t readMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
-                             std::string* fsLabel, bool untrusted) {
-    fsType->clear();
-    fsUuid->clear();
-    fsLabel->clear();
-
-    std::vector<std::string> cmd;
-    cmd.push_back(kBlkidPath);
-    cmd.push_back("-c");
-    cmd.push_back("/dev/null");
-    cmd.push_back("-s");
-    cmd.push_back("TYPE");
-    cmd.push_back("-s");
-    cmd.push_back("UUID");
-    cmd.push_back("-s");
-    cmd.push_back("LABEL");
-    cmd.push_back(path);
-
-    std::vector<std::string> output;
-    android::status_t res = ForkExecvp(cmd, &output, untrusted ? sBlkidUntrustedContext : sBlkidContext);
-    if (res != android::OK) {
-        LOG(WARNING) << "blkid failed to identify " << path;
-        return res;
-    }
-
-    for (const auto& line : output) {
-        // Extract values from blkid output, if defined
-        FindValue(line, "TYPE", fsType);
-        FindValue(line, "UUID", fsUuid);
-        FindValue(line, "LABEL", fsLabel);
-    }
-
-    return android::OK;
-}
-
-android::status_t ReadMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
-                      std::string* fsLabel) {
-    return readMetadata(path, fsType, fsUuid, fsLabel, false);
-}
-
-android::status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, std::string* fsUuid,
-                               std::string* fsLabel) {
-    return readMetadata(path, fsType, fsUuid, fsLabel, true);
-}
-
-static std::vector<const char*> ConvertToArgv(const std::vector<std::string>& args) {
-    std::vector<const char*> argv;
-    argv.reserve(args.size() + 1);
-    for (const auto& arg : args) {
-        if (argv.empty()) {
-            LOG(DEBUG) << arg;
-        } else {
-            LOG(DEBUG) << "    " << arg;
-        }
-        argv.emplace_back(arg.data());
-    }
-    argv.emplace_back(nullptr);
-    return argv;
-}
-
-static android::status_t ReadLinesFromFdAndLog(std::vector<std::string>* output,
-                                      android::base::unique_fd ufd) {
-    std::unique_ptr<FILE, int (*)(FILE*)> fp(android::base::Fdopen(std::move(ufd), "r"), fclose);
-    if (!fp) {
-        PLOG(ERROR) << "fdopen in ReadLinesFromFdAndLog";
-        return -errno;
-    }
-    if (output) output->clear();
-    char line[1024];
-    while (fgets(line, sizeof(line), fp.get()) != nullptr) {
-        LOG(DEBUG) << line;
-        if (output) output->emplace_back(line);
-    }
-    return android::OK;
-}
-
-android::status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>* output,
-                    security_context_t context) {
-    auto argv = ConvertToArgv(args);
-
-    android::base::unique_fd pipe_read, pipe_write;
-    if (!android::base::Pipe(&pipe_read, &pipe_write)) {
-        PLOG(ERROR) << "Pipe in ForkExecvp";
-        return -errno;
-    }
-
-    pid_t pid = fork();
-    if (pid == 0) {
-        if (context) {
-            if (setexeccon(context)) {
-                LOG(ERROR) << "Failed to setexeccon in ForkExecvp";
-                abort();
-            }
-        }
-        pipe_read.reset();
-        if (dup2(pipe_write.get(), STDOUT_FILENO) == -1) {
-            PLOG(ERROR) << "dup2 in ForkExecvp";
-            _exit(EXIT_FAILURE);
-        }
-        pipe_write.reset();
-        execvp(argv[0], const_cast<char**>(argv.data()));
-        PLOG(ERROR) << "exec in ForkExecvp";
-        _exit(EXIT_FAILURE);
-    }
-    if (pid == -1) {
-        PLOG(ERROR) << "fork in ForkExecvp";
-        return -errno;
-    }
-
-    pipe_write.reset();
-    auto st = ReadLinesFromFdAndLog(output, std::move(pipe_read));
-    if (st != 0) return st;
-
-    int status;
-    if (waitpid(pid, &status, 0) == -1) {
-        PLOG(ERROR) << "waitpid in ForkExecvp";
-        return -errno;
-    }
-    if (!WIFEXITED(status)) {
-        LOG(ERROR) << "Process did not exit normally, status: " << status;
-        return -ECHILD;
-    }
-    if (WEXITSTATUS(status)) {
-        LOG(ERROR) << "Process exited with code: " << WEXITSTATUS(status);
-        return WEXITSTATUS(status);
-    }
-    return android::OK;
-}
-
-pid_t ForkExecvpAsync(const std::vector<std::string>& args) {
-    auto argv = ConvertToArgv(args);
-
-    pid_t pid = fork();
-    if (pid == 0) {
-        close(STDIN_FILENO);
-        close(STDOUT_FILENO);
-        close(STDERR_FILENO);
-
-        execvp(argv[0], const_cast<char**>(argv.data()));
-        PLOG(ERROR) << "exec in ForkExecvpAsync";
-        _exit(EXIT_FAILURE);
-    }
-    if (pid == -1) {
-        PLOG(ERROR) << "fork in ForkExecvpAsync";
-        return -1;
-    }
-    return pid;
-}
-
-android::status_t ReadRandomBytes(size_t bytes, std::string& out) {
-    out.resize(bytes);
-    return ReadRandomBytes(bytes, &out[0]);
-}
-
-android::status_t ReadRandomBytes(size_t bytes, char* buf) {
-    int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
-    if (fd == -1) {
-        return -errno;
-    }
-
-    ssize_t n;
-    while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], bytes))) > 0) {
-        bytes -= n;
-        buf += n;
-    }
-    close(fd);
-
-    if (bytes == 0) {
-        return android::OK;
-    } else {
-        return -EIO;
-    }
-}
-
-android::status_t GenerateRandomUuid(std::string& out) {
-    android::status_t res = ReadRandomBytes(16, out);
-    if (res == android::OK) {
-        out[6] &= 0x0f; /* clear version        */
-        out[6] |= 0x40; /* set to version 4     */
-        out[8] &= 0x3f; /* clear variant        */
-        out[8] |= 0x80; /* set to IETF variant  */
-    }
-    return res;
-}
-
-android::status_t HexToStr(const std::string& hex, std::string& str) {
-    str.clear();
-    bool even = true;
-    char cur = 0;
-    for (size_t i = 0; i < hex.size(); i++) {
-        int val = 0;
-        switch (hex[i]) {
-            // clang-format off
-            case ' ': case '-': case ':': continue;
-            case 'f': case 'F': val = 15; break;
-            case 'e': case 'E': val = 14; break;
-            case 'd': case 'D': val = 13; break;
-            case 'c': case 'C': val = 12; break;
-            case 'b': case 'B': val = 11; break;
-            case 'a': case 'A': val = 10; break;
-            case '9': val = 9; break;
-            case '8': val = 8; break;
-            case '7': val = 7; break;
-            case '6': val = 6; break;
-            case '5': val = 5; break;
-            case '4': val = 4; break;
-            case '3': val = 3; break;
-            case '2': val = 2; break;
-            case '1': val = 1; break;
-            case '0': val = 0; break;
-            default: return -EINVAL;
-                // clang-format on
-        }
-
-        if (even) {
-            cur = val << 4;
-        } else {
-            cur += val;
-            str.push_back(cur);
-            cur = 0;
-        }
-        even = !even;
-    }
-    return even ? android::OK : -EINVAL;
-}
-
-static const char* kLookup = "0123456789abcdef";
-
-android::status_t StrToHex(const std::string& str, std::string& hex) {
-    hex.clear();
-    for (size_t i = 0; i < str.size(); i++) {
-        hex.push_back(kLookup[(str[i] & 0xF0) >> 4]);
-        hex.push_back(kLookup[str[i] & 0x0F]);
-    }
-    return android::OK;
-}
-
-android::status_t StrToHex(const KeyBuffer& str, KeyBuffer& hex) {
-    hex.clear();
-    for (size_t i = 0; i < str.size(); i++) {
-        hex.push_back(kLookup[(str.data()[i] & 0xF0) >> 4]);
-        hex.push_back(kLookup[str.data()[i] & 0x0F]);
-    }
-    return android::OK;
-}
-
-android::status_t NormalizeHex(const std::string& in, std::string& out) {
-    std::string tmp;
-    if (HexToStr(in, tmp)) {
-        return -EINVAL;
-    }
-    return StrToHex(tmp, out);
-}
-
-android::status_t GetBlockDevSize(int fd, uint64_t* size) {
-    if (ioctl(fd, BLKGETSIZE64, size)) {
-        return -errno;
-    }
-
-    return android::OK;
-}
-
-android::status_t GetBlockDevSize(const std::string& path, uint64_t* size) {
-    int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
-    android::status_t res = android::OK;
-
-    if (fd < 0) {
-        return -errno;
-    }
-
-    res = GetBlockDevSize(fd, size);
-
-    close(fd);
-
-    return res;
-}
-
-android::status_t GetBlockDev512Sectors(const std::string& path, uint64_t* nr_sec) {
-    uint64_t size;
-    android::status_t res = GetBlockDevSize(path, &size);
-
-    if (res != android::OK) {
-        return res;
-    }
-
-    *nr_sec = size / 512;
-
-    return android::OK;
-}
-
-uint64_t GetFreeBytes(const std::string& path) {
-    struct statvfs sb;
-    if (statvfs(path.c_str(), &sb) == 0) {
-        return (uint64_t)sb.f_bavail * sb.f_frsize;
-    } else {
-        return -1;
-    }
-}
-
-// TODO: borrowed from frameworks/native/libs/diskusage/ which should
-// eventually be migrated into system/
-static int64_t stat_size(struct stat* s) {
-    int64_t blksize = s->st_blksize;
-    // count actual blocks used instead of nominal file size
-    int64_t size = s->st_blocks * 512;
-
-    if (blksize) {
-        /* round up to filesystem block size */
-        size = (size + blksize - 1) & (~(blksize - 1));
-    }
-
-    return size;
-}
-
-// TODO: borrowed from frameworks/native/libs/diskusage/ which should
-// eventually be migrated into system/
-int64_t calculate_dir_size(int dfd) {
-    int64_t size = 0;
-    struct stat s;
-    DIR* d;
-    struct dirent* de;
-
-    d = fdopendir(dfd);
-    if (d == NULL) {
-        close(dfd);
-        return 0;
-    }
-
-    while ((de = readdir(d))) {
-        const char* name = de->d_name;
-        if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) {
-            size += stat_size(&s);
-        }
-        if (de->d_type == DT_DIR) {
-            int subfd;
-
-            /* always skip "." and ".." */
-            if (name[0] == '.') {
-                if (name[1] == 0) continue;
-                if ((name[1] == '.') && (name[2] == 0)) continue;
-            }
-
-            subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
-            if (subfd >= 0) {
-                size += calculate_dir_size(subfd);
-            }
-        }
-    }
-    closedir(d);
-    return size;
-}
-
-uint64_t GetTreeBytes(const std::string& path) {
-    int dirfd = open(path.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC);
-    if (dirfd < 0) {
-        PLOG(WARNING) << "Failed to open " << path;
-        return -1;
-    } else {
-        return calculate_dir_size(dirfd);
-    }
-}
-
-// TODO: Use a better way to determine if it's media provider app.
-bool IsFuseDaemon(const pid_t pid) {
-    auto path = StringPrintf("/proc/%d/mounts", pid);
-    char* tmp;
-    if (lgetfilecon(path.c_str(), &tmp) < 0) {
-        return false;
-    }
-    bool result = android::base::StartsWith(tmp, kMediaProviderAppCtx)
-            || android::base::StartsWith(tmp, kMediaProviderCtx);
-    freecon(tmp);
-    return result;
-}
-
-bool IsFilesystemSupported(const std::string& fsType) {
-    std::string supported;
-    if (!ReadFileToString(kProcFilesystems, &supported)) {
-        PLOG(ERROR) << "Failed to read supported filesystems";
-        return false;
-    }
-    return supported.find(fsType + "\n") != std::string::npos;
-}
-
-bool IsSdcardfsUsed() {
-    return IsFilesystemSupported("sdcardfs") &&
-           android::base::GetBoolProperty(kExternalStorageSdcardfs, true);
-}
-
-android::status_t WipeBlockDevice(const std::string& path) {
-    android::status_t res = -1;
-    const char* c_path = path.c_str();
-    uint64_t range[2] = {0, 0};
-
-    int fd = TEMP_FAILURE_RETRY(open(c_path, O_RDWR | O_CLOEXEC));
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open " << path;
-        goto done;
-    }
-
-    if (GetBlockDevSize(fd, &range[1]) != android::OK) {
-        PLOG(ERROR) << "Failed to determine size of " << path;
-        goto done;
-    }
-
-    LOG(INFO) << "About to discard " << range[1] << " on " << path;
-    if (ioctl(fd, BLKDISCARD, &range) == 0) {
-        LOG(INFO) << "Discard success on " << path;
-        res = 0;
-    } else {
-        PLOG(ERROR) << "Discard failure on " << path;
-    }
-
-done:
-    close(fd);
-    return res;
-}
-
-static bool isValidFilename(const std::string& name) {
-    if (name.empty() || (name == ".") || (name == "..") || (name.find('/') != std::string::npos)) {
-        return false;
-    } else {
-        return true;
-    }
-}
-
-std::string BuildKeyPath(const std::string& partGuid) {
-    return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str());
-}
-
-std::string BuildDataSystemLegacyPath(userid_t userId) {
-    return StringPrintf("%s/system/users/%u", BuildDataPath("").c_str(), userId);
-}
-
-std::string BuildDataSystemCePath(userid_t userId) {
-    return StringPrintf("%s/system_ce/%u", BuildDataPath("").c_str(), userId);
-}
-
-std::string BuildDataSystemDePath(userid_t userId) {
-    return StringPrintf("%s/system_de/%u", BuildDataPath("").c_str(), userId);
-}
-
-std::string BuildDataMiscLegacyPath(userid_t userId) {
-    return StringPrintf("%s/misc/user/%u", BuildDataPath("").c_str(), userId);
-}
-
-std::string BuildDataMiscCePath(userid_t userId) {
-    return StringPrintf("%s/misc_ce/%u", BuildDataPath("").c_str(), userId);
-}
-
-std::string BuildDataMiscDePath(userid_t userId) {
-    return StringPrintf("%s/misc_de/%u", BuildDataPath("").c_str(), userId);
-}
-
-// Keep in sync with installd (frameworks/native/cmds/installd/utils.h)
-std::string BuildDataProfilesDePath(userid_t userId) {
-    return StringPrintf("%s/misc/profiles/cur/%u", BuildDataPath("").c_str(), userId);
-}
-
-std::string BuildDataVendorCePath(userid_t userId) {
-    return StringPrintf("%s/vendor_ce/%u", BuildDataPath("").c_str(), userId);
-}
-
-std::string BuildDataVendorDePath(userid_t userId) {
-    return StringPrintf("%s/vendor_de/%u", BuildDataPath("").c_str(), userId);
-}
-
-std::string BuildDataPath(const std::string& volumeUuid) {
-    // TODO: unify with installd path generation logic
-    if (volumeUuid.empty()) {
-        return "/data";
-    } else {
-        CHECK(isValidFilename(volumeUuid));
-        return StringPrintf("/mnt/expand/%s", volumeUuid.c_str());
-    }
-}
-
-std::string BuildDataMediaCePath(const std::string& volumeUuid, userid_t userId) {
-    // TODO: unify with installd path generation logic
-    std::string data(BuildDataPath(volumeUuid));
-    return StringPrintf("%s/media/%u", data.c_str(), userId);
-}
-
-std::string BuildDataUserCePath(const std::string& volumeUuid, userid_t userId) {
-    // TODO: unify with installd path generation logic
-    std::string data(BuildDataPath(volumeUuid));
-    if (volumeUuid.empty() && userId == 0) {
-        std::string legacy = StringPrintf("%s/data", data.c_str());
-        struct stat sb;
-        if (lstat(legacy.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) {
-            /* /data/data is dir, return /data/data for legacy system */
-            return legacy;
-        }
-    }
-    return StringPrintf("%s/user/%u", data.c_str(), userId);
-}
-
-std::string BuildDataUserDePath(const std::string& volumeUuid, userid_t userId) {
-    // TODO: unify with installd path generation logic
-    std::string data(BuildDataPath(volumeUuid));
-    return StringPrintf("%s/user_de/%u", data.c_str(), userId);
-}
-
-dev_t GetDevice(const std::string& path) {
-    struct stat sb;
-    if (stat(path.c_str(), &sb)) {
-        PLOG(WARNING) << "Failed to stat " << path;
-        return 0;
-    } else {
-        return sb.st_dev;
-    }
-}
-
-android::status_t RestoreconRecursive(const std::string& path) {
-    LOG(DEBUG) << "Starting restorecon of " << path;
-
-    static constexpr const char* kRestoreconString = "selinux.restorecon_recursive";
-
-    android::base::SetProperty(kRestoreconString, "");
-    android::base::SetProperty(kRestoreconString, path);
-
-    android::base::WaitForProperty(kRestoreconString, path);
-
-    LOG(DEBUG) << "Finished restorecon of " << path;
-    return android::OK;
-}
-
-bool Readlinkat(int dirfd, const std::string& path, std::string* result) {
-    // Shamelessly borrowed from android::base::Readlink()
-    result->clear();
-
-    // Most Linux file systems (ext2 and ext4, say) limit symbolic links to
-    // 4095 bytes. Since we'll copy out into the string anyway, it doesn't
-    // waste memory to just start there. We add 1 so that we can recognize
-    // whether it actually fit (rather than being truncated to 4095).
-    std::vector<char> buf(4095 + 1);
-    while (true) {
-        ssize_t size = readlinkat(dirfd, path.c_str(), &buf[0], buf.size());
-        // Unrecoverable error?
-        if (size == -1) return false;
-        // It fit! (If size == buf.size(), it may have been truncated.)
-        if (static_cast<size_t>(size) < buf.size()) {
-            result->assign(&buf[0], size);
-            return true;
-        }
-        // Double our buffer and try again.
-        buf.resize(buf.size() * 2);
-    }
-}
-
-static unsigned int GetMajorBlockVirtioBlk() {
-    std::string devices;
-    if (!ReadFileToString(kProcDevices, &devices)) {
-        PLOG(ERROR) << "Unable to open /proc/devices";
-        return 0;
-    }
-
-    bool blockSection = false;
-    for (auto line : android::base::Split(devices, "\n")) {
-        if (line == "Block devices:") {
-            blockSection = true;
-        } else if (line == "Character devices:") {
-            blockSection = false;
-        } else if (blockSection) {
-            auto tokens = android::base::Split(line, " ");
-            if (tokens.size() == 2 && tokens[1] == "virtblk") {
-                return std::stoul(tokens[0]);
-            }
-        }
-    }
-
-    return 0;
-}
-
-bool IsVirtioBlkDevice(unsigned int major) {
-    // Most virtualized platforms expose block devices with the virtio-blk
-    // block device driver. Unfortunately, this driver does not use a fixed
-    // major number, but relies on the kernel to assign one from a specific
-    // range of block majors, which are allocated for "LOCAL/EXPERIMENAL USE"
-    // per Documentation/devices.txt. This is true even for the latest Linux
-    // kernel (4.4; see init() in drivers/block/virtio_blk.c).
-    static unsigned int kMajorBlockVirtioBlk = GetMajorBlockVirtioBlk();
-    return kMajorBlockVirtioBlk && major == kMajorBlockVirtioBlk;
-}
-
-static android::status_t findMountPointsWithPrefix(const std::string& prefix,
-                                          std::list<std::string>& mountPoints) {
-    // Add a trailing slash if the client didn't provide one so that we don't match /foo/barbaz
-    // when the prefix is /foo/bar
-    std::string prefixWithSlash(prefix);
-    if (prefix.back() != '/') {
-        android::base::StringAppendF(&prefixWithSlash, "/");
-    }
-
-    std::unique_ptr<FILE, int (*)(FILE*)> mnts(setmntent("/proc/mounts", "re"), endmntent);
-    if (!mnts) {
-        PLOG(ERROR) << "Unable to open /proc/mounts";
-        return -errno;
-    }
-
-    // Some volumes can be stacked on each other, so force unmount in
-    // reverse order to give us the best chance of success.
-    struct mntent* mnt;  // getmntent returns a thread local, so it's safe.
-    while ((mnt = getmntent(mnts.get())) != nullptr) {
-        auto mountPoint = std::string(mnt->mnt_dir) + "/";
-        if (android::base::StartsWith(mountPoint, prefixWithSlash)) {
-            mountPoints.push_front(mountPoint);
-        }
-    }
-    return android::OK;
-}
-
-// Unmount all mountpoints that start with prefix. prefix itself doesn't need to be a mountpoint.
-android::status_t UnmountTreeWithPrefix(const std::string& prefix) {
-    std::list<std::string> toUnmount;
-    android::status_t result = findMountPointsWithPrefix(prefix, toUnmount);
-    if (result < 0) {
-        return result;
-    }
-    for (const auto& path : toUnmount) {
-        if (umount2(path.c_str(), MNT_DETACH)) {
-            PLOG(ERROR) << "Failed to unmount " << path;
-            result = -errno;
-        }
-    }
-    return result;
-}
-
-android::status_t UnmountTree(const std::string& mountPoint) {
-    if (TEMP_FAILURE_RETRY(umount2(mountPoint.c_str(), MNT_DETACH)) < 0 && errno != EINVAL &&
-        errno != ENOENT) {
-        PLOG(ERROR) << "Failed to unmount " << mountPoint;
-        return -errno;
-    }
-    return android::OK;
-}
-
-static android::status_t delete_dir_contents(DIR* dir) {
-    // Shamelessly borrowed from android::installd
-    int dfd = dirfd(dir);
-    if (dfd < 0) {
-        return -errno;
-    }
-
-    android::status_t result = android::OK;
-    struct dirent* de;
-    while ((de = readdir(dir))) {
-        const char* name = de->d_name;
-        if (de->d_type == DT_DIR) {
-            /* always skip "." and ".." */
-            if (name[0] == '.') {
-                if (name[1] == 0) continue;
-                if ((name[1] == '.') && (name[2] == 0)) continue;
-            }
-
-            android::base::unique_fd subfd(
-                openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC));
-            if (subfd.get() == -1) {
-                PLOG(ERROR) << "Couldn't openat " << name;
-                result = -errno;
-                continue;
-            }
-            std::unique_ptr<DIR, decltype(&closedir)> subdirp(
-                android::base::Fdopendir(std::move(subfd)), closedir);
-            if (!subdirp) {
-                PLOG(ERROR) << "Couldn't fdopendir " << name;
-                result = -errno;
-                continue;
-            }
-            result = delete_dir_contents(subdirp.get());
-            if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) {
-                PLOG(ERROR) << "Couldn't unlinkat " << name;
-                result = -errno;
-            }
-        } else {
-            if (unlinkat(dfd, name, 0) < 0) {
-                PLOG(ERROR) << "Couldn't unlinkat " << name;
-                result = -errno;
-            }
-        }
-    }
-    return result;
-}
-
-android::status_t DeleteDirContentsAndDir(const std::string& pathname) {
-    android::status_t res = DeleteDirContents(pathname);
-    if (res < 0) {
-        return res;
-    }
-    if (TEMP_FAILURE_RETRY(rmdir(pathname.c_str())) < 0 && errno != ENOENT) {
-        PLOG(ERROR) << "rmdir failed on " << pathname;
-        return -errno;
-    }
-    LOG(VERBOSE) << "Success: rmdir on " << pathname;
-    return android::OK;
-}
-
-android::status_t DeleteDirContents(const std::string& pathname) {
-    // Shamelessly borrowed from android::installd
-    std::unique_ptr<DIR, decltype(&closedir)> dirp(opendir(pathname.c_str()), closedir);
-    if (!dirp) {
-        if (errno == ENOENT) {
-            return android::OK;
-        }
-        PLOG(ERROR) << "Failed to opendir " << pathname;
-        return -errno;
-    }
-    return delete_dir_contents(dirp.get());
-}
-
-// TODO(118708649): fix duplication with init/util.h
-android::status_t WaitForFile(const char* filename, std::chrono::nanoseconds timeout) {
-    android::base::Timer t;
-    while (t.duration() < timeout) {
-        struct stat sb;
-        if (stat(filename, &sb) != -1) {
-            LOG(INFO) << "wait for '" << filename << "' took " << t;
-            return 0;
-        }
-        std::this_thread::sleep_for(10ms);
-    }
-    LOG(WARNING) << "wait for '" << filename << "' timed out and took " << t;
-    return -1;
-}
-
-bool FsyncDirectory(const std::string& dirname) {
-    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(dirname.c_str(), O_RDONLY | O_CLOEXEC)));
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open " << dirname;
-        return false;
-    }
-    if (fsync(fd) == -1) {
-        if (errno == EROFS || errno == EINVAL) {
-            PLOG(WARNING) << "Skip fsync " << dirname
-                          << " on a file system does not support synchronization";
-        } else {
-            PLOG(ERROR) << "Failed to fsync " << dirname;
-            return false;
-        }
-    }
-    return true;
-}
-
-bool writeStringToFile(const std::string& payload, const std::string& filename) {
-    android::base::unique_fd fd(TEMP_FAILURE_RETRY(
-        open(filename.c_str(), O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC | O_CLOEXEC, 0666)));
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open " << filename;
-        return false;
-    }
-    if (!android::base::WriteStringToFd(payload, fd)) {
-        PLOG(ERROR) << "Failed to write to " << filename;
-        unlink(filename.c_str());
-        return false;
-    }
-    // fsync as close won't guarantee flush data
-    // see close(2), fsync(2) and b/68901441
-    if (fsync(fd) == -1) {
-        if (errno == EROFS || errno == EINVAL) {
-            PLOG(WARNING) << "Skip fsync " << filename
-                          << " on a file system does not support synchronization";
-        } else {
-            PLOG(ERROR) << "Failed to fsync " << filename;
-            unlink(filename.c_str());
-            return false;
-        }
-    }
-    return true;
-}
-
-android::status_t AbortFuseConnections() {
-    namespace fs = std::filesystem;
-
-    for (const auto& itEntry : fs::directory_iterator("/sys/fs/fuse/connections")) {
-        std::string abortPath = itEntry.path().string() + "/abort";
-        LOG(DEBUG) << "Aborting fuse connection entry " << abortPath;
-        bool ret = writeStringToFile("1", abortPath);
-        if (!ret) {
-            LOG(WARNING) << "Failed to write to " << abortPath;
-        }
-    }
-
-    return android::OK;
-}
-
-android::status_t EnsureDirExists(const std::string& path, mode_t mode, uid_t uid, gid_t gid) {
-    if (access(path.c_str(), F_OK) != 0) {
-        PLOG(WARNING) << "Dir does not exist: " << path;
-        if (fs_prepare_dir(path.c_str(), mode, uid, gid) != 0) {
-            return -errno;
-        }
-    }
-    return android::OK;
-}
-
-// Gets the sysfs path for parameters of the backing device info (bdi)
-static std::string getBdiPathForMount(const std::string& mount) {
-    // First figure out MAJOR:MINOR of mount. Simplest way is to stat the path.
-    struct stat info;
-    if (stat(mount.c_str(), &info) != 0) {
-        PLOG(ERROR) << "Failed to stat " << mount;
-        return "";
-    }
-    unsigned int maj = major(info.st_dev);
-    unsigned int min = minor(info.st_dev);
-
-    return StringPrintf("/sys/class/bdi/%u:%u", maj, min);
-}
-
-// Configures max_ratio for the FUSE filesystem.
-void ConfigureMaxDirtyRatioForFuse(const std::string& fuse_mount, unsigned int max_ratio) {
-    LOG(INFO) << "Configuring max_ratio of " << fuse_mount << " fuse filesystem to " << max_ratio;
-    if (max_ratio > 100) {
-        LOG(ERROR) << "Invalid max_ratio: " << max_ratio;
-        return;
-    }
-    std::string fuseBdiPath = getBdiPathForMount(fuse_mount);
-    if (fuseBdiPath == "") {
-        return;
-    }
-    std::string max_ratio_file = StringPrintf("%s/max_ratio", fuseBdiPath.c_str());
-    unique_fd fd(TEMP_FAILURE_RETRY(open(max_ratio_file.c_str(), O_WRONLY | O_CLOEXEC)));
-    if (fd.get() == -1) {
-        PLOG(ERROR) << "Failed to open " << max_ratio_file;
-        return;
-    }
-    LOG(INFO) << "Writing " << max_ratio << " to " << max_ratio_file;
-    if (!WriteStringToFd(std::to_string(max_ratio), fd)) {
-        PLOG(ERROR) << "Failed to write to " << max_ratio_file;
-    }
-}
-
-// Configures read ahead property of the fuse filesystem with the mount point |fuse_mount| by
-// writing |read_ahead_kb| to the /sys/class/bdi/MAJOR:MINOR/read_ahead_kb.
-void ConfigureReadAheadForFuse(const std::string& fuse_mount, size_t read_ahead_kb) {
-    LOG(INFO) << "Configuring read_ahead of " << fuse_mount << " fuse filesystem to "
-              << read_ahead_kb << "kb";
-    std::string fuseBdiPath = getBdiPathForMount(fuse_mount);
-    if (fuseBdiPath == "") {
-        return;
-    }
-    // We found the bdi path for our filesystem, time to configure read ahead!
-    std::string read_ahead_file = StringPrintf("%s/read_ahead_kb", fuseBdiPath.c_str());
-    unique_fd fd(TEMP_FAILURE_RETRY(open(read_ahead_file.c_str(), O_WRONLY | O_CLOEXEC)));
-    if (fd.get() == -1) {
-        PLOG(ERROR) << "Failed to open " << read_ahead_file;
-        return;
-    }
-    LOG(INFO) << "Writing " << read_ahead_kb << " to " << read_ahead_file;
-    if (!WriteStringToFd(std::to_string(read_ahead_kb), fd)) {
-        PLOG(ERROR) << "Failed to write to " << read_ahead_file;
-    }
-}
-
-android::status_t MountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
-                       const std::string& relative_upper_path, android::base::unique_fd* fuse_fd) {
-    std::string pre_fuse_path(StringPrintf("/mnt/user/%d", user_id));
-    std::string fuse_path(
-            StringPrintf("%s/%s", pre_fuse_path.c_str(), relative_upper_path.c_str()));
-
-    std::string pre_pass_through_path(StringPrintf("/mnt/pass_through/%d", user_id));
-    std::string pass_through_path(
-            StringPrintf("%s/%s", pre_pass_through_path.c_str(), relative_upper_path.c_str()));
-
-    // Ensure that /mnt/user is 0700. With FUSE, apps don't need access to /mnt/user paths directly.
-    // Without FUSE however, apps need /mnt/user access so /mnt/user in init.rc is 0755 until here
-    auto result = PrepareDir("/mnt/user", 0750, AID_ROOT, AID_MEDIA_RW);
-    if (result != android::OK) {
-        PLOG(ERROR) << "Failed to prepare directory /mnt/user";
-        return -1;
-    }
-
-    // Shell is neither AID_ROOT nor AID_EVERYBODY. Since it equally needs 'execute' access to
-    // /mnt/user/0 to 'adb shell ls /sdcard' for instance, we set the uid bit of /mnt/user/0 to
-    // AID_SHELL. This gives shell access along with apps running as group everybody (user 0 apps)
-    // These bits should be consistent with what is set in zygote in
-    // com_android_internal_os_Zygote#MountEmulatedStorage on volume bind mount during app fork
-    result = PrepareDir(pre_fuse_path, 0710, user_id ? AID_ROOT : AID_SHELL,
-                             multiuser_get_uid(user_id, AID_EVERYBODY));
-    if (result != android::OK) {
-        PLOG(ERROR) << "Failed to prepare directory " << pre_fuse_path;
-        return -1;
-    }
-
-    result = PrepareDir(fuse_path, 0700, AID_ROOT, AID_ROOT);
-    if (result != android::OK) {
-        PLOG(ERROR) << "Failed to prepare directory " << fuse_path;
-        return -1;
-    }
-
-    result = PrepareDir(pre_pass_through_path, 0710, AID_ROOT, AID_MEDIA_RW);
-    if (result != android::OK) {
-        PLOG(ERROR) << "Failed to prepare directory " << pre_pass_through_path;
-        return -1;
-    }
-
-    result = PrepareDir(pass_through_path, 0710, AID_ROOT, AID_MEDIA_RW);
-    if (result != android::OK) {
-        PLOG(ERROR) << "Failed to prepare directory " << pass_through_path;
-        return -1;
-    }
-
-    if (relative_upper_path == "emulated") {
-        std::string linkpath(StringPrintf("/mnt/user/%d/self", user_id));
-        result = PrepareDir(linkpath, 0755, AID_ROOT, AID_ROOT);
-        if (result != android::OK) {
-            PLOG(ERROR) << "Failed to prepare directory " << linkpath;
-            return -1;
-        }
-        linkpath += "/primary";
-        Symlink("/storage/emulated/" + std::to_string(user_id), linkpath);
-
-        std::string pass_through_linkpath(StringPrintf("/mnt/pass_through/%d/self", user_id));
-        result = PrepareDir(pass_through_linkpath, 0710, AID_ROOT, AID_MEDIA_RW);
-        if (result != android::OK) {
-            PLOG(ERROR) << "Failed to prepare directory " << pass_through_linkpath;
-            return -1;
-        }
-        pass_through_linkpath += "/primary";
-        Symlink("/storage/emulated/" + std::to_string(user_id), pass_through_linkpath);
-    }
-
-    // Open fuse fd.
-    fuse_fd->reset(open("/dev/fuse", O_RDWR | O_CLOEXEC));
-    if (fuse_fd->get() == -1) {
-        PLOG(ERROR) << "Failed to open /dev/fuse";
-        return -1;
-    }
-
-    // Note: leaving out default_permissions since we don't want kernel to do lower filesystem
-    // permission checks before routing to FUSE daemon.
-    const auto opts = StringPrintf(
-        "fd=%i,"
-        "rootmode=40000,"
-        "allow_other,"
-        "user_id=0,group_id=0,",
-        fuse_fd->get());
-
-    result = TEMP_FAILURE_RETRY(mount("/dev/fuse", fuse_path.c_str(), "fuse",
-                                      MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME | MS_LAZYTIME,
-                                      opts.c_str()));
-    if (result != 0) {
-        PLOG(ERROR) << "Failed to mount " << fuse_path;
-        return -errno;
-    }
-
-    if (IsSdcardfsUsed()) {
-        std::string sdcardfs_path(
-                StringPrintf("/mnt/runtime/full/%s", relative_upper_path.c_str()));
-
-        LOG(INFO) << "Bind mounting " << sdcardfs_path << " to " << pass_through_path;
-        return BindMount(sdcardfs_path, pass_through_path);
-    } else {
-        LOG(INFO) << "Bind mounting " << absolute_lower_path << " to " << pass_through_path;
-        return BindMount(absolute_lower_path, pass_through_path);
-    }
-}
-
-android::status_t UnmountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
-                         const std::string& relative_upper_path) {
-    std::string fuse_path(StringPrintf("/mnt/user/%d/%s", user_id, relative_upper_path.c_str()));
-    std::string pass_through_path(
-            StringPrintf("/mnt/pass_through/%d/%s", user_id, relative_upper_path.c_str()));
-
-    // Best effort unmount pass_through path
-    sSleepOnUnmount = false;
-    LOG(INFO) << "Unmounting pass_through_path " << pass_through_path;
-    auto status = ForceUnmount(pass_through_path);
-    if (status != android::OK) {
-        LOG(ERROR) << "Failed to unmount " << pass_through_path;
-    }
-    rmdir(pass_through_path.c_str());
-
-    LOG(INFO) << "Unmounting fuse path " << fuse_path;
-    android::status_t result = ForceUnmount(fuse_path);
-    sSleepOnUnmount = true;
-    if (result != android::OK) {
-        // TODO(b/135341433): MNT_DETACH is needed for fuse because umount2 can fail with EBUSY.
-        // Figure out why we get EBUSY and remove this special casing if possible.
-        PLOG(ERROR) << "Failed to unmount. Trying MNT_DETACH " << fuse_path << " ...";
-        if (umount2(fuse_path.c_str(), UMOUNT_NOFOLLOW | MNT_DETACH) && errno != EINVAL &&
-            errno != ENOENT) {
-            PLOG(ERROR) << "Failed to unmount with MNT_DETACH " << fuse_path;
-            return -errno;
-        }
-        result = android::OK;
-    }
-    rmdir(fuse_path.c_str());
-
-    return result;
-}
-
-android::status_t PrepareAndroidDirs(const std::string& volumeRoot) {
-    std::string androidDir = volumeRoot + kAndroidDir;
-    std::string androidDataDir = volumeRoot + kAppDataDir;
-    std::string androidObbDir = volumeRoot + kAppObbDir;
-    std::string androidMediaDir = volumeRoot + kAppMediaDir;
-
-    bool useSdcardFs = IsSdcardfsUsed();
-
-    // mode 0771 + sticky bit for inheriting GIDs
-    mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH | S_ISGID;
-    if (fs_prepare_dir(androidDir.c_str(), mode, AID_MEDIA_RW, AID_MEDIA_RW) != 0) {
-        PLOG(ERROR) << "Failed to create " << androidDir;
-        return -errno;
-    }
-
-    gid_t dataGid = useSdcardFs ? AID_MEDIA_RW : AID_EXT_DATA_RW;
-    if (fs_prepare_dir(androidDataDir.c_str(), mode, AID_MEDIA_RW, dataGid) != 0) {
-        PLOG(ERROR) << "Failed to create " << androidDataDir;
-        return -errno;
-    }
-
-    gid_t obbGid = useSdcardFs ? AID_MEDIA_RW : AID_EXT_OBB_RW;
-    if (fs_prepare_dir(androidObbDir.c_str(), mode, AID_MEDIA_RW, obbGid) != 0) {
-        PLOG(ERROR) << "Failed to create " << androidObbDir;
-        return -errno;
-    }
-    // Some other apps, like installers, have write access to the OBB directory
-    // to pre-download them. To make sure newly created folders in this directory
-    // have the right permissions, set a default ACL.
-    SetDefaultAcl(androidObbDir, mode, AID_MEDIA_RW, obbGid, {});
-
-    if (fs_prepare_dir(androidMediaDir.c_str(), mode, AID_MEDIA_RW, AID_MEDIA_RW) != 0) {
-        PLOG(ERROR) << "Failed to create " << androidMediaDir;
-        return -errno;
-    }
-
-    return android::OK;
-}
diff --git a/crypto/fscrypt/Utils.h b/crypto/fscrypt/Utils.h
deleted file mode 100755
index e820711..0000000
--- a/crypto/fscrypt/Utils.h
+++ /dev/null
@@ -1,188 +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 ANDROID_VOLD_UTILS_H
-#define ANDROID_VOLD_UTILS_H
-
-#include "KeyBuffer.h"
-
-#include <android-base/macros.h>
-#include <android-base/unique_fd.h>
-#include <cutils/multiuser.h>
-#include <selinux/selinux.h>
-#include <utils/Errors.h>
-
-#include <chrono>
-#include <string>
-#include <vector>
-
-struct DIR;
-
-static const char* kPropFuse = "persist.sys.fuse";
-static const char* kVoldAppDataIsolationEnabled = "persist.sys.vold_app_data_isolation_enabled";
-static const char* kExternalStorageSdcardfs = "external_storage.sdcardfs.enabled";
-
-/* SELinux contexts used depending on the block device type */
-extern security_context_t sBlkidContext;
-extern security_context_t sBlkidUntrustedContext;
-extern security_context_t sFsckContext;
-extern security_context_t sFsckUntrustedContext;
-
-// TODO remove this with better solution, b/64143519
-extern bool sSleepOnUnmount;
-
-std::string GetFuseMountPathForUser(userid_t user_id, const std::string& relative_upper_path);
-
-android::status_t CreateDeviceNode(const std::string& path, dev_t dev);
-android::status_t DestroyDeviceNode(const std::string& path);
-
-android::status_t AbortFuseConnections();
-
-int SetQuotaInherit(const std::string& path);
-int SetQuotaProjectId(const std::string& path, long projectId);
-/*
- * Creates and sets up an application-specific path on external
- * storage with the correct ACL and project ID (if needed).
- *
- * ONLY for use with app-specific data directories on external storage!
- * (eg, /Android/data/com.foo, /Android/obb/com.foo, etc.)
- */
-int PrepareAppDirFromRoot(const std::string& path, const std::string& root, int appUid,
-                          bool fixupExisting);
-
-/* fs_prepare_dir wrapper that creates with SELinux context */
-android::status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid);
-
-/* Really unmounts the path, killing active processes along the way */
-android::status_t ForceUnmount(const std::string& path);
-
-/* Kills any processes using given path */
-android::status_t KillProcessesUsingPath(const std::string& path);
-
-/* Kills any processes using given mount prifix */
-android::status_t KillProcessesWithMountPrefix(const std::string& path);
-
-/* Creates bind mount from source to target */
-android::status_t BindMount(const std::string& source, const std::string& target);
-
-/** Creates a symbolic link to target */
-android::status_t Symlink(const std::string& target, const std::string& linkpath);
-
-/** Calls unlink(2) at linkpath */
-android::status_t Unlink(const std::string& linkpath);
-
-/** Creates the given directory if it is not already available */
-android::status_t CreateDir(const std::string& dir, mode_t mode);
-
-bool FindValue(const std::string& raw, const std::string& key, std::string* value);
-
-/* Reads filesystem metadata from device at path */
-android::status_t ReadMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
-                      std::string* fsLabel);
-
-/* Reads filesystem metadata from untrusted device at path */
-android::status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, std::string* fsUuid,
-                               std::string* fsLabel);
-
-/* Returns either WEXITSTATUS() status, or a negative errno */
-android::status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>* output = nullptr,
-                    security_context_t context = nullptr);
-
-pid_t ForkExecvpAsync(const std::vector<std::string>& args);
-
-/* Gets block device size in bytes */
-android::status_t GetBlockDevSize(int fd, uint64_t* size);
-android::status_t GetBlockDevSize(const std::string& path, uint64_t* size);
-/* Gets block device size in 512 byte sectors */
-android::status_t GetBlockDev512Sectors(const std::string& path, uint64_t* nr_sec);
-
-android::status_t ReadRandomBytes(size_t bytes, std::string& out);
-android::status_t ReadRandomBytes(size_t bytes, char* buffer);
-android::status_t GenerateRandomUuid(std::string& out);
-
-/* Converts hex string to raw bytes, ignoring [ :-] */
-android::status_t HexToStr(const std::string& hex, std::string& str);
-/* Converts raw bytes to hex string */
-android::status_t StrToHex(const std::string& str, std::string& hex);
-/* Converts raw key bytes to hex string */
-android::status_t StrToHex(const KeyBuffer& str, KeyBuffer& hex);
-/* Normalize given hex string into consistent format */
-android::status_t NormalizeHex(const std::string& in, std::string& out);
-
-uint64_t GetFreeBytes(const std::string& path);
-uint64_t GetTreeBytes(const std::string& path);
-
-bool IsFilesystemSupported(const std::string& fsType);
-bool IsSdcardfsUsed();
-bool IsFuseDaemon(const pid_t pid);
-
-/* Wipes contents of block device at given path */
-android::status_t WipeBlockDevice(const std::string& path);
-
-std::string BuildKeyPath(const std::string& partGuid);
-
-std::string BuildDataSystemLegacyPath(userid_t userid);
-std::string BuildDataSystemCePath(userid_t userid);
-std::string BuildDataSystemDePath(userid_t userid);
-std::string BuildDataMiscLegacyPath(userid_t userid);
-std::string BuildDataMiscCePath(userid_t userid);
-std::string BuildDataMiscDePath(userid_t userid);
-std::string BuildDataProfilesDePath(userid_t userid);
-std::string BuildDataVendorCePath(userid_t userid);
-std::string BuildDataVendorDePath(userid_t userid);
-
-std::string BuildDataPath(const std::string& volumeUuid);
-std::string BuildDataMediaCePath(const std::string& volumeUuid, userid_t userid);
-std::string BuildDataUserCePath(const std::string& volumeUuid, userid_t userid);
-std::string BuildDataUserDePath(const std::string& volumeUuid, userid_t userid);
-
-dev_t GetDevice(const std::string& path);
-
-android::status_t EnsureDirExists(const std::string& path, mode_t mode, uid_t uid, gid_t gid);
-
-android::status_t RestoreconRecursive(const std::string& path);
-
-// TODO: promote to android::base
-bool Readlinkat(int dirfd, const std::string& path, std::string* result);
-
-// Handles dynamic major assignment for virtio-block
-bool IsVirtioBlkDevice(unsigned int major);
-
-android::status_t UnmountTreeWithPrefix(const std::string& prefix);
-android::status_t UnmountTree(const std::string& mountPoint);
-
-android::status_t DeleteDirContentsAndDir(const std::string& pathname);
-android::status_t DeleteDirContents(const std::string& pathname);
-
-android::status_t WaitForFile(const char* filename, std::chrono::nanoseconds timeout);
-
-bool FsyncDirectory(const std::string& dirname);
-
-bool writeStringToFile(const std::string& payload, const std::string& filename);
-
-void ConfigureMaxDirtyRatioForFuse(const std::string& fuse_mount, unsigned int max_ratio);
-
-void ConfigureReadAheadForFuse(const std::string& fuse_mount, size_t read_ahead_kb);
-
-android::status_t MountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
-                       const std::string& relative_upper_path, android::base::unique_fd* fuse_fd);
-
-android::status_t UnmountUserFuse(userid_t userId, const std::string& absolute_lower_path,
-                         const std::string& relative_upper_path);
-
-android::status_t PrepareAndroidDirs(const std::string& volumeRoot);
-
-#endif
diff --git a/crypto/fscrypt/VoldUtil.cpp b/crypto/fscrypt/VoldUtil.cpp
deleted file mode 100644
index 082f743..0000000
--- a/crypto/fscrypt/VoldUtil.cpp
+++ /dev/null
@@ -1,19 +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.
- */
-
-#include "VoldUtil.h"
-
-android::fs_mgr::Fstab fstab_default;
diff --git a/crypto/fscrypt/VoldUtil.h b/crypto/fscrypt/VoldUtil.h
deleted file mode 100644
index e0945bf..0000000
--- a/crypto/fscrypt/VoldUtil.h
+++ /dev/null
@@ -1,24 +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.
- */
-
-#pragma once
-
-#include <fstab/fstab.h>
-
-extern android::fs_mgr::Fstab fstab_default;
-
-#define DATA_MNT_POINT "/data"
-#define METADATA_MNT_POINT "/metadata"
diff --git a/crypto/fscrypt/Weaver1.cpp b/crypto/fscrypt/Weaver1.cpp
deleted file mode 100644
index ea357ed..0000000
--- a/crypto/fscrypt/Weaver1.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2017 Team Win Recovery 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.
- */
-
-/* To the best of my knowledge there is no native implementation for
- * Weaver so I made this by looking at the IWeaver.h file that gets
- * compiled by the build system. I took the information from this header
- * file and looked at keymaster source to get an idea of the proper way
- * to write the functions.
- */
-
-#include "Weaver1.h"
-
-//#include <android-base/logging.h>
-//#include <keystore/keymaster_tags.h>
-//#include <keystore/authorization_set.h>
-//#include <keystore/keystore_hidl_support.h>
-
-#include <android/hardware/weaver/1.0/IWeaver.h>
-
-#include <iostream>
-#define ERROR 1
-#define LOG(x) std::cout
-
-using namespace android::hardware::weaver;
-using android::hardware::hidl_string;
-using ::android::hardware::weaver::V1_0::IWeaver;
-using ::android::hardware::weaver::V1_0::WeaverConfig;
-using ::android::hardware::weaver::V1_0::WeaverReadStatus;
-using ::android::hardware::weaver::V1_0::WeaverReadResponse;
-using ::android::hardware::weaver::V1_0::WeaverStatus;
-using ::android::hardware::Return;
-using ::android::sp;
-
-namespace android {
-namespace vold {
-
-Weaver::Weaver() {
-	mDevice = ::android::hardware::weaver::V1_0::IWeaver::getService();
-	GottenConfig = false;
-}
-
-bool Weaver::GetConfig() {
-	if (GottenConfig)
-		return true;
-
-	WeaverStatus status;
-	WeaverConfig cfg;
-
-	bool callbackCalled = false;
-	auto ret = mDevice->getConfig([&](WeaverStatus s, WeaverConfig c) {
-		callbackCalled = true;
-		status = s;
-		cfg = c;
-	});
-	if (ret.isOk() && callbackCalled && status == WeaverStatus::OK) {
-		config = cfg;
-		GottenConfig = true;
-		return true;
-	}
-	return false;
-}
-
-bool Weaver::GetSlots(uint32_t* slots) {
-	if (!GetConfig())
-		return false;
-	*slots = config.slots;
-	return true;
-}
-
-bool Weaver::GetKeySize(uint32_t* keySize) {
-	if (!GetConfig())
-		return false;
-	*keySize = config.keySize;
-	return true;
-}
-
-bool Weaver::GetValueSize(uint32_t* valueSize) {
-	if (!GetConfig())
-		return false;
-	*valueSize = config.valueSize;
-	return true;
-}
-
-// TODO: we should return more information about the status including time delays before the next retry
-bool Weaver::WeaverVerify(const uint32_t slot, const void* weaver_key, std::vector<uint8_t>* payload) {
-	bool callbackCalled = false;
-	WeaverReadStatus status;
-	std::vector<uint8_t> readValue;
-	uint32_t timeout;
-	uint32_t keySize;
-	if (!GetKeySize(&keySize))
-		return false;
-	std::vector<uint8_t> key;
-	key.resize(keySize);
-	uint32_t index = 0;
-	unsigned char* ptr = (unsigned char*)weaver_key;
-	for (index = 0; index < keySize; index++) {
-		key[index] = *ptr;
-		ptr++;
-	}
-	const auto readRet = mDevice->read(slot, key, [&](WeaverReadStatus s, WeaverReadResponse r) {
-		callbackCalled = true;
-		status = s;
-		readValue = r.value;
-		timeout = r.timeout;
-	});
-	if (readRet.isOk() && callbackCalled && status == WeaverReadStatus::OK && timeout == 0) {
-		*payload = readValue;
-		return true;
-	}
-	return false;
-}
-
-}  // namespace vold
-}  // namespace android
diff --git a/crypto/fscrypt/Weaver1.h b/crypto/fscrypt/Weaver1.h
deleted file mode 100644
index 22f401e..0000000
--- a/crypto/fscrypt/Weaver1.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2017 Team Win Recovery 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.
- */
-
-/* To the best of my knowledge there is no native implementation for
- * Weaver so I made this by looking at the IWeaver.h file that gets
- * compiled by the build system. I took the information from this header
- * file and looked at keymaster source to get an idea of the proper way
- * to write the functions.
- */
-
-#ifndef TWRP_WEAVER_H
-#define TWRP_WEAVER_H
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <android/hardware/weaver/1.0/IWeaver.h>
-#include "Utils.h"
-
-namespace android {
-namespace vold {
-using ::android::hardware::weaver::V1_0::IWeaver;
-
-// Wrapper for a Weaver device
-class Weaver {
-	public:
-		Weaver();
-		// false if we failed to open the weaver device.
-		explicit operator bool() { return mDevice.get() != nullptr; }
-
-		bool GetSlots(uint32_t* slots);
-		bool GetKeySize(uint32_t* keySize);
-		bool GetValueSize(uint32_t* valueSize);
-		// TODO: we should return more information about the status including time delays before the next retry
-		bool WeaverVerify(const uint32_t slot, const void* weaver_key, std::vector<uint8_t>* payload);
-
-	private:
-		sp<hardware::weaver::V1_0::IWeaver> mDevice;
-		hardware::weaver::V1_0::WeaverConfig config;
-		bool GottenConfig;
-
-		bool GetConfig();
-
-		DISALLOW_COPY_AND_ASSIGN(Weaver);
-};
-
-}  // namespace vold
-}  // namespace android
-
-#endif
diff --git a/crypto/fscrypt/cryptfs.cpp b/crypto/fscrypt/cryptfs.cpp
deleted file mode 100644
index b58c343..0000000
--- a/crypto/fscrypt/cryptfs.cpp
+++ /dev/null
@@ -1,2902 +0,0 @@
-/*
- * Copyright (C) 2010 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 "Cryptfs"
-
-#include "cryptfs.h"
-
-#include "Checkpoint.h"
-#include "CryptoType.h"
-#include "EncryptInplace.h"
-#include "FsCrypt.h"
-#include "Keymaster.h"
-#include "Process.h"
-#include "ScryptParameters.h"
-#include "Utils.h"
-#include "VoldUtil.h"
-#include "VolumeManager.h"
-
-#include <android-base/parseint.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <bootloader_message/bootloader_message.h>
-#include <cutils/android_reboot.h>
-#include <cutils/properties.h>
-#include <ext4_utils/ext4_utils.h>
-#include <f2fs_sparseblock.h>
-#include <fs_mgr.h>
-#include <fscrypt/fscrypt.h>
-#include <libdm/dm.h>
-#include <log/log.h>
-#include <logwrap/logwrap.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-#include <selinux/selinux.h>
-// #include <wakelock/wakelock.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <libgen.h>
-#include <linux/kdev_t.h>
-#include <math.h>
-#include <mntent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <thread>
-
-extern "C" {
-#include <crypto_scrypt.h>
-}
-
-using android::base::ParseUint;
-using android::base::StringPrintf;
-using android::fs_mgr::GetEntryForMountPoint;
-using ::CryptoType;
-using ::KeyBuffer;
-using ::KeyGeneration;
-using namespace android::dm;
-using namespace std::chrono_literals;
-
-/* The current cryptfs version */
-#define CURRENT_MAJOR_VERSION 1
-#define CURRENT_MINOR_VERSION 3
-
-#define CRYPT_FOOTER_TO_PERSIST_OFFSET 0x1000
-#define CRYPT_PERSIST_DATA_SIZE 0x1000
-
-#define MAX_CRYPTO_TYPE_NAME_LEN 64
-
-#define MAX_KEY_LEN 48
-#define SALT_LEN 16
-#define SCRYPT_LEN 32
-
-/* definitions of flags in the structure below */
-#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */
-#define CRYPT_ENCRYPTION_IN_PROGRESS       \
-    0x2 /* Encryption partially completed, \
-           encrypted_upto valid*/
-#define CRYPT_INCONSISTENT_STATE                    \
-    0x4 /* Set when starting encryption, clear when \
-           exit cleanly, either through success or  \
-           correctly marked partial encryption */
-#define CRYPT_DATA_CORRUPT                      \
-    0x8 /* Set when encryption is fine, but the \
-           underlying volume is corrupt */
-#define CRYPT_FORCE_ENCRYPTION                        \
-    0x10 /* Set when it is time to encrypt this       \
-            volume on boot. Everything in this        \
-            structure is set up correctly as          \
-            though device is encrypted except         \
-            that the master key is encrypted with the \
-            default password. */
-#define CRYPT_FORCE_COMPLETE                           \
-    0x20 /* Set when the above encryption cycle is     \
-            complete. On next cryptkeeper entry, match \
-            the password. If it matches fix the master \
-            key and remove this flag. */
-
-/* Allowed values for type in the structure below */
-#define CRYPT_TYPE_PASSWORD                       \
-    0 /* master_key is encrypted with a password  \
-       * Must be zero to be compatible with pre-L \
-       * devices where type is always password.*/
-#define CRYPT_TYPE_DEFAULT                                            \
-    1                         /* master_key is encrypted with default \
-                               * password */
-#define CRYPT_TYPE_PATTERN 2  /* master_key is encrypted with a pattern */
-#define CRYPT_TYPE_PIN 3      /* master_key is encrypted with a pin */
-#define CRYPT_TYPE_MAX_TYPE 3 /* type cannot be larger than this value */
-
-#define CRYPT_MNT_MAGIC 0xD0B5B1C4
-#define PERSIST_DATA_MAGIC 0xE950CD44
-
-/* Key Derivation Function algorithms */
-#define KDF_PBKDF2 1
-#define KDF_SCRYPT 2
-/* Algorithms 3 & 4 deprecated before shipping outside of google, so removed */
-#define KDF_SCRYPT_KEYMASTER 5
-
-/* Maximum allowed keymaster blob size. */
-#define KEYMASTER_BLOB_SIZE 2048
-
-/* __le32 and __le16 defined in system/extras/ext4_utils/ext4_utils.h */
-#define __le8 unsigned char
-
-#if !defined(SHA256_DIGEST_LENGTH)
-#define SHA256_DIGEST_LENGTH 32
-#endif
-
-/* This structure starts 16,384 bytes before the end of a hardware
- * partition that is encrypted, or in a separate partition.  It's location
- * is specified by a property set in init.<device>.rc.
- * The structure allocates 48 bytes for a key, but the real key size is
- * specified in the struct.  Currently, the code is hardcoded to use 128
- * bit keys.
- * The fields after salt are only valid in rev 1.1 and later stuctures.
- * Obviously, the filesystem does not include the last 16 kbytes
- * of the partition if the crypt_mnt_ftr lives at the end of the
- * partition.
- */
-
-struct crypt_mnt_ftr {
-    __le32 magic; /* See above */
-    __le16 major_version;
-    __le16 minor_version;
-    __le32 ftr_size;             /* in bytes, not including key following */
-    __le32 flags;                /* See above */
-    __le32 keysize;              /* in bytes */
-    __le32 crypt_type;           /* how master_key is encrypted. Must be a
-                                  * CRYPT_TYPE_XXX value */
-    __le64 fs_size;              /* Size of the encrypted fs, in 512 byte sectors */
-    __le32 failed_decrypt_count; /* count of # of failed attempts to decrypt and
-                                    mount, set to 0 on successful mount */
-    unsigned char crypto_type_name[MAX_CRYPTO_TYPE_NAME_LEN]; /* The type of encryption
-                                                                 needed to decrypt this
-                                                                 partition, null terminated */
-    __le32 spare2;                                            /* ignored */
-    unsigned char master_key[MAX_KEY_LEN]; /* The encrypted key for decrypting the filesystem */
-    unsigned char salt[SALT_LEN];          /* The salt used for this encryption */
-    __le64 persist_data_offset[2];         /* Absolute offset to both copies of crypt_persist_data
-                                            * on device with that info, either the footer of the
-                                            * real_blkdevice or the metadata partition. */
-
-    __le32 persist_data_size; /* The number of bytes allocated to each copy of the
-                               * persistent data table*/
-
-    __le8 kdf_type; /* The key derivation function used. */
-
-    /* scrypt parameters. See www.tarsnap.com/scrypt/scrypt.pdf */
-    __le8 N_factor;        /* (1 << N) */
-    __le8 r_factor;        /* (1 << r) */
-    __le8 p_factor;        /* (1 << p) */
-    __le64 encrypted_upto; /* If we are in state CRYPT_ENCRYPTION_IN_PROGRESS and
-                              we have to stop (e.g. power low) this is the last
-                              encrypted 512 byte sector.*/
-    __le8 hash_first_block[SHA256_DIGEST_LENGTH]; /* When CRYPT_ENCRYPTION_IN_PROGRESS
-                                                     set, hash of first block, used
-                                                     to validate before continuing*/
-
-    /* key_master key, used to sign the derived key which is then used to generate
-     * the intermediate key
-     * This key should be used for no other purposes! We use this key to sign unpadded
-     * data, which is acceptable but only if the key is not reused elsewhere. */
-    __le8 keymaster_blob[KEYMASTER_BLOB_SIZE];
-    __le32 keymaster_blob_size;
-
-    /* Store scrypt of salted intermediate key. When decryption fails, we can
-       check if this matches, and if it does, we know that the problem is with the
-       drive, and there is no point in asking the user for more passwords.
-
-       Note that if any part of this structure is corrupt, this will not match and
-       we will continue to believe the user entered the wrong password. In that
-       case the only solution is for the user to enter a password enough times to
-       force a wipe.
-
-       Note also that there is no need to worry about migration. If this data is
-       wrong, we simply won't recognise a right password, and will continue to
-       prompt. On the first password change, this value will be populated and
-       then we will be OK.
-     */
-    unsigned char scrypted_intermediate_key[SCRYPT_LEN];
-
-    /* sha of this structure with this element set to zero
-       Used when encrypting on reboot to validate structure before doing something
-       fatal
-     */
-    unsigned char sha256[SHA256_DIGEST_LENGTH];
-};
-
-/* Persistant data that should be available before decryption.
- * Things like airplane mode, locale and timezone are kept
- * here and can be retrieved by the CryptKeeper UI to properly
- * configure the phone before asking for the password
- * This is only valid if the major and minor version above
- * is set to 1.1 or higher.
- *
- * This is a 4K structure.  There are 2 copies, and the code alternates
- * writing one and then clearing the previous one.  The reading
- * code reads the first valid copy it finds, based on the magic number.
- * The absolute offset to the first of the two copies is kept in rev 1.1
- * and higher crypt_mnt_ftr structures.
- */
-struct crypt_persist_entry {
-    char key[PROPERTY_KEY_MAX];
-    char val[PROPERTY_VALUE_MAX];
-};
-
-/* Should be exactly 4K in size */
-struct crypt_persist_data {
-    __le32 persist_magic;
-    __le32 persist_valid_entries;
-    __le32 persist_spare[30];
-    struct crypt_persist_entry persist_entry[0];
-};
-
-static int wait_and_unmount(const char* mountpoint, bool kill);
-
-typedef int (*kdf_func)(const char* passwd, const unsigned char* salt, unsigned char* ikey,
-                        void* params);
-
-#define UNUSED __attribute__((unused))
-
-#define HASH_COUNT 2000
-
-constexpr size_t INTERMEDIATE_KEY_LEN_BYTES = 16;
-constexpr size_t INTERMEDIATE_IV_LEN_BYTES = 16;
-constexpr size_t INTERMEDIATE_BUF_SIZE = (INTERMEDIATE_KEY_LEN_BYTES + INTERMEDIATE_IV_LEN_BYTES);
-
-// SCRYPT_LEN is used by struct crypt_mnt_ftr for its intermediate key.
-static_assert(INTERMEDIATE_BUF_SIZE == SCRYPT_LEN, "Mismatch of intermediate key sizes");
-
-#define KEY_IN_FOOTER "footer"
-
-#define DEFAULT_PASSWORD "default_password"
-
-#define CRYPTO_BLOCK_DEVICE "userdata"
-
-#define BREADCRUMB_FILE "/data/misc/vold/convert_fde"
-
-#define EXT4_FS 1
-#define F2FS_FS 2
-
-#define TABLE_LOAD_RETRIES 10
-
-#define RSA_KEY_SIZE 2048
-#define RSA_KEY_SIZE_BYTES (RSA_KEY_SIZE / 8)
-#define RSA_EXPONENT 0x10001
-#define KEYMASTER_CRYPTFS_RATE_LIMIT 1  // Maximum one try per second
-
-#define RETRY_MOUNT_ATTEMPTS 10
-#define RETRY_MOUNT_DELAY_SECONDS 1
-
-#define CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE (1)
-
-static int put_crypt_ftr_and_key(struct crypt_mnt_ftr* crypt_ftr);
-
-static unsigned char saved_master_key[MAX_KEY_LEN];
-static char* saved_mount_point;
-static int master_key_saved = 0;
-static struct crypt_persist_data* persist_data = NULL;
-
-constexpr CryptoType aes_128_cbc = CryptoType()
-                                           .set_config_name("AES-128-CBC")
-                                           .set_kernel_name("aes-cbc-essiv:sha256")
-                                           .set_keysize(16);
-
-constexpr CryptoType supported_crypto_types[] = {aes_128_cbc, ::adiantum};
-
-static_assert(validateSupportedCryptoTypes(MAX_KEY_LEN, supported_crypto_types,
-                                           array_length(supported_crypto_types)),
-              "We have a CryptoType with keysize > MAX_KEY_LEN or which was "
-              "incompletely constructed.");
-
-static const CryptoType& get_crypto_type() {
-    // We only want to parse this read-only property once.  But we need to wait
-    // until the system is initialized before we can read it.  So we use a static
-    // scoped within this function to get it only once.
-    static CryptoType crypto_type =
-            lookup_crypto_algorithm(supported_crypto_types, array_length(supported_crypto_types),
-                                    aes_128_cbc, "ro.crypto.fde_algorithm");
-    return crypto_type;
-}
-
-const KeyGeneration cryptfs_get_keygen() {
-    return KeyGeneration{get_crypto_type().get_keysize(), true, false};
-}
-
-/* Should we use keymaster? */
-static int keymaster_check_compatibility() {
-    return keymaster_compatibility_cryptfs_scrypt();
-}
-
-/* Create a new keymaster key and store it in this footer */
-static int keymaster_create_key(struct crypt_mnt_ftr* ftr) {
-    if (ftr->keymaster_blob_size) {
-        SLOGI("Already have key");
-        return 0;
-    }
-
-    int rc = keymaster_create_key_for_cryptfs_scrypt(
-        RSA_KEY_SIZE, RSA_EXPONENT, KEYMASTER_CRYPTFS_RATE_LIMIT, ftr->keymaster_blob,
-        KEYMASTER_BLOB_SIZE, &ftr->keymaster_blob_size);
-    if (rc) {
-        if (ftr->keymaster_blob_size > KEYMASTER_BLOB_SIZE) {
-            SLOGE("Keymaster key blob too large");
-            ftr->keymaster_blob_size = 0;
-        }
-        SLOGE("Failed to generate keypair");
-        return -1;
-    }
-    return 0;
-}
-
-/* This signs the given object using the keymaster key. */
-static int keymaster_sign_object(struct crypt_mnt_ftr* ftr, const unsigned char* object,
-                                 const size_t object_size, unsigned char** signature,
-                                 size_t* signature_size) {
-    unsigned char to_sign[RSA_KEY_SIZE_BYTES];
-    size_t to_sign_size = sizeof(to_sign);
-    memset(to_sign, 0, RSA_KEY_SIZE_BYTES);
-
-    // To sign a message with RSA, the message must satisfy two
-    // constraints:
-    //
-    // 1. The message, when interpreted as a big-endian numeric value, must
-    //    be strictly less than the public modulus of the RSA key.  Note
-    //    that because the most significant bit of the public modulus is
-    //    guaranteed to be 1 (else it's an (n-1)-bit key, not an n-bit
-    //    key), an n-bit message with most significant bit 0 always
-    //    satisfies this requirement.
-    //
-    // 2. The message must have the same length in bits as the public
-    //    modulus of the RSA key.  This requirement isn't mathematically
-    //    necessary, but is necessary to ensure consistency in
-    //    implementations.
-    switch (ftr->kdf_type) {
-        case KDF_SCRYPT_KEYMASTER:
-            // This ensures the most significant byte of the signed message
-            // is zero.  We could have zero-padded to the left instead, but
-            // this approach is slightly more robust against changes in
-            // object size.  However, it's still broken (but not unusably
-            // so) because we really should be using a proper deterministic
-            // RSA padding function, such as PKCS1.
-            memcpy(to_sign + 1, object, std::min((size_t)RSA_KEY_SIZE_BYTES - 1, object_size));
-            SLOGI("Signing safely-padded object");
-            break;
-        default:
-            SLOGE("Unknown KDF type %d", ftr->kdf_type);
-            return -1;
-    }
-    for (;;) {
-        auto result = keymaster_sign_object_for_cryptfs_scrypt(
-            ftr->keymaster_blob, ftr->keymaster_blob_size, KEYMASTER_CRYPTFS_RATE_LIMIT, to_sign,
-            to_sign_size, signature, signature_size);
-        switch (result) {
-            case KeymasterSignResult::ok:
-                return 0;
-            case KeymasterSignResult::upgrade:
-                break;
-            default:
-                return -1;
-        }
-        SLOGD("Upgrading key");
-        if (keymaster_upgrade_key_for_cryptfs_scrypt(
-                RSA_KEY_SIZE, RSA_EXPONENT, KEYMASTER_CRYPTFS_RATE_LIMIT, ftr->keymaster_blob,
-                ftr->keymaster_blob_size, ftr->keymaster_blob, KEYMASTER_BLOB_SIZE,
-                &ftr->keymaster_blob_size) != 0) {
-            SLOGE("Failed to upgrade key");
-            return -1;
-        }
-        if (put_crypt_ftr_and_key(ftr) != 0) {
-            SLOGE("Failed to write upgraded key to disk");
-        }
-        SLOGD("Key upgraded successfully");
-    }
-}
-
-/* Store password when userdata is successfully decrypted and mounted.
- * Cleared by cryptfs_clear_password
- *
- * To avoid a double prompt at boot, we need to store the CryptKeeper
- * password and pass it to KeyGuard, which uses it to unlock KeyStore.
- * Since the entire framework is torn down and rebuilt after encryption,
- * we have to use a daemon or similar to store the password. Since vold
- * is secured against IPC except from system processes, it seems a reasonable
- * place to store this.
- *
- * password should be cleared once it has been used.
- *
- * password is aged out after password_max_age_seconds seconds.
- */
-static char* password = 0;
-static int password_expiry_time = 0;
-static const int password_max_age_seconds = 60;
-
-enum class RebootType { reboot, recovery, shutdown };
-static void cryptfs_reboot(RebootType rt) {
-    switch (rt) {
-        case RebootType::reboot:
-            property_set(ANDROID_RB_PROPERTY, "reboot");
-            break;
-
-        case RebootType::recovery:
-            property_set(ANDROID_RB_PROPERTY, "reboot,recovery");
-            break;
-
-        case RebootType::shutdown:
-            property_set(ANDROID_RB_PROPERTY, "shutdown");
-            break;
-    }
-
-    sleep(20);
-
-    /* Shouldn't get here, reboot should happen before sleep times out */
-    return;
-}
-
-/**
- * Gets the default device scrypt parameters for key derivation time tuning.
- * The parameters should lead to about one second derivation time for the
- * given device.
- */
-static void get_device_scrypt_params(struct crypt_mnt_ftr* ftr) {
-    char paramstr[PROPERTY_VALUE_MAX];
-    int Nf, rf, pf;
-
-    property_get(SCRYPT_PROP, paramstr, SCRYPT_DEFAULTS);
-    if (!parse_scrypt_parameters(paramstr, &Nf, &rf, &pf)) {
-        SLOGW("bad scrypt parameters '%s' should be like '12:8:1'; using defaults", paramstr);
-        parse_scrypt_parameters(SCRYPT_DEFAULTS, &Nf, &rf, &pf);
-    }
-    ftr->N_factor = Nf;
-    ftr->r_factor = rf;
-    ftr->p_factor = pf;
-}
-
-static uint64_t get_fs_size(const char* dev) {
-    int fd, block_size;
-    struct ext4_super_block sb;
-    uint64_t len;
-
-    if ((fd = open(dev, O_RDONLY | O_CLOEXEC)) < 0) {
-        SLOGE("Cannot open device to get filesystem size ");
-        return 0;
-    }
-
-    if (lseek64(fd, 1024, SEEK_SET) < 0) {
-        SLOGE("Cannot seek to superblock");
-        return 0;
-    }
-
-    if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) {
-        SLOGE("Cannot read superblock");
-        return 0;
-    }
-
-    close(fd);
-
-    if (le32_to_cpu(sb.s_magic) != EXT4_SUPER_MAGIC) {
-        SLOGE("Not a valid ext4 superblock");
-        return 0;
-    }
-    block_size = 1024 << sb.s_log_block_size;
-    /* compute length in bytes */
-    len = (((uint64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size;
-
-    /* return length in sectors */
-    return len / 512;
-}
-
-static void get_crypt_info(std::string* key_loc, std::string* real_blk_device) {
-    for (const auto& entry : fstab_default) {
-        if (!entry.fs_mgr_flags.vold_managed &&
-            (entry.fs_mgr_flags.crypt || entry.fs_mgr_flags.force_crypt ||
-             entry.fs_mgr_flags.force_fde_or_fbe || entry.fs_mgr_flags.file_encryption)) {
-            if (key_loc != nullptr) {
-                *key_loc = entry.key_loc;
-            }
-            if (real_blk_device != nullptr) {
-                *real_blk_device = entry.blk_device;
-            }
-            return;
-        }
-    }
-}
-
-static int get_crypt_ftr_info(char** metadata_fname, off64_t* off) {
-    static int cached_data = 0;
-    static uint64_t cached_off = 0;
-    static char cached_metadata_fname[PROPERTY_VALUE_MAX] = "";
-    char key_loc[PROPERTY_VALUE_MAX];
-    char real_blkdev[PROPERTY_VALUE_MAX];
-    int rc = -1;
-
-    if (!cached_data) {
-        std::string key_loc;
-        std::string real_blkdev;
-        get_crypt_info(&key_loc, &real_blkdev);
-
-        if (key_loc == KEY_IN_FOOTER) {
-            if (::GetBlockDevSize(real_blkdev, &cached_off) == android::OK) {
-                /* If it's an encrypted Android partition, the last 16 Kbytes contain the
-                 * encryption info footer and key, and plenty of bytes to spare for future
-                 * growth.
-                 */
-                strlcpy(cached_metadata_fname, real_blkdev.c_str(), sizeof(cached_metadata_fname));
-                cached_off -= CRYPT_FOOTER_OFFSET;
-                cached_data = 1;
-            } else {
-                SLOGE("Cannot get size of block device %s\n", real_blkdev.c_str());
-            }
-        } else {
-            strlcpy(cached_metadata_fname, key_loc.c_str(), sizeof(cached_metadata_fname));
-            cached_off = 0;
-            cached_data = 1;
-        }
-    }
-
-    if (cached_data) {
-        if (metadata_fname) {
-            *metadata_fname = cached_metadata_fname;
-        }
-        if (off) {
-            *off = cached_off;
-        }
-        rc = 0;
-    }
-
-    return rc;
-}
-
-/* Set sha256 checksum in structure */
-static void set_ftr_sha(struct crypt_mnt_ftr* crypt_ftr) {
-    SHA256_CTX c;
-    SHA256_Init(&c);
-    memset(crypt_ftr->sha256, 0, sizeof(crypt_ftr->sha256));
-    SHA256_Update(&c, crypt_ftr, sizeof(*crypt_ftr));
-    SHA256_Final(crypt_ftr->sha256, &c);
-}
-
-/* key or salt can be NULL, in which case just skip writing that value.  Useful to
- * update the failed mount count but not change the key.
- */
-static int put_crypt_ftr_and_key(struct crypt_mnt_ftr* crypt_ftr) {
-    int fd;
-    unsigned int cnt;
-    /* starting_off is set to the SEEK_SET offset
-     * where the crypto structure starts
-     */
-    off64_t starting_off;
-    int rc = -1;
-    char* fname = NULL;
-    struct stat statbuf;
-
-    set_ftr_sha(crypt_ftr);
-
-    if (get_crypt_ftr_info(&fname, &starting_off)) {
-        SLOGE("Unable to get crypt_ftr_info\n");
-        return -1;
-    }
-    if (fname[0] != '/') {
-        SLOGE("put_crypt_ftr_and_key::Unexpected value for crypto key location: %s\n", fname);
-        return -1;
-    }
-    if ((fd = open(fname, O_RDWR | O_CREAT | O_CLOEXEC, 0600)) < 0) {
-        SLOGE("Cannot open footer file %s for put\n", fname);
-        return -1;
-    }
-
-    /* Seek to the start of the crypt footer */
-    if (lseek64(fd, starting_off, SEEK_SET) == -1) {
-        SLOGE("Cannot seek to real block device footer\n");
-        goto errout;
-    }
-
-    if ((cnt = write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
-        SLOGE("Cannot write real block device footer\n");
-        goto errout;
-    }
-
-    fstat(fd, &statbuf);
-    /* If the keys are kept on a raw block device, do not try to truncate it. */
-    if (S_ISREG(statbuf.st_mode)) {
-        if (ftruncate(fd, 0x4000)) {
-            SLOGE("Cannot set footer file size\n");
-            goto errout;
-        }
-    }
-
-    /* Success! */
-    rc = 0;
-
-errout:
-    close(fd);
-    return rc;
-}
-
-static bool check_ftr_sha(const struct crypt_mnt_ftr* crypt_ftr) {
-    struct crypt_mnt_ftr copy;
-    memcpy(&copy, crypt_ftr, sizeof(copy));
-    set_ftr_sha(&copy);
-    return memcmp(copy.sha256, crypt_ftr->sha256, sizeof(copy.sha256)) == 0;
-}
-
-static inline int unix_read(int fd, void* buff, int len) {
-    return TEMP_FAILURE_RETRY(read(fd, buff, len));
-}
-
-static inline int unix_write(int fd, const void* buff, int len) {
-    return TEMP_FAILURE_RETRY(write(fd, buff, len));
-}
-
-static void init_empty_persist_data(struct crypt_persist_data* pdata, int len) {
-    memset(pdata, 0, len);
-    pdata->persist_magic = PERSIST_DATA_MAGIC;
-    pdata->persist_valid_entries = 0;
-}
-
-/* A routine to update the passed in crypt_ftr to the lastest version.
- * fd is open read/write on the device that holds the crypto footer and persistent
- * data, crypt_ftr is a pointer to the struct to be updated, and offset is the
- * absolute offset to the start of the crypt_mnt_ftr on the passed in fd.
- */
-static void upgrade_crypt_ftr(int fd, struct crypt_mnt_ftr* crypt_ftr, off64_t offset) {
-    int orig_major = crypt_ftr->major_version;
-    int orig_minor = crypt_ftr->minor_version;
-
-    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 0)) {
-        struct crypt_persist_data* pdata;
-        off64_t pdata_offset = offset + CRYPT_FOOTER_TO_PERSIST_OFFSET;
-
-        SLOGW("upgrading crypto footer to 1.1");
-
-        pdata = (crypt_persist_data*)malloc(CRYPT_PERSIST_DATA_SIZE);
-        if (pdata == NULL) {
-            SLOGE("Cannot allocate persisent data\n");
-            return;
-        }
-        memset(pdata, 0, CRYPT_PERSIST_DATA_SIZE);
-
-        /* Need to initialize the persistent data area */
-        if (lseek64(fd, pdata_offset, SEEK_SET) == -1) {
-            SLOGE("Cannot seek to persisent data offset\n");
-            free(pdata);
-            return;
-        }
-        /* Write all zeros to the first copy, making it invalid */
-        unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE);
-
-        /* Write a valid but empty structure to the second copy */
-        init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
-        unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE);
-
-        /* Update the footer */
-        crypt_ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE;
-        crypt_ftr->persist_data_offset[0] = pdata_offset;
-        crypt_ftr->persist_data_offset[1] = pdata_offset + CRYPT_PERSIST_DATA_SIZE;
-        crypt_ftr->minor_version = 1;
-        free(pdata);
-    }
-
-    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 1)) {
-        SLOGW("upgrading crypto footer to 1.2");
-        /* But keep the old kdf_type.
-         * It will get updated later to KDF_SCRYPT after the password has been verified.
-         */
-        crypt_ftr->kdf_type = KDF_PBKDF2;
-        get_device_scrypt_params(crypt_ftr);
-        crypt_ftr->minor_version = 2;
-    }
-
-    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 2)) {
-        SLOGW("upgrading crypto footer to 1.3");
-        crypt_ftr->crypt_type = CRYPT_TYPE_PASSWORD;
-        crypt_ftr->minor_version = 3;
-    }
-
-    if ((orig_major != crypt_ftr->major_version) || (orig_minor != crypt_ftr->minor_version)) {
-        if (lseek64(fd, offset, SEEK_SET) == -1) {
-            SLOGE("Cannot seek to crypt footer\n");
-            return;
-        }
-        unix_write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr));
-    }
-}
-
-static int get_crypt_ftr_and_key(struct crypt_mnt_ftr* crypt_ftr) {
-    int fd;
-    unsigned int cnt;
-    off64_t starting_off;
-    int rc = -1;
-    char* fname = NULL;
-    struct stat statbuf;
-
-    if (get_crypt_ftr_info(&fname, &starting_off)) {
-        SLOGE("Unable to get crypt_ftr_info\n");
-        return -1;
-    }
-    if (fname[0] != '/') {
-        SLOGE("get_crypt_ftr_and_key::Unexpected value for crypto key location: %s\n", fname);
-        return -1;
-    }
-    if ((fd = open(fname, O_RDWR | O_CLOEXEC)) < 0) {
-        SLOGE("Cannot open footer file %s for get\n", fname);
-        return -1;
-    }
-
-    /* Make sure it's 16 Kbytes in length */
-    fstat(fd, &statbuf);
-    if (S_ISREG(statbuf.st_mode) && (statbuf.st_size != 0x4000)) {
-        SLOGE("footer file %s is not the expected size!\n", fname);
-        goto errout;
-    }
-
-    /* Seek to the start of the crypt footer */
-    if (lseek64(fd, starting_off, SEEK_SET) == -1) {
-        SLOGE("Cannot seek to real block device footer\n");
-        goto errout;
-    }
-
-    if ((cnt = read(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
-        SLOGE("Cannot read real block device footer\n");
-        goto errout;
-    }
-
-    if (crypt_ftr->magic != CRYPT_MNT_MAGIC) {
-        SLOGE("Bad magic for real block device %s\n", fname);
-        goto errout;
-    }
-
-    if (crypt_ftr->major_version != CURRENT_MAJOR_VERSION) {
-        SLOGE("Cannot understand major version %d real block device footer; expected %d\n",
-              crypt_ftr->major_version, CURRENT_MAJOR_VERSION);
-        goto errout;
-    }
-
-    // We risk buffer overflows with oversized keys, so we just reject them.
-    // 0-sized keys are problematic (essentially by-passing encryption), and
-    // AES-CBC key wrapping only works for multiples of 16 bytes.
-    if ((crypt_ftr->keysize == 0) || ((crypt_ftr->keysize % 16) != 0) ||
-        (crypt_ftr->keysize > MAX_KEY_LEN)) {
-        SLOGE(
-            "Invalid keysize (%u) for block device %s; Must be non-zero, "
-            "divisible by 16, and <= %d\n",
-            crypt_ftr->keysize, fname, MAX_KEY_LEN);
-        goto errout;
-    }
-
-    if (crypt_ftr->minor_version > CURRENT_MINOR_VERSION) {
-        SLOGW("Warning: crypto footer minor version %d, expected <= %d, continuing...\n",
-              crypt_ftr->minor_version, CURRENT_MINOR_VERSION);
-    }
-
-    /* If this is a verion 1.0 crypt_ftr, make it a 1.1 crypt footer, and update the
-     * copy on disk before returning.
-     */
-    if (crypt_ftr->minor_version < CURRENT_MINOR_VERSION) {
-        upgrade_crypt_ftr(fd, crypt_ftr, starting_off);
-    }
-
-    /* Success! */
-    rc = 0;
-
-errout:
-    close(fd);
-    return rc;
-}
-
-static int validate_persistent_data_storage(struct crypt_mnt_ftr* crypt_ftr) {
-    if (crypt_ftr->persist_data_offset[0] + crypt_ftr->persist_data_size >
-        crypt_ftr->persist_data_offset[1]) {
-        SLOGE("Crypt_ftr persist data regions overlap");
-        return -1;
-    }
-
-    if (crypt_ftr->persist_data_offset[0] >= crypt_ftr->persist_data_offset[1]) {
-        SLOGE("Crypt_ftr persist data region 0 starts after region 1");
-        return -1;
-    }
-
-    if (((crypt_ftr->persist_data_offset[1] + crypt_ftr->persist_data_size) -
-         (crypt_ftr->persist_data_offset[0] - CRYPT_FOOTER_TO_PERSIST_OFFSET)) >
-        CRYPT_FOOTER_OFFSET) {
-        SLOGE("Persistent data extends past crypto footer");
-        return -1;
-    }
-
-    return 0;
-}
-
-static int load_persistent_data(void) {
-    struct crypt_mnt_ftr crypt_ftr;
-    struct crypt_persist_data* pdata = NULL;
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    char* fname;
-    int found = 0;
-    int fd;
-    int ret;
-    int i;
-
-    if (persist_data) {
-        /* Nothing to do, we've already loaded or initialized it */
-        return 0;
-    }
-
-    /* If not encrypted, just allocate an empty table and initialize it */
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (strcmp(encrypted_state, "encrypted")) {
-        pdata = (crypt_persist_data*)malloc(CRYPT_PERSIST_DATA_SIZE);
-        if (pdata) {
-            init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
-            persist_data = pdata;
-            return 0;
-        }
-        return -1;
-    }
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        return -1;
-    }
-
-    if ((crypt_ftr.major_version < 1) ||
-        (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) {
-        SLOGE("Crypt_ftr version doesn't support persistent data");
-        return -1;
-    }
-
-    if (get_crypt_ftr_info(&fname, NULL)) {
-        return -1;
-    }
-
-    ret = validate_persistent_data_storage(&crypt_ftr);
-    if (ret) {
-        return -1;
-    }
-
-    fd = open(fname, O_RDONLY | O_CLOEXEC);
-    if (fd < 0) {
-        SLOGE("Cannot open %s metadata file", fname);
-        return -1;
-    }
-
-    pdata = (crypt_persist_data*)malloc(crypt_ftr.persist_data_size);
-    if (pdata == NULL) {
-        SLOGE("Cannot allocate memory for persistent data");
-        goto err;
-    }
-
-    for (i = 0; i < 2; i++) {
-        if (lseek64(fd, crypt_ftr.persist_data_offset[i], SEEK_SET) < 0) {
-            SLOGE("Cannot seek to read persistent data on %s", fname);
-            goto err2;
-        }
-        if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0) {
-            SLOGE("Error reading persistent data on iteration %d", i);
-            goto err2;
-        }
-        if (pdata->persist_magic == PERSIST_DATA_MAGIC) {
-            found = 1;
-            break;
-        }
-    }
-
-    if (!found) {
-        SLOGI("Could not find valid persistent data, creating");
-        init_empty_persist_data(pdata, crypt_ftr.persist_data_size);
-    }
-
-    /* Success */
-    persist_data = pdata;
-    close(fd);
-    return 0;
-
-err2:
-    free(pdata);
-
-err:
-    close(fd);
-    return -1;
-}
-
-static int save_persistent_data(void) {
-    struct crypt_mnt_ftr crypt_ftr;
-    struct crypt_persist_data* pdata;
-    char* fname;
-    off64_t write_offset;
-    off64_t erase_offset;
-    int fd;
-    int ret;
-
-    if (persist_data == NULL) {
-        SLOGE("No persistent data to save");
-        return -1;
-    }
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        return -1;
-    }
-
-    if ((crypt_ftr.major_version < 1) ||
-        (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) {
-        SLOGE("Crypt_ftr version doesn't support persistent data");
-        return -1;
-    }
-
-    ret = validate_persistent_data_storage(&crypt_ftr);
-    if (ret) {
-        return -1;
-    }
-
-    if (get_crypt_ftr_info(&fname, NULL)) {
-        return -1;
-    }
-
-    fd = open(fname, O_RDWR | O_CLOEXEC);
-    if (fd < 0) {
-        SLOGE("Cannot open %s metadata file", fname);
-        return -1;
-    }
-
-    pdata = (crypt_persist_data*)malloc(crypt_ftr.persist_data_size);
-    if (pdata == NULL) {
-        SLOGE("Cannot allocate persistant data");
-        goto err;
-    }
-
-    if (lseek64(fd, crypt_ftr.persist_data_offset[0], SEEK_SET) < 0) {
-        SLOGE("Cannot seek to read persistent data on %s", fname);
-        goto err2;
-    }
-
-    if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0) {
-        SLOGE("Error reading persistent data before save");
-        goto err2;
-    }
-
-    if (pdata->persist_magic == PERSIST_DATA_MAGIC) {
-        /* The first copy is the curent valid copy, so write to
-         * the second copy and erase this one */
-        write_offset = crypt_ftr.persist_data_offset[1];
-        erase_offset = crypt_ftr.persist_data_offset[0];
-    } else {
-        /* The second copy must be the valid copy, so write to
-         * the first copy, and erase the second */
-        write_offset = crypt_ftr.persist_data_offset[0];
-        erase_offset = crypt_ftr.persist_data_offset[1];
-    }
-
-    /* Write the new copy first, if successful, then erase the old copy */
-    if (lseek64(fd, write_offset, SEEK_SET) < 0) {
-        SLOGE("Cannot seek to write persistent data");
-        goto err2;
-    }
-    if (unix_write(fd, persist_data, crypt_ftr.persist_data_size) ==
-        (int)crypt_ftr.persist_data_size) {
-        if (lseek64(fd, erase_offset, SEEK_SET) < 0) {
-            SLOGE("Cannot seek to erase previous persistent data");
-            goto err2;
-        }
-        fsync(fd);
-        memset(pdata, 0, crypt_ftr.persist_data_size);
-        if (unix_write(fd, pdata, crypt_ftr.persist_data_size) != (int)crypt_ftr.persist_data_size) {
-            SLOGE("Cannot write to erase previous persistent data");
-            goto err2;
-        }
-        fsync(fd);
-    } else {
-        SLOGE("Cannot write to save persistent data");
-        goto err2;
-    }
-
-    /* Success */
-    free(pdata);
-    close(fd);
-    return 0;
-
-err2:
-    free(pdata);
-err:
-    close(fd);
-    return -1;
-}
-
-/* Convert a binary key of specified length into an ascii hex string equivalent,
- * without the leading 0x and with null termination
- */
-static void convert_key_to_hex_ascii(const unsigned char* master_key, unsigned int keysize,
-                                     char* master_key_ascii) {
-    unsigned int i, a;
-    unsigned char nibble;
-
-    for (i = 0, a = 0; i < keysize; i++, a += 2) {
-        /* For each byte, write out two ascii hex digits */
-        nibble = (master_key[i] >> 4) & 0xf;
-        master_key_ascii[a] = nibble + (nibble > 9 ? 0x37 : 0x30);
-
-        nibble = master_key[i] & 0xf;
-        master_key_ascii[a + 1] = nibble + (nibble > 9 ? 0x37 : 0x30);
-    }
-
-    /* Add the null termination */
-    master_key_ascii[a] = '\0';
-}
-
-/*
- * If the ro.crypto.fde_sector_size system property is set, append the
- * parameters to make dm-crypt use the specified crypto sector size and round
- * the crypto device size down to a crypto sector boundary.
- */
-static int add_sector_size_param(DmTargetCrypt* target, struct crypt_mnt_ftr* ftr) {
-    constexpr char DM_CRYPT_SECTOR_SIZE[] = "ro.crypto.fde_sector_size";
-    char value[PROPERTY_VALUE_MAX];
-
-    if (property_get(DM_CRYPT_SECTOR_SIZE, value, "") > 0) {
-        unsigned int sector_size;
-
-        if (!ParseUint(value, &sector_size) || sector_size < 512 || sector_size > 4096 ||
-            (sector_size & (sector_size - 1)) != 0) {
-            SLOGE("Invalid value for %s: %s.  Must be >= 512, <= 4096, and a power of 2\n",
-                  DM_CRYPT_SECTOR_SIZE, value);
-            return -1;
-        }
-
-        target->SetSectorSize(sector_size);
-
-        // With this option, IVs will match the sector numbering, instead
-        // of being hard-coded to being based on 512-byte sectors.
-        target->SetIvLargeSectors();
-
-        // Round the crypto device size down to a crypto sector boundary.
-        ftr->fs_size &= ~((sector_size / 512) - 1);
-    }
-    return 0;
-}
-
-static int create_crypto_blk_dev(struct crypt_mnt_ftr* crypt_ftr, const unsigned char* master_key,
-                                 const char* real_blk_name, std::string* crypto_blk_name,
-                                 const char* name, uint32_t flags) {
-    auto& dm = DeviceMapper::Instance();
-    ALOGE("create_crypto_blk_dev\n");
-
-    // We need two ASCII characters to represent each byte, and need space for
-    // the '\0' terminator.
-    char master_key_ascii[MAX_KEY_LEN * 2 + 1];
-    convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
-
-    auto target = std::make_unique<DmTargetCrypt>(0, crypt_ftr->fs_size,
-                                                  (const char*)crypt_ftr->crypto_type_name,
-                                                  master_key_ascii, 0, real_blk_name, 0);
-    target->AllowDiscards();
-
-    if (flags & CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE) {
-        target->AllowEncryptOverride();
-    }
-    if (add_sector_size_param(target.get(), crypt_ftr)) {
-        SLOGE("Error processing dm-crypt sector size param\n");
-        return -1;
-    }
-
-    DmTable table;
-    table.AddTarget(std::move(target));
-
-    int load_count = 1;
-    while (load_count < TABLE_LOAD_RETRIES) {
-        if (dm.CreateDevice(name, table)) {
-            break;
-        }
-        load_count++;
-    }
-
-    if (load_count >= TABLE_LOAD_RETRIES) {
-        SLOGE("Cannot load dm-crypt mapping table.\n");
-        return -1;
-    }
-    if (load_count > 1) {
-        SLOGI("Took %d tries to load dmcrypt table.\n", load_count);
-    }
-
-    // ALOGE("GetDmDevicePathByName::%s::%s\n", name, crypto_blk_name->c_str());
-    if (!dm.GetDmDevicePathByName(name, crypto_blk_name)) {
-        SLOGE("Cannot determine dm-crypt path for %s.\n", name);
-        return -1;
-    }
-
-    /* Ensure the dm device has been created before returning. */
-    if (::WaitForFile(crypto_blk_name->c_str(), 1s) < 0) {
-        // WaitForFile generates a suitable log message
-        return -1;
-    }
-    return 0;
-}
-
-static int delete_crypto_blk_dev(const std::string& name) {
-    bool ret;
-    auto& dm = DeviceMapper::Instance();
-    // TODO(b/149396179) there appears to be a race somewhere in the system where trying
-    // to delete the device fails with EBUSY; for now, work around this by retrying.
-    int tries = 5;
-    while (tries-- > 0) {
-        ret = dm.DeleteDevice(name);
-        if (ret || errno != EBUSY) {
-            break;
-        }
-        SLOGW("DM_DEV Cannot remove dm-crypt device %s: %s, retrying...\n", name.c_str(),
-              strerror(errno));
-        std::this_thread::sleep_for(std::chrono::milliseconds(100));
-    }
-    if (!ret) {
-        SLOGE("DM_DEV Cannot remove dm-crypt device %s: %s\n", name.c_str(), strerror(errno));
-        return -1;
-    }
-    return 0;
-}
-
-static int pbkdf2(const char* passwd, const unsigned char* salt, unsigned char* ikey,
-                  void* params UNUSED) {
-    SLOGI("Using pbkdf2 for cryptfs KDF");
-
-    /* Turn the password into a key and IV that can decrypt the master key */
-    return PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, SALT_LEN, HASH_COUNT,
-                                  INTERMEDIATE_BUF_SIZE, ikey) != 1;
-}
-
-static int scrypt(const char* passwd, const unsigned char* salt, unsigned char* ikey, void* params) {
-    SLOGI("Using scrypt for cryptfs KDF");
-
-    struct crypt_mnt_ftr* ftr = (struct crypt_mnt_ftr*)params;
-
-    int N = 1 << ftr->N_factor;
-    int r = 1 << ftr->r_factor;
-    int p = 1 << ftr->p_factor;
-
-    /* Turn the password into a key and IV that can decrypt the master key */
-    crypto_scrypt((const uint8_t*)passwd, strlen(passwd), salt, SALT_LEN, N, r, p, ikey,
-                  INTERMEDIATE_BUF_SIZE);
-
-    return 0;
-}
-
-static int scrypt_keymaster(const char* passwd, const unsigned char* salt, unsigned char* ikey,
-                            void* params) {
-    SLOGI("Using scrypt with keymaster for cryptfs KDF");
-
-    int rc;
-    size_t signature_size;
-    unsigned char* signature;
-    struct crypt_mnt_ftr* ftr = (struct crypt_mnt_ftr*)params;
-
-    int N = 1 << ftr->N_factor;
-    int r = 1 << ftr->r_factor;
-    int p = 1 << ftr->p_factor;
-
-    rc = crypto_scrypt((const uint8_t*)passwd, strlen(passwd), salt, SALT_LEN, N, r, p, ikey,
-                       INTERMEDIATE_BUF_SIZE);
-
-    if (rc) {
-        SLOGE("scrypt failed");
-        return -1;
-    }
-
-    if (keymaster_sign_object(ftr, ikey, INTERMEDIATE_BUF_SIZE, &signature, &signature_size)) {
-        SLOGE("Signing failed");
-        return -1;
-    }
-
-    rc = crypto_scrypt(signature, signature_size, salt, SALT_LEN, N, r, p, ikey,
-                       INTERMEDIATE_BUF_SIZE);
-    free(signature);
-
-    if (rc) {
-        SLOGE("scrypt failed");
-        return -1;
-    }
-
-    return 0;
-}
-
-static int encrypt_master_key(const char* passwd, const unsigned char* salt,
-                              const unsigned char* decrypted_master_key,
-                              unsigned char* encrypted_master_key, struct crypt_mnt_ftr* crypt_ftr) {
-    unsigned char ikey[INTERMEDIATE_BUF_SIZE] = {0};
-    EVP_CIPHER_CTX e_ctx;
-    int encrypted_len, final_len;
-    int rc = 0;
-
-    /* Turn the password into an intermediate key and IV that can decrypt the master key */
-    get_device_scrypt_params(crypt_ftr);
-
-    switch (crypt_ftr->kdf_type) {
-        case KDF_SCRYPT_KEYMASTER:
-            if (keymaster_create_key(crypt_ftr)) {
-                SLOGE("keymaster_create_key failed");
-                return -1;
-            }
-
-            if (scrypt_keymaster(passwd, salt, ikey, crypt_ftr)) {
-                SLOGE("scrypt failed");
-                return -1;
-            }
-            break;
-
-        case KDF_SCRYPT:
-            if (scrypt(passwd, salt, ikey, crypt_ftr)) {
-                SLOGE("scrypt failed");
-                return -1;
-            }
-            break;
-
-        default:
-            SLOGE("Invalid kdf_type");
-            return -1;
-    }
-
-    /* Initialize the decryption engine */
-    EVP_CIPHER_CTX_init(&e_ctx);
-    if (!EVP_EncryptInit_ex(&e_ctx, EVP_aes_128_cbc(), NULL, ikey,
-                            ikey + INTERMEDIATE_KEY_LEN_BYTES)) {
-        SLOGE("EVP_EncryptInit failed\n");
-        return -1;
-    }
-    EVP_CIPHER_CTX_set_padding(&e_ctx, 0); /* Turn off padding as our data is block aligned */
-
-    /* Encrypt the master key */
-    if (!EVP_EncryptUpdate(&e_ctx, encrypted_master_key, &encrypted_len, decrypted_master_key,
-                           crypt_ftr->keysize)) {
-        SLOGE("EVP_EncryptUpdate failed\n");
-        return -1;
-    }
-    if (!EVP_EncryptFinal_ex(&e_ctx, encrypted_master_key + encrypted_len, &final_len)) {
-        SLOGE("EVP_EncryptFinal failed\n");
-        return -1;
-    }
-
-    if (encrypted_len + final_len != static_cast<int>(crypt_ftr->keysize)) {
-        SLOGE("EVP_Encryption length check failed with %d, %d bytes\n", encrypted_len, final_len);
-        return -1;
-    }
-
-    /* Store the scrypt of the intermediate key, so we can validate if it's a
-       password error or mount error when things go wrong.
-       Note there's no need to check for errors, since if this is incorrect, we
-       simply won't wipe userdata, which is the correct default behavior
-    */
-    int N = 1 << crypt_ftr->N_factor;
-    int r = 1 << crypt_ftr->r_factor;
-    int p = 1 << crypt_ftr->p_factor;
-
-    rc = crypto_scrypt(ikey, INTERMEDIATE_KEY_LEN_BYTES, crypt_ftr->salt, sizeof(crypt_ftr->salt),
-                       N, r, p, crypt_ftr->scrypted_intermediate_key,
-                       sizeof(crypt_ftr->scrypted_intermediate_key));
-
-    if (rc) {
-        SLOGE("encrypt_master_key: crypto_scrypt failed");
-    }
-
-    EVP_CIPHER_CTX_cleanup(&e_ctx);
-
-    return 0;
-}
-
-static int decrypt_master_key_aux(const char* passwd, unsigned char* salt,
-                                  const unsigned char* encrypted_master_key, size_t keysize,
-                                  unsigned char* decrypted_master_key, kdf_func kdf,
-                                  void* kdf_params, unsigned char** intermediate_key,
-                                  size_t* intermediate_key_size) {
-    unsigned char ikey[INTERMEDIATE_BUF_SIZE] = {0};
-    EVP_CIPHER_CTX d_ctx;
-    int decrypted_len, final_len;
-
-    /* Turn the password into an intermediate key and IV that can decrypt the
-       master key */
-    if (kdf(passwd, salt, ikey, kdf_params)) {
-        SLOGE("kdf failed");
-        return -1;
-    }
-
-    /* Initialize the decryption engine */
-    EVP_CIPHER_CTX_init(&d_ctx);
-    if (!EVP_DecryptInit_ex(&d_ctx, EVP_aes_128_cbc(), NULL, ikey,
-                            ikey + INTERMEDIATE_KEY_LEN_BYTES)) {
-        return -1;
-    }
-    EVP_CIPHER_CTX_set_padding(&d_ctx, 0); /* Turn off padding as our data is block aligned */
-    /* Decrypt the master key */
-    if (!EVP_DecryptUpdate(&d_ctx, decrypted_master_key, &decrypted_len, encrypted_master_key,
-                           keysize)) {
-        return -1;
-    }
-    if (!EVP_DecryptFinal_ex(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) {
-        return -1;
-    }
-
-    if (decrypted_len + final_len != static_cast<int>(keysize)) {
-        return -1;
-    }
-
-    /* Copy intermediate key if needed by params */
-    if (intermediate_key && intermediate_key_size) {
-        *intermediate_key = (unsigned char*)malloc(INTERMEDIATE_KEY_LEN_BYTES);
-        if (*intermediate_key) {
-            memcpy(*intermediate_key, ikey, INTERMEDIATE_KEY_LEN_BYTES);
-            *intermediate_key_size = INTERMEDIATE_KEY_LEN_BYTES;
-        }
-    }
-
-    EVP_CIPHER_CTX_cleanup(&d_ctx);
-
-    return 0;
-}
-
-static void get_kdf_func(struct crypt_mnt_ftr* ftr, kdf_func* kdf, void** kdf_params) {
-    if (ftr->kdf_type == KDF_SCRYPT_KEYMASTER) {
-        *kdf = scrypt_keymaster;
-        *kdf_params = ftr;
-    } else if (ftr->kdf_type == KDF_SCRYPT) {
-        *kdf = scrypt;
-        *kdf_params = ftr;
-    } else {
-        *kdf = pbkdf2;
-        *kdf_params = NULL;
-    }
-}
-
-static int decrypt_master_key(const char* passwd, unsigned char* decrypted_master_key,
-                              struct crypt_mnt_ftr* crypt_ftr, unsigned char** intermediate_key,
-                              size_t* intermediate_key_size) {
-    kdf_func kdf;
-    void* kdf_params;
-    int ret;
-
-    get_kdf_func(crypt_ftr, &kdf, &kdf_params);
-    ret = decrypt_master_key_aux(passwd, crypt_ftr->salt, crypt_ftr->master_key, crypt_ftr->keysize,
-                                 decrypted_master_key, kdf, kdf_params, intermediate_key,
-                                 intermediate_key_size);
-    if (ret != 0) {
-        SLOGW("failure decrypting master key");
-    }
-
-    return ret;
-}
-
-static int create_encrypted_random_key(const char* passwd, unsigned char* master_key,
-                                       unsigned char* salt, struct crypt_mnt_ftr* crypt_ftr) {
-    unsigned char key_buf[MAX_KEY_LEN];
-
-    /* Get some random bits for a key and salt */
-    if (::ReadRandomBytes(sizeof(key_buf), reinterpret_cast<char*>(key_buf)) != 0) {
-        return -1;
-    }
-    if (::ReadRandomBytes(SALT_LEN, reinterpret_cast<char*>(salt)) != 0) {
-        return -1;
-    }
-
-    /* Now encrypt it with the password */
-    return encrypt_master_key(passwd, salt, key_buf, master_key, crypt_ftr);
-}
-
-static void ensure_subdirectory_unmounted(const char *prefix) {
-    std::vector<std::string> umount_points;
-    std::unique_ptr<FILE, int (*)(FILE*)> mnts(setmntent("/proc/mounts", "r"), endmntent);
-    if (!mnts) {
-        SLOGW("could not read mount files");
-        return;
-    }
-
-    //Find sudirectory mount point
-    mntent* mentry;
-    std::string top_directory(prefix);
-    if (!android::base::EndsWith(prefix, "/")) {
-        top_directory = top_directory + "/";
-    }
-    while ((mentry = getmntent(mnts.get())) != nullptr) {
-        if (strcmp(mentry->mnt_dir, top_directory.c_str()) == 0) {
-            continue;
-        }
-
-        if (android::base::StartsWith(mentry->mnt_dir, top_directory)) {
-            SLOGW("found sub-directory mount %s - %s\n", prefix, mentry->mnt_dir);
-            umount_points.push_back(mentry->mnt_dir);
-        }
-    }
-
-    //Sort by path length to umount longest path first
-    std::sort(std::begin(umount_points), std::end(umount_points),
-        [](const std::string& s1, const std::string& s2) {return s1.length() > s2.length(); });
-
-    for (std::string& mount_point : umount_points) {
-        umount(mount_point.c_str());
-        SLOGW("umount sub-directory mount %s\n", mount_point.c_str());
-    }
-}
-
-static int wait_and_unmount(const char* mountpoint, bool kill) {
-    int i, err, rc;
-
-    // Subdirectory mount will cause a failure of umount.
-    ensure_subdirectory_unmounted(mountpoint);
-#define WAIT_UNMOUNT_COUNT 20
-
-    /*  Now umount the tmpfs filesystem */
-    for (i = 0; i < WAIT_UNMOUNT_COUNT; i++) {
-        if (umount(mountpoint) == 0) {
-            break;
-        }
-
-        if (errno == EINVAL) {
-            /* EINVAL is returned if the directory is not a mountpoint,
-             * i.e. there is no filesystem mounted there.  So just get out.
-             */
-            break;
-        }
-
-        err = errno;
-
-        /* If allowed, be increasingly aggressive before the last two retries */
-        if (kill) {
-            if (i == (WAIT_UNMOUNT_COUNT - 3)) {
-                SLOGW("sending SIGHUP to processes with open files\n");
-                android::vold::KillProcessesWithOpenFiles(mountpoint, SIGTERM);
-            } else if (i == (WAIT_UNMOUNT_COUNT - 2)) {
-                SLOGW("sending SIGKILL to processes with open files\n");
-                android::vold::KillProcessesWithOpenFiles(mountpoint, SIGKILL);
-            }
-        }
-
-        sleep(1);
-    }
-
-    if (i < WAIT_UNMOUNT_COUNT) {
-        SLOGD("unmounting %s succeeded\n", mountpoint);
-        rc = 0;
-    } else {
-        android::vold::KillProcessesWithOpenFiles(mountpoint, 0);
-        SLOGE("unmounting %s failed: %s\n", mountpoint, strerror(err));
-        rc = -1;
-    }
-
-    return rc;
-}
-
-static void prep_data_fs(void) {
-    // NOTE: post_fs_data results in init calling back around to vold, so all
-    // callers to this method must be async
-
-    /* Do the prep of the /data filesystem */
-    property_set("vold.post_fs_data_done", "0");
-    property_set("vold.decrypt", "trigger_post_fs_data");
-    SLOGD("Just triggered post_fs_data");
-
-    /* Wait a max of 50 seconds, hopefully it takes much less */
-    while (!android::base::WaitForProperty("vold.post_fs_data_done", "1", std::chrono::seconds(15))) {
-        /* We timed out to prep /data in time.  Continue wait. */
-        SLOGE("waited 15s for vold.post_fs_data_done, still waiting...");
-    }
-    SLOGD("post_fs_data done");
-}
-
-static void cryptfs_set_corrupt() {
-    // Mark the footer as bad
-    struct crypt_mnt_ftr crypt_ftr;
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Failed to get crypto footer - panic");
-        return;
-    }
-
-    crypt_ftr.flags |= CRYPT_DATA_CORRUPT;
-    if (put_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Failed to set crypto footer - panic");
-        return;
-    }
-}
-
-static void cryptfs_trigger_restart_min_framework() {
-    if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) {
-        SLOGE("Failed to mount tmpfs on data - panic");
-        return;
-    }
-
-    if (property_set("vold.decrypt", "trigger_post_fs_data")) {
-        SLOGE("Failed to trigger post fs data - panic");
-        return;
-    }
-
-    if (property_set("vold.decrypt", "trigger_restart_min_framework")) {
-        SLOGE("Failed to trigger restart min framework - panic");
-        return;
-    }
-}
-
-/* returns < 0 on failure */
-static int cryptfs_restart_internal(int restart_main) {
-    char crypto_blkdev[MAXPATHLEN];
-    int rc = -1;
-    static int restart_successful = 0;
-
-    /* Validate that it's OK to call this routine */
-    if (!master_key_saved) {
-        SLOGE("Encrypted filesystem not validated, aborting");
-        return -1;
-    }
-
-    if (restart_successful) {
-        SLOGE("System already restarted with encrypted disk, aborting");
-        return -1;
-    }
-
-    if (restart_main) {
-        /* Here is where we shut down the framework.  The init scripts
-         * start all services in one of these classes: core, early_hal, hal,
-         * main and late_start. To get to the minimal UI for PIN entry, we
-         * need to start core, early_hal, hal and main. When we want to
-         * shutdown the framework again, we need to stop most of the services in
-         * these classes, but only those services that were started after
-         * /data was mounted. This excludes critical services like vold and
-         * ueventd, which need to keep running. We could possible stop
-         * even fewer services, but because we want services to pick up APEX
-         * libraries from the real /data, restarting is better, as it makes
-         * these devices consistent with FBE devices and lets them use the
-         * most recent code.
-         *
-         * Once these services have stopped, we should be able
-         * to umount the tmpfs /data, then mount the encrypted /data.
-         * We then restart the class core, hal, main, and also the class
-         * late_start.
-         *
-         * At the moment, I've only put a few things in late_start that I know
-         * are not needed to bring up the framework, and that also cause problems
-         * with unmounting the tmpfs /data, but I hope to add add more services
-         * to the late_start class as we optimize this to decrease the delay
-         * till the user is asked for the password to the filesystem.
-         */
-
-        /* The init files are setup to stop the right set of services when
-         * vold.decrypt is set to trigger_shutdown_framework.
-         */
-        property_set("vold.decrypt", "trigger_shutdown_framework");
-        SLOGD("Just asked init to shut down class main\n");
-
-        /* Ugh, shutting down the framework is not synchronous, so until it
-         * can be fixed, this horrible hack will wait a moment for it all to
-         * shut down before proceeding.  Without it, some devices cannot
-         * restart the graphics services.
-         */
-        sleep(2);
-    }
-
-    /* Now that the framework is shutdown, we should be able to umount()
-     * the tmpfs filesystem, and mount the real one.
-     */
-
-    property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "");
-    if (strlen(crypto_blkdev) == 0) {
-        SLOGE("fs_crypto_blkdev not set\n");
-        return -1;
-    }
-
-    if (!(rc = wait_and_unmount(DATA_MNT_POINT, true))) {
-        /* If ro.crypto.readonly is set to 1, mount the decrypted
-         * filesystem readonly.  This is used when /data is mounted by
-         * recovery mode.
-         */
-        char ro_prop[PROPERTY_VALUE_MAX];
-        property_get("ro.crypto.readonly", ro_prop, "");
-        if (strlen(ro_prop) > 0 && std::stoi(ro_prop)) {
-            auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
-            if (entry != nullptr) {
-                entry->flags |= MS_RDONLY;
-            }
-        }
-
-        /* If that succeeded, then mount the decrypted filesystem */
-        int retries = RETRY_MOUNT_ATTEMPTS;
-        int mount_rc;
-
-        /*
-         * fs_mgr_do_mount runs fsck. Use setexeccon to run trusted
-         * partitions in the fsck domain.
-         */
-        if (setexeccon(::sFsckContext)) {
-            SLOGE("Failed to setexeccon");
-            return -1;
-        }
-        bool needs_cp = ::cp_needsCheckpoint();
-        while ((mount_rc = fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT, crypto_blkdev, 0,
-                                           needs_cp, false)) != 0) {
-            if (mount_rc == FS_MGR_DOMNT_BUSY) {
-                /* TODO: invoke something similar to
-                   Process::killProcessWithOpenFiles(DATA_MNT_POINT,
-                                   retries > RETRY_MOUNT_ATTEMPT/2 ? 1 : 2 ) */
-                SLOGI("Failed to mount %s because it is busy - waiting", crypto_blkdev);
-                if (--retries) {
-                    sleep(RETRY_MOUNT_DELAY_SECONDS);
-                } else {
-                    /* Let's hope that a reboot clears away whatever is keeping
-                       the mount busy */
-                    cryptfs_reboot(RebootType::reboot);
-                }
-            } else {
-                SLOGE("Failed to mount decrypted data");
-                cryptfs_set_corrupt();
-                cryptfs_trigger_restart_min_framework();
-                SLOGI("Started framework to offer wipe");
-                if (setexeccon(NULL)) {
-                    SLOGE("Failed to setexeccon");
-                }
-                return -1;
-            }
-        }
-        if (setexeccon(NULL)) {
-            SLOGE("Failed to setexeccon");
-            return -1;
-        }
-
-        /* Create necessary paths on /data */
-        prep_data_fs();
-        property_set("vold.decrypt", "trigger_load_persist_props");
-
-        /* startup service classes main and late_start */
-        property_set("vold.decrypt", "trigger_restart_framework");
-        SLOGD("Just triggered restart_framework\n");
-
-        /* Give it a few moments to get started */
-        sleep(1);
-    }
-
-    if (rc == 0) {
-        restart_successful = 1;
-    }
-
-    return rc;
-}
-
-int cryptfs_restart(void) {
-    SLOGI("cryptfs_restart");
-    if (fscrypt_is_native()) {
-        SLOGE("cryptfs_restart not valid for file encryption:");
-        return -1;
-    }
-
-    /* Call internal implementation forcing a restart of main service group */
-    return cryptfs_restart_internal(1);
-}
-
-static int do_crypto_complete(const char* mount_point) {
-    struct crypt_mnt_ftr crypt_ftr;
-    char encrypted_state[PROPERTY_VALUE_MAX];
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (strcmp(encrypted_state, "encrypted")) {
-        SLOGE("not running with encryption, aborting");
-        return CRYPTO_COMPLETE_NOT_ENCRYPTED;
-    }
-
-    // crypto_complete is full disk encrypted status
-    if (fscrypt_is_native()) {
-        return CRYPTO_COMPLETE_NOT_ENCRYPTED;
-    }
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        std::string key_loc;
-        get_crypt_info(&key_loc, nullptr);
-
-        /*
-         * Only report this error if key_loc is a file and it exists.
-         * If the device was never encrypted, and /data is not mountable for
-         * some reason, returning 1 should prevent the UI from presenting the
-         * a "enter password" screen, or worse, a "press button to wipe the
-         * device" screen.
-         */
-        if (!key_loc.empty() && key_loc[0] == '/' && (access("key_loc", F_OK) == -1)) {
-            SLOGE("master key file does not exist, aborting");
-            return CRYPTO_COMPLETE_NOT_ENCRYPTED;
-        } else {
-            SLOGE("Error getting crypt footer and key\n");
-            return CRYPTO_COMPLETE_BAD_METADATA;
-        }
-    }
-
-    // Test for possible error flags
-    if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) {
-        SLOGE("Encryption process is partway completed\n");
-        return CRYPTO_COMPLETE_PARTIAL;
-    }
-
-    if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) {
-        SLOGE("Encryption process was interrupted but cannot continue\n");
-        return CRYPTO_COMPLETE_INCONSISTENT;
-    }
-
-    if (crypt_ftr.flags & CRYPT_DATA_CORRUPT) {
-        SLOGE("Encryption is successful but data is corrupt\n");
-        return CRYPTO_COMPLETE_CORRUPT;
-    }
-
-    /* We passed the test! We shall diminish, and return to the west */
-    return CRYPTO_COMPLETE_ENCRYPTED;
-}
-
-static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, const char* passwd,
-                                   const char* mount_point, const char* label) {
-    unsigned char decrypted_master_key[MAX_KEY_LEN];
-    std::string crypto_blkdev;
-    std::string real_blkdev;
-    char tmp_mount_point[64];
-    unsigned int orig_failed_decrypt_count;
-    int rc;
-    int use_keymaster = 0;
-    int upgrade = 0;
-    unsigned char* intermediate_key = 0;
-    size_t intermediate_key_size = 0;
-    int N = 1 << crypt_ftr->N_factor;
-    int r = 1 << crypt_ftr->r_factor;
-    int p = 1 << crypt_ftr->p_factor;
-
-    SLOGD("crypt_ftr->fs_size = %lld\n", crypt_ftr->fs_size);
-    orig_failed_decrypt_count = crypt_ftr->failed_decrypt_count;
-
-    if (!(crypt_ftr->flags & CRYPT_MNT_KEY_UNENCRYPTED)) {
-        if (decrypt_master_key(passwd, decrypted_master_key, crypt_ftr, &intermediate_key,
-                               &intermediate_key_size)) {
-            SLOGE("Failed to decrypt master key\n");
-            rc = -1;
-            goto errout;
-        }
-    }
-
-    get_crypt_info(nullptr, &real_blkdev);
-
-    // Create crypto block device - all (non fatal) code paths
-    // need it
-    if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, real_blkdev.c_str(), &crypto_blkdev,
-                              label, 0)) {
-        SLOGE("Error creating decrypted block device\n");
-        rc = -1;
-        goto errout;
-    }
-
-    /* Work out if the problem is the password or the data */
-    unsigned char scrypted_intermediate_key[sizeof(crypt_ftr->scrypted_intermediate_key)];
-
-    rc = crypto_scrypt(intermediate_key, intermediate_key_size, crypt_ftr->salt,
-                       sizeof(crypt_ftr->salt), N, r, p, scrypted_intermediate_key,
-                       sizeof(scrypted_intermediate_key));
-
-    // Does the key match the crypto footer?
-    if (rc == 0 && memcmp(scrypted_intermediate_key, crypt_ftr->scrypted_intermediate_key,
-                          sizeof(scrypted_intermediate_key)) == 0) {
-        SLOGI("Password matches");
-        rc = 0;
-    } else {
-        /* Try mounting the file system anyway, just in case the problem's with
-         * the footer, not the key. */
-        snprintf(tmp_mount_point, sizeof(tmp_mount_point), "%s/tmp_mnt", mount_point);
-        mkdir(tmp_mount_point, 0755);
-        if (fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT,
-                            const_cast<char*>(crypto_blkdev.c_str()), tmp_mount_point)) {
-            SLOGE("Error temp mounting decrypted block device\n");
-            delete_crypto_blk_dev(label);
-
-            rc = ++crypt_ftr->failed_decrypt_count;
-            put_crypt_ftr_and_key(crypt_ftr);
-        } else {
-            /* Success! */
-            SLOGI("Password did not match but decrypted drive mounted - continue");
-            umount(tmp_mount_point);
-            rc = 0;
-        }
-    }
-
-    if (rc == 0) {
-        crypt_ftr->failed_decrypt_count = 0;
-        if (orig_failed_decrypt_count != 0) {
-            put_crypt_ftr_and_key(crypt_ftr);
-        }
-
-        /* Save the name of the crypto block device
-         * so we can mount it when restarting the framework. */
-        property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev.c_str());
-
-        /* Also save a the master key so we can reencrypted the key
-         * the key when we want to change the password on it. */
-        memcpy(saved_master_key, decrypted_master_key, crypt_ftr->keysize);
-        saved_mount_point = strdup(mount_point);
-        master_key_saved = 1;
-        SLOGD("%s(): Master key saved\n", __FUNCTION__);
-        rc = 0;
-
-        // Upgrade if we're not using the latest KDF.
-        use_keymaster = keymaster_check_compatibility();
-        if (crypt_ftr->kdf_type == KDF_SCRYPT_KEYMASTER) {
-            // Don't allow downgrade
-        } else if (use_keymaster == 1 && crypt_ftr->kdf_type != KDF_SCRYPT_KEYMASTER) {
-            crypt_ftr->kdf_type = KDF_SCRYPT_KEYMASTER;
-            upgrade = 1;
-        } else if (use_keymaster == 0 && crypt_ftr->kdf_type != KDF_SCRYPT) {
-            crypt_ftr->kdf_type = KDF_SCRYPT;
-            upgrade = 1;
-        }
-
-        if (upgrade) {
-            rc = encrypt_master_key(passwd, crypt_ftr->salt, saved_master_key,
-                                    crypt_ftr->master_key, crypt_ftr);
-            if (!rc) {
-                rc = put_crypt_ftr_and_key(crypt_ftr);
-            }
-            SLOGD("Key Derivation Function upgrade: rc=%d\n", rc);
-
-            // Do not fail even if upgrade failed - machine is bootable
-            // Note that if this code is ever hit, there is a *serious* problem
-            // since KDFs should never fail. You *must* fix the kdf before
-            // proceeding!
-            if (rc) {
-                SLOGW(
-                    "Upgrade failed with error %d,"
-                    " but continuing with previous state",
-                    rc);
-                rc = 0;
-            }
-        }
-    }
-
-errout:
-    if (intermediate_key) {
-        memset(intermediate_key, 0, intermediate_key_size);
-        free(intermediate_key);
-    }
-    return rc;
-}
-
-/*
- * Called by vold when it's asked to mount an encrypted external
- * storage volume. The incoming partition has no crypto header/footer,
- * as any metadata is been stored in a separate, small partition.  We
- * assume it must be using our same crypt type and keysize.
- */
-int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev, const KeyBuffer& key,
-                             std::string* out_crypto_blkdev) {
-    auto crypto_type = get_crypto_type();
-    if (key.size() != crypto_type.get_keysize()) {
-        SLOGE("Raw keysize %zu does not match crypt keysize %zu", key.size(),
-              crypto_type.get_keysize());
-        return -1;
-    }
-    uint64_t nr_sec = 0;
-    if (::GetBlockDev512Sectors(real_blkdev, &nr_sec) != android::OK) {
-        SLOGE("Failed to get size of %s: %s", real_blkdev, strerror(errno));
-        return -1;
-    }
-
-    struct crypt_mnt_ftr ext_crypt_ftr;
-    memset(&ext_crypt_ftr, 0, sizeof(ext_crypt_ftr));
-    ext_crypt_ftr.fs_size = nr_sec;
-    ext_crypt_ftr.keysize = crypto_type.get_keysize();
-    strlcpy((char*)ext_crypt_ftr.crypto_type_name, crypto_type.get_kernel_name(),
-            MAX_CRYPTO_TYPE_NAME_LEN);
-    uint32_t flags = 0;
-    if (fscrypt_is_native() &&
-        android::base::GetBoolProperty("ro.crypto.allow_encrypt_override", false))
-        flags |= CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE;
-
-    return create_crypto_blk_dev(&ext_crypt_ftr, reinterpret_cast<const unsigned char*>(key.data()),
-                                 real_blkdev, out_crypto_blkdev, label, flags);
-}
-
-int cryptfs_crypto_complete(void) {
-    return do_crypto_complete("/data");
-}
-
-int check_unmounted_and_get_ftr(struct crypt_mnt_ftr* crypt_ftr) {
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (master_key_saved || strcmp(encrypted_state, "encrypted")) {
-        SLOGE(
-            "encrypted fs already validated or not running with encryption,"
-            " aborting");
-        return -1;
-    }
-
-    if (get_crypt_ftr_and_key(crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key");
-        return -1;
-    }
-
-    return 0;
-}
-
-int cryptfs_check_passwd(const char* passwd) {
-    SLOGI("cryptfs_check_passwd");
-    if (fscrypt_is_native()) {
-        SLOGE("cryptfs_check_passwd not valid for file encryption");
-        return -1;
-    }
-
-    struct crypt_mnt_ftr crypt_ftr;
-    int rc;
-
-    rc = check_unmounted_and_get_ftr(&crypt_ftr);
-    if (rc) {
-        SLOGE("Could not get footer");
-        return rc;
-    }
-
-    rc = test_mount_encrypted_fs(&crypt_ftr, passwd, DATA_MNT_POINT, CRYPTO_BLOCK_DEVICE);
-    if (rc) {
-        SLOGE("Password did not match");
-        return rc;
-    }
-
-    if (crypt_ftr.flags & CRYPT_FORCE_COMPLETE) {
-        // Here we have a default actual password but a real password
-        // we must test against the scrypted value
-        // First, we must delete the crypto block device that
-        // test_mount_encrypted_fs leaves behind as a side effect
-        delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE);
-        rc = test_mount_encrypted_fs(&crypt_ftr, DEFAULT_PASSWORD, DATA_MNT_POINT,
-                                     CRYPTO_BLOCK_DEVICE);
-        if (rc) {
-            SLOGE("Default password did not match on reboot encryption");
-            return rc;
-        }
-
-        crypt_ftr.flags &= ~CRYPT_FORCE_COMPLETE;
-        put_crypt_ftr_and_key(&crypt_ftr);
-        rc = cryptfs_changepw(crypt_ftr.crypt_type, passwd);
-        if (rc) {
-            SLOGE("Could not change password on reboot encryption");
-            return rc;
-        }
-    }
-
-    if (crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) {
-        cryptfs_clear_password();
-        password = strdup(passwd);
-        struct timespec now;
-        clock_gettime(CLOCK_BOOTTIME, &now);
-        password_expiry_time = now.tv_sec + password_max_age_seconds;
-    }
-
-    return rc;
-}
-
-int cryptfs_verify_passwd(const char* passwd) {
-    struct crypt_mnt_ftr crypt_ftr;
-    unsigned char decrypted_master_key[MAX_KEY_LEN];
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    int rc;
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (strcmp(encrypted_state, "encrypted")) {
-        SLOGE("device not encrypted, aborting");
-        return -2;
-    }
-
-    if (!master_key_saved) {
-        SLOGE("encrypted fs not yet mounted, aborting");
-        return -1;
-    }
-
-    if (!saved_mount_point) {
-        SLOGE("encrypted fs failed to save mount point, aborting");
-        return -1;
-    }
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key\n");
-        return -1;
-    }
-
-    if (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) {
-        /* If the device has no password, then just say the password is valid */
-        rc = 0;
-    } else {
-        decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
-        if (!memcmp(decrypted_master_key, saved_master_key, crypt_ftr.keysize)) {
-            /* They match, the password is correct */
-            rc = 0;
-        } else {
-            /* If incorrect, sleep for a bit to prevent dictionary attacks */
-            sleep(1);
-            rc = 1;
-        }
-    }
-
-    return rc;
-}
-
-/* Initialize a crypt_mnt_ftr structure.  The keysize is
- * defaulted to get_crypto_type().get_keysize() bytes, and the filesystem size to 0.
- * Presumably, at a minimum, the caller will update the
- * filesystem size and crypto_type_name after calling this function.
- */
-static int cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr* ftr) {
-    off64_t off;
-
-    memset(ftr, 0, sizeof(struct crypt_mnt_ftr));
-    ftr->magic = CRYPT_MNT_MAGIC;
-    ftr->major_version = CURRENT_MAJOR_VERSION;
-    ftr->minor_version = CURRENT_MINOR_VERSION;
-    ftr->ftr_size = sizeof(struct crypt_mnt_ftr);
-    ftr->keysize = get_crypto_type().get_keysize();
-
-    switch (keymaster_check_compatibility()) {
-        case 1:
-            ftr->kdf_type = KDF_SCRYPT_KEYMASTER;
-            break;
-
-        case 0:
-            ftr->kdf_type = KDF_SCRYPT;
-            break;
-
-        default:
-            SLOGE("keymaster_check_compatibility failed");
-            return -1;
-    }
-
-    get_device_scrypt_params(ftr);
-
-    ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE;
-    if (get_crypt_ftr_info(NULL, &off) == 0) {
-        ftr->persist_data_offset[0] = off + CRYPT_FOOTER_TO_PERSIST_OFFSET;
-        ftr->persist_data_offset[1] = off + CRYPT_FOOTER_TO_PERSIST_OFFSET + ftr->persist_data_size;
-    }
-
-    return 0;
-}
-
-#define FRAMEWORK_BOOT_WAIT 60
-
-static int cryptfs_SHA256_fileblock(const char* filename, __le8* buf) {
-    int fd = open(filename, O_RDONLY | O_CLOEXEC);
-    if (fd == -1) {
-        SLOGE("Error opening file %s", filename);
-        return -1;
-    }
-
-    char block[CRYPT_INPLACE_BUFSIZE];
-    memset(block, 0, sizeof(block));
-    if (unix_read(fd, block, sizeof(block)) < 0) {
-        SLOGE("Error reading file %s", filename);
-        close(fd);
-        return -1;
-    }
-
-    close(fd);
-
-    SHA256_CTX c;
-    SHA256_Init(&c);
-    SHA256_Update(&c, block, sizeof(block));
-    SHA256_Final(buf, &c);
-
-    return 0;
-}
-
-static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr* crypt_ftr, const char* crypto_blkdev,
-                                      const char* real_blkdev, int previously_encrypted_upto) {
-    off64_t cur_encryption_done = 0, tot_encryption_size = 0;
-    int rc = -1;
-
-    /* The size of the userdata partition, and add in the vold volumes below */
-    tot_encryption_size = crypt_ftr->fs_size;
-
-    rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, crypt_ftr->fs_size, &cur_encryption_done,
-                                tot_encryption_size, previously_encrypted_upto, true);
-
-    if (rc == ENABLE_INPLACE_ERR_DEV) {
-        /* Hack for b/17898962 */
-        SLOGE("cryptfs_enable: crypto block dev failure. Must reboot...\n");
-        cryptfs_reboot(RebootType::reboot);
-    }
-
-    if (!rc) {
-        crypt_ftr->encrypted_upto = cur_encryption_done;
-    }
-
-    if (!rc && crypt_ftr->encrypted_upto == crypt_ftr->fs_size) {
-        /* The inplace routine never actually sets the progress to 100% due
-         * to the round down nature of integer division, so set it here */
-        property_set("vold.encrypt_progress", "100");
-    }
-
-    return rc;
-}
-
-// static int vold_unmountAll(void) {
-//     VolumeManager* vm = VolumeManager::Instance();
-//     return vm->unmountAll();
-// }
-
-int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
-    std::string crypto_blkdev;
-    std::string real_blkdev;
-    unsigned char decrypted_master_key[MAX_KEY_LEN];
-    int rc = -1, i;
-    struct crypt_mnt_ftr crypt_ftr;
-    struct crypt_persist_data* pdata;
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    char lockid[32] = {0};
-    std::string key_loc;
-    int num_vols;
-    off64_t previously_encrypted_upto = 0;
-    bool rebootEncryption = false;
-    bool onlyCreateHeader = false;
-    // std::unique_ptr<android::wakelock::WakeLock> wakeLock = nullptr;
-
-    if (get_crypt_ftr_and_key(&crypt_ftr) == 0) {
-        if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) {
-            /* An encryption was underway and was interrupted */
-            previously_encrypted_upto = crypt_ftr.encrypted_upto;
-            crypt_ftr.encrypted_upto = 0;
-            crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
-
-            /* At this point, we are in an inconsistent state. Until we successfully
-               complete encryption, a reboot will leave us broken. So mark the
-               encryption failed in case that happens.
-               On successfully completing encryption, remove this flag */
-            crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
-
-            put_crypt_ftr_and_key(&crypt_ftr);
-        } else if (crypt_ftr.flags & CRYPT_FORCE_ENCRYPTION) {
-            if (!check_ftr_sha(&crypt_ftr)) {
-                memset(&crypt_ftr, 0, sizeof(crypt_ftr));
-                put_crypt_ftr_and_key(&crypt_ftr);
-                goto error_unencrypted;
-            }
-
-            /* Doing a reboot-encryption*/
-            crypt_ftr.flags &= ~CRYPT_FORCE_ENCRYPTION;
-            crypt_ftr.flags |= CRYPT_FORCE_COMPLETE;
-            rebootEncryption = true;
-        }
-    } else {
-        // We don't want to accidentally reference invalid data.
-        memset(&crypt_ftr, 0, sizeof(crypt_ftr));
-    }
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (!strcmp(encrypted_state, "encrypted") && !previously_encrypted_upto) {
-        SLOGE("Device is already running encrypted, aborting");
-        goto error_unencrypted;
-    }
-
-    get_crypt_info(&key_loc, &real_blkdev);
-
-    /* Get the size of the real block device */
-    uint64_t nr_sec;
-    if (::GetBlockDev512Sectors(real_blkdev, &nr_sec) != android::OK) {
-        SLOGE("Cannot get size of block device %s\n", real_blkdev.c_str());
-        goto error_unencrypted;
-    }
-
-    /* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */
-    if (key_loc == KEY_IN_FOOTER) {
-        uint64_t fs_size_sec, max_fs_size_sec;
-        fs_size_sec = get_fs_size(real_blkdev.c_str());
-        if (fs_size_sec == 0) fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev.data());
-
-        max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
-
-        if (fs_size_sec > max_fs_size_sec) {
-            SLOGE("Orig filesystem overlaps crypto footer region.  Cannot encrypt in place.");
-            goto error_unencrypted;
-        }
-    }
-
-    /* Get a wakelock as this may take a while, and we don't want the
-     * device to sleep on us.  We'll grab a partial wakelock, and if the UI
-     * wants to keep the screen on, it can grab a full wakelock.
-     */
-    snprintf(lockid, sizeof(lockid), "enablecrypto%d", (int)getpid());
-    // wakeLock = std::make_unique<android::wakelock::WakeLock>(lockid);
-
-    /* The init files are setup to stop the class main and late start when
-     * vold sets trigger_shutdown_framework.
-     */
-    property_set("vold.decrypt", "trigger_shutdown_framework");
-    SLOGD("Just asked init to shut down class main\n");
-
-    /* Ask vold to unmount all devices that it manages */
-    // if (vold_unmountAll()) {
-    //     SLOGE("Failed to unmount all vold managed devices");
-    // }
-
-    /* no_ui means we are being called from init, not settings.
-       Now we always reboot from settings, so !no_ui means reboot
-     */
-    if (!no_ui) {
-        /* Try fallback, which is to reboot and try there */
-        onlyCreateHeader = true;
-        FILE* breadcrumb = fopen(BREADCRUMB_FILE, "we");
-        if (breadcrumb == 0) {
-            SLOGE("Failed to create breadcrumb file");
-            goto error_shutting_down;
-        }
-        fclose(breadcrumb);
-    }
-
-    /* Do extra work for a better UX when doing the long inplace encryption */
-    if (!onlyCreateHeader) {
-        /* Now that /data is unmounted, we need to mount a tmpfs
-         * /data, set a property saying we're doing inplace encryption,
-         * and restart the framework.
-         */
-        wait_and_unmount(DATA_MNT_POINT, true);
-        if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) {
-            goto error_shutting_down;
-        }
-        /* Tells the framework that inplace encryption is starting */
-        property_set("vold.encrypt_progress", "0");
-
-        /* restart the framework. */
-        /* Create necessary paths on /data */
-        prep_data_fs();
-
-        /* Ugh, shutting down the framework is not synchronous, so until it
-         * can be fixed, this horrible hack will wait a moment for it all to
-         * shut down before proceeding.  Without it, some devices cannot
-         * restart the graphics services.
-         */
-        sleep(2);
-    }
-
-    /* Start the actual work of making an encrypted filesystem */
-    /* Initialize a crypt_mnt_ftr for the partition */
-    if (previously_encrypted_upto == 0 && !rebootEncryption) {
-        if (cryptfs_init_crypt_mnt_ftr(&crypt_ftr)) {
-            goto error_shutting_down;
-        }
-
-        if (key_loc == KEY_IN_FOOTER) {
-            crypt_ftr.fs_size = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
-        } else {
-            crypt_ftr.fs_size = nr_sec;
-        }
-        /* At this point, we are in an inconsistent state. Until we successfully
-           complete encryption, a reboot will leave us broken. So mark the
-           encryption failed in case that happens.
-           On successfully completing encryption, remove this flag */
-        if (onlyCreateHeader) {
-            crypt_ftr.flags |= CRYPT_FORCE_ENCRYPTION;
-        } else {
-            crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
-        }
-        crypt_ftr.crypt_type = crypt_type;
-        strlcpy((char*)crypt_ftr.crypto_type_name, get_crypto_type().get_kernel_name(),
-                MAX_CRYPTO_TYPE_NAME_LEN);
-
-        /* Make an encrypted master key */
-        if (create_encrypted_random_key(onlyCreateHeader ? DEFAULT_PASSWORD : passwd,
-                                        crypt_ftr.master_key, crypt_ftr.salt, &crypt_ftr)) {
-            SLOGE("Cannot create encrypted master key\n");
-            goto error_shutting_down;
-        }
-
-        /* Replace scrypted intermediate key if we are preparing for a reboot */
-        if (onlyCreateHeader) {
-            unsigned char fake_master_key[MAX_KEY_LEN];
-            unsigned char encrypted_fake_master_key[MAX_KEY_LEN];
-            memset(fake_master_key, 0, sizeof(fake_master_key));
-            encrypt_master_key(passwd, crypt_ftr.salt, fake_master_key, encrypted_fake_master_key,
-                               &crypt_ftr);
-        }
-
-        /* Write the key to the end of the partition */
-        put_crypt_ftr_and_key(&crypt_ftr);
-
-        /* If any persistent data has been remembered, save it.
-         * If none, create a valid empty table and save that.
-         */
-        if (!persist_data) {
-            pdata = (crypt_persist_data*)malloc(CRYPT_PERSIST_DATA_SIZE);
-            if (pdata) {
-                init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
-                persist_data = pdata;
-            }
-        }
-        if (persist_data) {
-            save_persistent_data();
-        }
-    }
-
-    if (onlyCreateHeader) {
-        sleep(2);
-        cryptfs_reboot(RebootType::reboot);
-    }
-
-    if (!no_ui || rebootEncryption) {
-        /* startup service classes main and late_start */
-        property_set("vold.decrypt", "trigger_restart_min_framework");
-        SLOGD("Just triggered restart_min_framework\n");
-
-        /* OK, the framework is restarted and will soon be showing a
-         * progress bar.  Time to setup an encrypted mapping, and
-         * either write a new filesystem, or encrypt in place updating
-         * the progress bar as we work.
-         */
-    }
-
-    decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
-    ALOGE("cryptfs_enable_internal\n");
-    create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev.c_str(), &crypto_blkdev,
-                          CRYPTO_BLOCK_DEVICE, 0);
-
-    /* If we are continuing, check checksums match */
-    rc = 0;
-    if (previously_encrypted_upto) {
-        __le8 hash_first_block[SHA256_DIGEST_LENGTH];
-        rc = cryptfs_SHA256_fileblock(crypto_blkdev.c_str(), hash_first_block);
-
-        if (!rc &&
-            memcmp(hash_first_block, crypt_ftr.hash_first_block, sizeof(hash_first_block)) != 0) {
-            SLOGE("Checksums do not match - trigger wipe");
-            rc = -1;
-        }
-    }
-
-    if (!rc) {
-        rc = cryptfs_enable_all_volumes(&crypt_ftr, crypto_blkdev.c_str(), real_blkdev.data(),
-                                        previously_encrypted_upto);
-    }
-
-    /* Calculate checksum if we are not finished */
-    if (!rc && crypt_ftr.encrypted_upto != crypt_ftr.fs_size) {
-        rc = cryptfs_SHA256_fileblock(crypto_blkdev.c_str(), crypt_ftr.hash_first_block);
-        if (rc) {
-            SLOGE("Error calculating checksum for continuing encryption");
-            rc = -1;
-        }
-    }
-
-    /* Undo the dm-crypt mapping whether we succeed or not */
-    delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE);
-
-    if (!rc) {
-        /* Success */
-        crypt_ftr.flags &= ~CRYPT_INCONSISTENT_STATE;
-
-        if (crypt_ftr.encrypted_upto != crypt_ftr.fs_size) {
-            SLOGD("Encrypted up to sector %lld - will continue after reboot",
-                  crypt_ftr.encrypted_upto);
-            crypt_ftr.flags |= CRYPT_ENCRYPTION_IN_PROGRESS;
-        }
-
-        put_crypt_ftr_and_key(&crypt_ftr);
-
-        if (crypt_ftr.encrypted_upto == crypt_ftr.fs_size) {
-            char value[PROPERTY_VALUE_MAX];
-            property_get("ro.crypto.state", value, "");
-            if (!strcmp(value, "")) {
-                /* default encryption - continue first boot sequence */
-                property_set("ro.crypto.state", "encrypted");
-                property_set("ro.crypto.type", "block");
-                // wakeLock.reset(nullptr);
-                if (rebootEncryption && crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) {
-                    // Bring up cryptkeeper that will check the password and set it
-                    property_set("vold.decrypt", "trigger_shutdown_framework");
-                    sleep(2);
-                    property_set("vold.encrypt_progress", "");
-                    cryptfs_trigger_restart_min_framework();
-                } else {
-                    cryptfs_check_passwd(DEFAULT_PASSWORD);
-                    cryptfs_restart_internal(1);
-                }
-                return 0;
-            } else {
-                sleep(2); /* Give the UI a chance to show 100% progress */
-                cryptfs_reboot(RebootType::reboot);
-            }
-        } else {
-            sleep(2); /* Partially encrypted, ensure writes flushed to ssd */
-            cryptfs_reboot(RebootType::shutdown);
-        }
-    } else {
-        char value[PROPERTY_VALUE_MAX];
-
-        property_get("ro.vold.wipe_on_crypt_fail", value, "0");
-        if (!strcmp(value, "1")) {
-            /* wipe data if encryption failed */
-            SLOGE("encryption failed - rebooting into recovery to wipe data\n");
-            std::string err;
-            const std::vector<std::string> options = {
-                "--wipe_data\n--reason=cryptfs_enable_internal\n"};
-            if (!write_bootloader_message(options, &err)) {
-                SLOGE("could not write bootloader message: %s", err.c_str());
-            }
-            cryptfs_reboot(RebootType::recovery);
-        } else {
-            /* set property to trigger dialog */
-            property_set("vold.encrypt_progress", "error_partially_encrypted");
-        }
-        return -1;
-    }
-
-    /* hrm, the encrypt step claims success, but the reboot failed.
-     * This should not happen.
-     * Set the property and return.  Hope the framework can deal with it.
-     */
-    property_set("vold.encrypt_progress", "error_reboot_failed");
-    return rc;
-
-error_unencrypted:
-    property_set("vold.encrypt_progress", "error_not_encrypted");
-    return -1;
-
-error_shutting_down:
-    /* we failed, and have not encrypted anthing, so the users's data is still intact,
-     * but the framework is stopped and not restarted to show the error, so it's up to
-     * vold to restart the system.
-     */
-    SLOGE(
-        "Error enabling encryption after framework is shutdown, no data changed, restarting "
-        "system");
-    cryptfs_reboot(RebootType::reboot);
-
-    /* shouldn't get here */
-    property_set("vold.encrypt_progress", "error_shutting_down");
-    return -1;
-}
-
-int cryptfs_enable(int type, const char* passwd, int no_ui) {
-    return cryptfs_enable_internal(type, passwd, no_ui);
-}
-
-int cryptfs_enable_default(int no_ui) {
-    return cryptfs_enable_internal(CRYPT_TYPE_DEFAULT, DEFAULT_PASSWORD, no_ui);
-}
-
-int cryptfs_changepw(int crypt_type, const char* newpw) {
-    if (fscrypt_is_native()) {
-        SLOGE("cryptfs_changepw not valid for file encryption");
-        return -1;
-    }
-
-    struct crypt_mnt_ftr crypt_ftr;
-    int rc;
-
-    /* This is only allowed after we've successfully decrypted the master key */
-    if (!master_key_saved) {
-        SLOGE("Key not saved, aborting");
-        return -1;
-    }
-
-    if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
-        SLOGE("Invalid crypt_type %d", crypt_type);
-        return -1;
-    }
-
-    /* get key */
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key");
-        return -1;
-    }
-
-    crypt_ftr.crypt_type = crypt_type;
-
-    rc = encrypt_master_key(crypt_type == CRYPT_TYPE_DEFAULT ? DEFAULT_PASSWORD : newpw,
-                            crypt_ftr.salt, saved_master_key, crypt_ftr.master_key, &crypt_ftr);
-    if (rc) {
-        SLOGE("Encrypt master key failed: %d", rc);
-        return -1;
-    }
-    /* save the key */
-    put_crypt_ftr_and_key(&crypt_ftr);
-
-    return 0;
-}
-
-static unsigned int persist_get_max_entries(int encrypted) {
-    struct crypt_mnt_ftr crypt_ftr;
-    unsigned int dsize;
-
-    /* If encrypted, use the values from the crypt_ftr, otherwise
-     * use the values for the current spec.
-     */
-    if (encrypted) {
-        if (get_crypt_ftr_and_key(&crypt_ftr)) {
-            /* Something is wrong, assume no space for entries */
-            return 0;
-        }
-        dsize = crypt_ftr.persist_data_size;
-    } else {
-        dsize = CRYPT_PERSIST_DATA_SIZE;
-    }
-
-    if (dsize > sizeof(struct crypt_persist_data)) {
-        return (dsize - sizeof(struct crypt_persist_data)) / sizeof(struct crypt_persist_entry);
-    } else {
-        return 0;
-    }
-}
-
-static int persist_get_key(const char* fieldname, char* value) {
-    unsigned int i;
-
-    if (persist_data == NULL) {
-        return -1;
-    }
-    for (i = 0; i < persist_data->persist_valid_entries; i++) {
-        if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) {
-            /* We found it! */
-            strlcpy(value, persist_data->persist_entry[i].val, PROPERTY_VALUE_MAX);
-            return 0;
-        }
-    }
-
-    return -1;
-}
-
-static int persist_set_key(const char* fieldname, const char* value, int encrypted) {
-    unsigned int i;
-    unsigned int num;
-    unsigned int max_persistent_entries;
-
-    if (persist_data == NULL) {
-        return -1;
-    }
-
-    max_persistent_entries = persist_get_max_entries(encrypted);
-
-    num = persist_data->persist_valid_entries;
-
-    for (i = 0; i < num; i++) {
-        if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) {
-            /* We found an existing entry, update it! */
-            memset(persist_data->persist_entry[i].val, 0, PROPERTY_VALUE_MAX);
-            strlcpy(persist_data->persist_entry[i].val, value, PROPERTY_VALUE_MAX);
-            return 0;
-        }
-    }
-
-    /* We didn't find it, add it to the end, if there is room */
-    if (persist_data->persist_valid_entries < max_persistent_entries) {
-        memset(&persist_data->persist_entry[num], 0, sizeof(struct crypt_persist_entry));
-        strlcpy(persist_data->persist_entry[num].key, fieldname, PROPERTY_KEY_MAX);
-        strlcpy(persist_data->persist_entry[num].val, value, PROPERTY_VALUE_MAX);
-        persist_data->persist_valid_entries++;
-        return 0;
-    }
-
-    return -1;
-}
-
-/**
- * Test if key is part of the multi-entry (field, index) sequence. Return non-zero if key is in the
- * sequence and its index is greater than or equal to index. Return 0 otherwise.
- */
-int match_multi_entry(const char* key, const char* field, unsigned index) {
-    std::string key_ = key;
-    std::string field_ = field;
-
-    std::string parsed_field;
-    unsigned parsed_index;
-
-    std::string::size_type split = key_.find_last_of('_');
-    if (split == std::string::npos) {
-        parsed_field = key_;
-        parsed_index = 0;
-    } else {
-        parsed_field = key_.substr(0, split);
-        parsed_index = std::stoi(key_.substr(split + 1));
-    }
-
-    return parsed_field == field_ && parsed_index >= index;
-}
-
-/*
- * Delete entry/entries from persist_data. If the entries are part of a multi-segment field, all
- * remaining entries starting from index will be deleted.
- * returns PERSIST_DEL_KEY_OK if deletion succeeds,
- * PERSIST_DEL_KEY_ERROR_NO_FIELD if the field does not exist,
- * and PERSIST_DEL_KEY_ERROR_OTHER if error occurs.
- *
- */
-static int persist_del_keys(const char* fieldname, unsigned index) {
-    unsigned int i;
-    unsigned int j;
-    unsigned int num;
-
-    if (persist_data == NULL) {
-        return PERSIST_DEL_KEY_ERROR_OTHER;
-    }
-
-    num = persist_data->persist_valid_entries;
-
-    j = 0;  // points to the end of non-deleted entries.
-    // Filter out to-be-deleted entries in place.
-    for (i = 0; i < num; i++) {
-        if (!match_multi_entry(persist_data->persist_entry[i].key, fieldname, index)) {
-            persist_data->persist_entry[j] = persist_data->persist_entry[i];
-            j++;
-        }
-    }
-
-    if (j < num) {
-        persist_data->persist_valid_entries = j;
-        // Zeroise the remaining entries
-        memset(&persist_data->persist_entry[j], 0, (num - j) * sizeof(struct crypt_persist_entry));
-        return PERSIST_DEL_KEY_OK;
-    } else {
-        // Did not find an entry matching the given fieldname
-        return PERSIST_DEL_KEY_ERROR_NO_FIELD;
-    }
-}
-
-static int persist_count_keys(const char* fieldname) {
-    unsigned int i;
-    unsigned int count;
-
-    if (persist_data == NULL) {
-        return -1;
-    }
-
-    count = 0;
-    for (i = 0; i < persist_data->persist_valid_entries; i++) {
-        if (match_multi_entry(persist_data->persist_entry[i].key, fieldname, 0)) {
-            count++;
-        }
-    }
-
-    return count;
-}
-
-/* Return the value of the specified field. */
-int cryptfs_getfield(const char* fieldname, char* value, int len) {
-    if (fscrypt_is_native()) {
-        SLOGE("Cannot get field when file encrypted");
-        return -1;
-    }
-
-    char temp_value[PROPERTY_VALUE_MAX];
-    /* CRYPTO_GETFIELD_OK is success,
-     * CRYPTO_GETFIELD_ERROR_NO_FIELD is value not set,
-     * CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL is buffer (as given by len) too small,
-     * CRYPTO_GETFIELD_ERROR_OTHER is any other error
-     */
-    int rc = CRYPTO_GETFIELD_ERROR_OTHER;
-    int i;
-    char temp_field[PROPERTY_KEY_MAX];
-
-    if (persist_data == NULL) {
-        load_persistent_data();
-        if (persist_data == NULL) {
-            SLOGE("Getfield error, cannot load persistent data");
-            goto out;
-        }
-    }
-
-    // Read value from persistent entries. If the original value is split into multiple entries,
-    // stitch them back together.
-    if (!persist_get_key(fieldname, temp_value)) {
-        // We found it, copy it to the caller's buffer and keep going until all entries are read.
-        if (strlcpy(value, temp_value, len) >= (unsigned)len) {
-            // value too small
-            rc = CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL;
-            goto out;
-        }
-        rc = CRYPTO_GETFIELD_OK;
-
-        for (i = 1; /* break explicitly */; i++) {
-            if (snprintf(temp_field, sizeof(temp_field), "%s_%d", fieldname, i) >=
-                (int)sizeof(temp_field)) {
-                // If the fieldname is very long, we stop as soon as it begins to overflow the
-                // maximum field length. At this point we have in fact fully read out the original
-                // value because cryptfs_setfield would not allow fields with longer names to be
-                // written in the first place.
-                break;
-            }
-            if (!persist_get_key(temp_field, temp_value)) {
-                if (strlcat(value, temp_value, len) >= (unsigned)len) {
-                    // value too small.
-                    rc = CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL;
-                    goto out;
-                }
-            } else {
-                // Exhaust all entries.
-                break;
-            }
-        }
-    } else {
-        /* Sadness, it's not there.  Return the error */
-        rc = CRYPTO_GETFIELD_ERROR_NO_FIELD;
-    }
-
-out:
-    return rc;
-}
-
-/* Set the value of the specified field. */
-int cryptfs_setfield(const char* fieldname, const char* value) {
-    if (fscrypt_is_native()) {
-        SLOGE("Cannot set field when file encrypted");
-        return -1;
-    }
-
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    /* 0 is success, negative values are error */
-    int rc = CRYPTO_SETFIELD_ERROR_OTHER;
-    int encrypted = 0;
-    unsigned int field_id;
-    char temp_field[PROPERTY_KEY_MAX];
-    unsigned int num_entries;
-    unsigned int max_keylen;
-
-    if (persist_data == NULL) {
-        load_persistent_data();
-        if (persist_data == NULL) {
-            SLOGE("Setfield error, cannot load persistent data");
-            goto out;
-        }
-    }
-
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (!strcmp(encrypted_state, "encrypted")) {
-        encrypted = 1;
-    }
-
-    // Compute the number of entries required to store value, each entry can store up to
-    // (PROPERTY_VALUE_MAX - 1) chars
-    if (strlen(value) == 0) {
-        // Empty value also needs one entry to store.
-        num_entries = 1;
-    } else {
-        num_entries = (strlen(value) + (PROPERTY_VALUE_MAX - 1) - 1) / (PROPERTY_VALUE_MAX - 1);
-    }
-
-    max_keylen = strlen(fieldname);
-    if (num_entries > 1) {
-        // Need an extra "_%d" suffix.
-        max_keylen += 1 + log10(num_entries);
-    }
-    if (max_keylen > PROPERTY_KEY_MAX - 1) {
-        rc = CRYPTO_SETFIELD_ERROR_FIELD_TOO_LONG;
-        goto out;
-    }
-
-    // Make sure we have enough space to write the new value
-    if (persist_data->persist_valid_entries + num_entries - persist_count_keys(fieldname) >
-        persist_get_max_entries(encrypted)) {
-        rc = CRYPTO_SETFIELD_ERROR_VALUE_TOO_LONG;
-        goto out;
-    }
-
-    // Now that we know persist_data has enough space for value, let's delete the old field first
-    // to make up space.
-    persist_del_keys(fieldname, 0);
-
-    if (persist_set_key(fieldname, value, encrypted)) {
-        // fail to set key, should not happen as we have already checked the available space
-        SLOGE("persist_set_key() error during setfield()");
-        goto out;
-    }
-
-    for (field_id = 1; field_id < num_entries; field_id++) {
-        snprintf(temp_field, sizeof(temp_field), "%s_%u", fieldname, field_id);
-
-        if (persist_set_key(temp_field, value + field_id * (PROPERTY_VALUE_MAX - 1), encrypted)) {
-            // fail to set key, should not happen as we have already checked the available space.
-            SLOGE("persist_set_key() error during setfield()");
-            goto out;
-        }
-    }
-
-    /* If we are running encrypted, save the persistent data now */
-    if (encrypted) {
-        if (save_persistent_data()) {
-            SLOGE("Setfield error, cannot save persistent data");
-            goto out;
-        }
-    }
-
-    rc = CRYPTO_SETFIELD_OK;
-
-out:
-    return rc;
-}
-
-/* Checks userdata. Attempt to mount the volume if default-
- * encrypted.
- * On success trigger next init phase and return 0.
- * Currently do not handle failure - see TODO below.
- */
-int cryptfs_mount_default_encrypted(void) {
-    int crypt_type = cryptfs_get_password_type();
-    if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
-        SLOGE("Bad crypt type - error");
-    } else if (crypt_type != CRYPT_TYPE_DEFAULT) {
-        SLOGD(
-            "Password is not default - "
-            "starting min framework to prompt");
-        property_set("vold.decrypt", "trigger_restart_min_framework");
-        return 0;
-    } else if (cryptfs_check_passwd(DEFAULT_PASSWORD) == 0) {
-        SLOGD("Password is default - restarting filesystem");
-        cryptfs_restart_internal(0);
-        return 0;
-    } else {
-        SLOGE("Encrypted, default crypt type but can't decrypt");
-    }
-
-    /** Corrupt. Allow us to boot into framework, which will detect bad
-        crypto when it calls do_crypto_complete, then do a factory reset
-     */
-    property_set("vold.decrypt", "trigger_restart_min_framework");
-    return 0;
-}
-
-/* Returns type of the password, default, pattern, pin or password.
- */
-int cryptfs_get_password_type(void) {
-    if (fscrypt_is_native()) {
-        SLOGE("cryptfs_get_password_type not valid for file encryption");
-        return -1;
-    }
-
-    struct crypt_mnt_ftr crypt_ftr;
-
-    if (get_crypt_ftr_and_key(&crypt_ftr)) {
-        SLOGE("Error getting crypt footer and key\n");
-        return -1;
-    }
-
-    if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) {
-        return -1;
-    }
-
-    return crypt_ftr.crypt_type;
-}
-
-const char* cryptfs_get_password() {
-    if (fscrypt_is_native()) {
-        SLOGE("cryptfs_get_password not valid for file encryption");
-        return 0;
-    }
-
-    struct timespec now;
-    clock_gettime(CLOCK_BOOTTIME, &now);
-    if (now.tv_sec < password_expiry_time) {
-        return password;
-    } else {
-        cryptfs_clear_password();
-        return 0;
-    }
-}
-
-void cryptfs_clear_password() {
-    if (password) {
-        size_t len = strlen(password);
-        memset(password, 0, len);
-        free(password);
-        password = 0;
-        password_expiry_time = 0;
-    }
-}
-
-int cryptfs_isConvertibleToFBE() {
-    auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
-    return entry && entry->fs_mgr_flags.force_fde_or_fbe;
-}
diff --git a/crypto/fscrypt/cryptfs.h b/crypto/fscrypt/cryptfs.h
deleted file mode 100644
index 728b775..0000000
--- a/crypto/fscrypt/cryptfs.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2010 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 ANDROID_VOLD_CRYPTFS_H
-#define ANDROID_VOLD_CRYPTFS_H
-
-#include <string>
-
-#include <linux/types.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#include <cutils/properties.h>
-
-#include "KeyBuffer.h"
-#include "KeyUtil.h"
-
-#define CRYPT_FOOTER_OFFSET 0x4000
-
-/* Return values for cryptfs_crypto_complete */
-#define CRYPTO_COMPLETE_NOT_ENCRYPTED 1
-#define CRYPTO_COMPLETE_ENCRYPTED 0
-#define CRYPTO_COMPLETE_BAD_METADATA (-1)
-#define CRYPTO_COMPLETE_PARTIAL (-2)
-#define CRYPTO_COMPLETE_INCONSISTENT (-3)
-#define CRYPTO_COMPLETE_CORRUPT (-4)
-
-/* Return values for cryptfs_getfield */
-#define CRYPTO_GETFIELD_OK 0
-#define CRYPTO_GETFIELD_ERROR_NO_FIELD (-1)
-#define CRYPTO_GETFIELD_ERROR_OTHER (-2)
-#define CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL (-3)
-
-/* Return values for cryptfs_setfield */
-#define CRYPTO_SETFIELD_OK 0
-#define CRYPTO_SETFIELD_ERROR_OTHER (-1)
-#define CRYPTO_SETFIELD_ERROR_FIELD_TOO_LONG (-2)
-#define CRYPTO_SETFIELD_ERROR_VALUE_TOO_LONG (-3)
-
-/* Return values for persist_del_key */
-#define PERSIST_DEL_KEY_OK 0
-#define PERSIST_DEL_KEY_ERROR_OTHER (-1)
-#define PERSIST_DEL_KEY_ERROR_NO_FIELD (-2)
-
-// Exposed for testing only
-int match_multi_entry(const char* key, const char* field, unsigned index);
-
-int cryptfs_crypto_complete(void);
-int cryptfs_check_passwd(const char* pw);
-int cryptfs_verify_passwd(const char* pw);
-int cryptfs_restart(void);
-int cryptfs_enable(int type, const char* passwd, int no_ui);
-int cryptfs_changepw(int type, const char* newpw);
-int cryptfs_enable_default(int no_ui);
-int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev,
-                             const ::KeyBuffer& key, std::string* out_crypto_blkdev);
-int cryptfs_getfield(const char* fieldname, char* value, int len);
-int cryptfs_setfield(const char* fieldname, const char* value);
-int cryptfs_mount_default_encrypted(void);
-int cryptfs_get_password_type(void);
-const char* cryptfs_get_password(void);
-void cryptfs_clear_password(void);
-int cryptfs_isConvertibleToFBE(void);
-const KeyGeneration cryptfs_get_keygen();
-
-#endif /* ANDROID_VOLD_CRYPTFS_H */
diff --git a/crypto/fscrypt/fscrypt-common.h b/crypto/fscrypt/fscrypt-common.h
deleted file mode 100755
index e5733c6..0000000
--- a/crypto/fscrypt/fscrypt-common.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#include <map>

-// Store main DE/CE policy

-extern std::map<userid_t, EncryptionPolicy> s_de_policies;

-extern std::map<userid_t, EncryptionPolicy> s_ce_policies;

-extern std::string de_key_raw_ref;
\ No newline at end of file
diff --git a/crypto/fscrypt/fscrypt_policy.cpp b/crypto/fscrypt/fscrypt_policy.cpp
deleted file mode 100755
index c4986e5..0000000
--- a/crypto/fscrypt/fscrypt_policy.cpp
+++ /dev/null
@@ -1,208 +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 <array>
-
-#include <asm/ioctl.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/fs.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <cutils/properties.h>
-#include <logwrap/logwrap.h>
-#include <utils/misc.h>
-#include <fscrypt/fscrypt.h>
-#include "KeyUtil.h"
-
-#include "fscrypt_policy.h"
-
-static int encryption_mode = FS_ENCRYPTION_MODE_PRIVATE;
-
-bool fscrypt_is_native() {
-    LOG(ERROR) << "fscrypt_is_native::ro.crypto.type";
-    char value[PROPERTY_VALUE_MAX];
-    property_get("ro.crypto.type", value, "none");
-    return !strcmp(value, "file");
-}
-
-extern "C" void bytes_to_hex(const uint8_t *bytes, size_t num_bytes, char *hex) {
-  for (size_t i = 0; i < num_bytes; i++) {
-    sprintf(&hex[2 * i], "%02x", bytes[i]);
-  }
-}
-
-static bool is_dir_empty(const char *dirname, bool *is_empty)
-{
-    int n = 0;
-    auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(dirname), closedir);
-    if (!dirp) {
-        PLOG(ERROR) << "Unable to read directory: " << dirname;
-        return false;
-    }
-    for (;;) {
-        errno = 0;
-        auto entry = readdir(dirp.get());
-        if (!entry) {
-            if (errno) {
-                PLOG(ERROR) << "Unable to read directory: " << dirname;
-                return false;
-            }
-            break;
-        }
-        if (strcmp(entry->d_name, "lost+found") != 0) { // Skip lost+found
-            ++n;
-            if (n > 2) {
-                *is_empty = false;
-                return true;
-            }
-        }
-    }
-    *is_empty = true;
-    return true;
-}
-
-static uint8_t fscrypt_get_policy_flags(int filenames_encryption_mode) {
-    if (filenames_encryption_mode == FS_ENCRYPTION_MODE_AES_256_CTS) {
-        // Use legacy padding with our original filenames encryption mode.
-        return FS_POLICY_FLAGS_PAD_4;
-    } else if (filenames_encryption_mode == FS_ENCRYPTION_MODE_ADIANTUM) {
-        // Use DIRECT_KEY for Adiantum, since it's much more efficient but just
-        // as secure since Android doesn't reuse the same master key for
-        // multiple encryption modes
-        return (FS_POLICY_FLAGS_PAD_16 | FS_POLICY_FLAG_DIRECT_KEY);
-    }
-    // With a new mode we can use the better padding flag without breaking existing devices: pad
-    // filenames with zeroes to the next 16-byte boundary.  This is more secure (helps hide the
-    // length of filenames) and makes the inputs evenly divisible into blocks which is more
-    // efficient for encryption and decryption.
-    return FS_POLICY_FLAGS_PAD_16;
-}
-
-extern "C" bool fscrypt_set_mode() {
-    const char* mode_file = "/data/unencrypted/mode";
-    struct stat st;
-    if (stat(mode_file, &st) != 0 || st.st_size <= 0) {
-        printf("Invalid encryption mode file %s\n", mode_file);
-        return false;
-    }
-    size_t mode_size = st.st_size;
-    char contents_encryption_mode[mode_size + 1];
-    memset((void*)contents_encryption_mode, 0, mode_size + 1);
-    int fd = open(mode_file, O_RDONLY);
-    if (fd < 0) {
-        printf("error opening '%s': %s\n", mode_file, strerror(errno));
-        return false;
-    }
-    if (read(fd, contents_encryption_mode, mode_size) != mode_size) {
-        printf("read error on '%s': %s\n", mode_file, strerror(errno));
-        close(fd);
-        return false;
-    }
-    close(fd);
-
-    std::string contents_encryption_mode_string = std::string(contents_encryption_mode);
-    int pos = contents_encryption_mode_string.find(":");
-    LOG(INFO) << "contents_encryption_mode_string: " << contents_encryption_mode_string.substr(0, pos);
-
-    if (contents_encryption_mode_string.substr(0, pos) == "software") {
-        encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS;
-    } else if (contents_encryption_mode_string.substr(0, pos) == "ice") {
-        encryption_mode = FS_ENCRYPTION_MODE_PRIVATE;
-    } else {
-        printf("Invalid encryption mode '%s'\n", contents_encryption_mode);
-        return false;
-    }
-
-    printf("set encryption mode to %i\n", encryption_mode);
-    return true;
-}
-
-#ifdef USE_FSCRYPT_POLICY_V1
-extern "C" bool fscrypt_policy_set_struct(const char *directory, const struct fscrypt_policy_v1 *fep) {
-#else
-extern "C" bool fscrypt_policy_set_struct(const char *directory, const struct fscrypt_policy_v2 *fep) {
-#endif
-    int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
-    if (fd == -1) {
-        printf("failed to open %s\n", directory);
-        PLOG(ERROR) << "Failed to open directory " << directory;
-        return false;
-    }
-    if (isFsKeyringSupported()) {
-        if (ioctl(fd, FS_IOC_SET_ENCRYPTION_POLICY, fep)) {
-            PLOG(ERROR) << "Failed to set encryption policy for " << directory;
-            close(fd);
-            return false;
-        }
-    } else {
-        if (ioctl(fd, FS_IOC_SET_ENCRYPTION_POLICY, fep)) {
-            PLOG(ERROR) << "Failed to set encryption policy for " << directory;
-            close(fd);
-            return false;
-        }
-    }
-    close(fd);
-    return true;
-}
-
-#ifdef USE_FSCRYPT_POLICY_V1
-extern "C" bool fscrypt_policy_get_struct(const char *directory, struct fscrypt_policy_v1 *fep) {
-#else
-extern "C" bool fscrypt_policy_get_struct(const char *directory, struct fscrypt_policy_v2 *fep) {
-#endif
-    int fd = open(directory, O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open directory " << directory;
-        return false;
-    }
-#ifdef USE_FSCRYPT_POLICY_V1
-    memset(fep, 0, sizeof(fscrypt_policy_v1));
-#else
-    memset(fep, 0, sizeof(fscrypt_policy_v2));
-#endif
-    struct fscrypt_get_policy_ex_arg ex_policy = {0};
-
-    if (isFsKeyringSupported()) {
-        ex_policy.policy_size = sizeof(ex_policy.policy);
-        if (ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &ex_policy) != 0) {
-            PLOG(ERROR) << "Failed to get encryption policy for " << directory;
-            close(fd);
-            return false;
-        }
-#ifdef USE_FSCRYPT_POLICY_V1
-        memcpy(fep, &ex_policy.policy.v1, sizeof(ex_policy.policy.v1));
-#else
-        memcpy(fep, &ex_policy.policy.v2, sizeof(ex_policy.policy.v2));
-#endif
-    } else {
-        if (ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, &ex_policy.policy.v1) != 0) {
-            PLOG(ERROR) << "Failed to get encryption policy for " << directory;
-            close(fd);
-            return false;
-        }
-        memcpy(fep, &ex_policy.policy.v1, sizeof(ex_policy.policy.v1));
-    }
-    close(fd);
-    return true;
-}
diff --git a/crypto/fscrypt/fscrypt_policy.h b/crypto/fscrypt/fscrypt_policy.h
deleted file mode 100755
index 5714790..0000000
--- a/crypto/fscrypt/fscrypt_policy.h
+++ /dev/null
@@ -1,87 +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 _FS_CRYPT_H_
-#define _FS_CRYPT_H_
-
-#include <sys/cdefs.h>
-#include <stdbool.h>
-#include <cutils/multiuser.h>
-#include <linux/fs.h>
-
-__BEGIN_DECLS
-
-#define FS_KEY_DESCRIPTOR_SIZE_HEX (2 * FS_KEY_DESCRIPTOR_SIZE + 1)
-#define FSCRYPT_KEY_IDENTIFIER_HEX_SIZE ((2 * FSCRYPT_KEY_IDENTIFIER_SIZE) + 1)
-
-#ifdef USE_FSCRYPT_POLICY_V1
-#define USER_CE_FSCRYPT_POLICY           "0CE"
-#define USER_DE_FSCRYPT_POLICY           "0DE"
-#define SYSTEM_DE_FSCRYPT_POLICY         "0DK"
-#else
-#define USER_CE_FSCRYPT_POLICY           "2CE"
-#define USER_DE_FSCRYPT_POLICY           "2DE"
-#define SYSTEM_DE_FSCRYPT_POLICY         "2DK"
-#endif
-
-#define FSCRYPT_V1                        "0"
-#define FSCRYPT_V2                        "2"
-#define SYSTEM_DE_KEY                     "DK"
-#define USER_CE_KEY                       "C"
-#define USER_DE_KEY                       "D"
-
-/* modes not supported by upstream kernel, so not in <linux/fs.h> */
-#define FS_ENCRYPTION_MODE_AES_256_HEH      126
-#define FS_ENCRYPTION_MODE_PRIVATE          127
-
-/* new definition, not yet in Bionic's <linux/fs.h> */
-#ifndef FS_ENCRYPTION_MODE_ADIANTUM
-#define FS_ENCRYPTION_MODE_ADIANTUM         9
-#endif
-
-/* new definition, not yet in Bionic's <linux/fs.h> */
-#ifndef FS_POLICY_FLAG_DIRECT_KEY
-#define FS_POLICY_FLAG_DIRECT_KEY           0x4
-#endif
-
-#define HEX_LOOKUP "0123456789abcdef"
-
-bool fscrypt_set_mode();
-
-#ifdef USE_FSCRYPT_POLICY_V1
-bool lookup_ref_key(struct fscrypt_policy_v1 *fep, uint8_t* policy_type);
-#else
-bool lookup_ref_key(struct fscrypt_policy_v2 *fep, uint8_t* policy_type);
-#endif
-
-bool lookup_ref_tar(const uint8_t *policy_type, uint8_t *policy);
-
-#ifdef USE_FSCRYPT_POLICY_V1
-bool fscrypt_policy_get_struct(const char *directory, struct fscrypt_policy_v1  *fep);
-#else
-bool fscrypt_policy_get_struct(const char *directory, struct fscrypt_policy_v2  *fep);
-#endif
-
-#ifdef USE_FSCRYPT_POLICY_V1
-bool fscrypt_policy_set_struct(const char *directory, const struct fscrypt_policy_v1  *fep);
-#else
-bool fscrypt_policy_set_struct(const char *directory, const struct fscrypt_policy_v2  *fep);
-#endif
-
-void bytes_to_hex(const uint8_t *bytes, size_t num_bytes, char *hex);
-__END_DECLS
-
-#endif // _FS_CRYPT_H_
diff --git a/crypto/fscrypt/fscryptpolicyget.cpp b/crypto/fscrypt/fscryptpolicyget.cpp
deleted file mode 100755
index 189a428..0000000
--- a/crypto/fscrypt/fscryptpolicyget.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2016 Team Win Recovery 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 <stdlib.h>
-#include <string.h>
-#include "fscrypt_policy.h"
-#include "fscrypt/fscrypt.h"
-
-int main(int argc, char *argv[]) {
-	if (argc != 2) {
-		printf("Must specify a path\n");
-		return -1;
-	} else  {
-#ifdef USE_FSCRYPT_POLICY_V1
-		fscrypt_policy_v1 fep;
-#else
-		fscrypt_policy_v2 fep;
-#endif
-		if (fscrypt_policy_get_struct(argv[1], &fep)) {
-#ifdef USE_FSCRYPT_POLICY_V1
-			char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-			bytes_to_hex(fep.master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE, policy_hex);
-#else
-			char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
-			bytes_to_hex(fep.master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
-#endif
-			printf("%s\n", policy_hex);
-		} else {
-			printf("No policy set\n");
-		}
-	}
-	return 0;
-}
diff --git a/crypto/fscrypt/keystore_auth.cpp b/crypto/fscrypt/keystore_auth.cpp
deleted file mode 100755
index a65fe21..0000000
--- a/crypto/fscrypt/keystore_auth.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-	Copyright 2020 TeamWin
-	This file is part of TWRP/TeamWin Recovery Project.
-
-	TWRP is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	TWRP is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* The keystore refuses to allow the root user to supply auth tokens, so
- * we write the auth token to a file in TWRP and run a separate service
- * (this) that runs as the system user to add the auth token. TWRP waits
- * for /auth_token to be deleted and also looks for /auth_error to check
- * for errors. TWRP will error out after a while if /auth_token does not
- * get deleted. */
-
-#include <stdio.h>
-#include <string>
-
-#ifdef USE_SECURITY_NAMESPACE
-#include <android/security/keystore/IKeystoreService.h>
-#else
-#include <keystore/IKeystoreService.h>
-#include <keystore/authorization_set.h>
-#endif
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <keystore/keystore.h>
-
-#ifndef LOG_TAG
-#define LOG_TAG "keystore_auth"
-#endif
-
-using namespace android;
-using android::security::keystore::IKeystoreService;
-
-void create_error_file() {
-	FILE* error_file = fopen("/auth_error", "wb");
-	if (error_file == NULL) {
-		printf("Failed to open /auth_error\n");
-		ALOGE("Failed to open /auth_error\n");
-		return;
-	}
-	fwrite("1", 1, 1, error_file);
-	fclose(error_file);
-	unlink("/auth_token");
-}
-
-int main() {
-	unlink("/auth_error");
-	FILE* auth_file = fopen("/auth_token", "rb");
-	if (auth_file == NULL) {
-		printf("Failed to open /auth_token\n");
-		ALOGE("Failed to open /auth_token\n");
-		create_error_file();
-		return -1;
-	}
-	// Get the file size
-	fseek(auth_file, 0, SEEK_END);
-	int size = ftell(auth_file);
-	fseek(auth_file, 0, SEEK_SET);
-	uint8_t auth_token[size];
-	fread(auth_token , sizeof(uint8_t), size, auth_file);
-	fclose(auth_file);
-	// First get the keystore service
-	sp<IServiceManager> sm = defaultServiceManager();
-	sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
-#ifdef USE_SECURITY_NAMESPACE
-	sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-#else
-	sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-#endif
-	if (service == NULL) {
-		printf("error: could not connect to keystore service\n");
-		ALOGE("error: could not connect to keystore service\n");
-		create_error_file();
-		return -2;
-	}
-#ifdef USE_SECURITY_NAMESPACE
-	std::vector<uint8_t> auth_token_vector(&auth_token[0], (&auth_token[0]) + size);
-	int result = 0;
-	auto binder_result = service->addAuthToken(auth_token_vector, &result);
-	if (!binder_result.isOk() || !keystore::KeyStoreServiceReturnCode(result).isOk()) {
-#else
-	::keystore::KeyStoreServiceReturnCode auth_result = service->addAuthToken(auth_token, size);
-	if (!auth_result.isOk()) {
-#endif
-		// The keystore checks the uid of the calling process and will return a permission denied on this operation for user 0
-		printf("keystore error adding auth token\n");
-		ALOGE("keystore error adding auth token\n");
-		create_error_file();
-		return -3;
-	}
-	printf("successfully added auth token to keystore\n");
-	ALOGD("successfully added auth token to keystore\n");
-	unlink("/auth_token");
-	return 0;
-}
diff --git a/crypto/fscrypt/main.cpp b/crypto/fscrypt/main.cpp
deleted file mode 100644
index f0266ae..0000000
--- a/crypto/fscrypt/main.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 Team Win Recovery 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 <stdlib.h>
-#include <string.h>
-#include "Decrypt.h"
-
-int main(int argc, char *argv[]) {
-	bool ret = false;
-	if (argc < 2) {
-		Decrypt_DE();
-		ret = Decrypt_User(0, "0000");
-	} else if (argc < 3) {
-		Decrypt_DE();
-		ret = Decrypt_User(0, argv[1]);
-	} else {
-		ret = Decrypt_User(atoi(argv[1]), argv[2]);
-	}
-	if (!ret)
-		printf("Failed to decrypt\n");
-	return 0;
-}
diff --git a/crypto/fscrypt/sehandle.h b/crypto/fscrypt/sehandle.h
deleted file mode 100644
index 8921db5..0000000
--- a/crypto/fscrypt/sehandle.h
+++ /dev/null
@@ -1,24 +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 _SEHANDLE_H
-#define _SEHANDLE_H
-
-#include <selinux/android.h>
-
-extern struct selabel_handle* sehandle;
-
-#endif
diff --git a/etc/Android.mk b/etc/Android.mk
index e76527a..4aa769c 100755
--- a/etc/Android.mk
+++ b/etc/Android.mk
@@ -85,6 +85,23 @@
 
 	LOCAL_SRC_FILES := init/$(LOCAL_MODULE)
 	include $(BUILD_PREBUILT)
+
+	include $(CLEAR_VARS)
+	LOCAL_MODULE := keystore2.rc
+	LOCAL_MODULE_TAGS := optional
+	LOCAL_MODULE_CLASS := EXECUTABLES
+	LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/etc/init
+
+	LOCAL_SRC_FILES := init/$(LOCAL_MODULE)
+	include $(BUILD_PREBUILT)
+
+	include $(CLEAR_VARS)
+	LOCAL_MODULE := android.system.keystore2-service.xml
+	LOCAL_MODULE_TAGS := optional
+	LOCAL_MODULE_CLASS := EXECUTABLES
+	LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/etc/vintf/manifest
+	LOCAL_SRC_FILES := init/$(LOCAL_MODULE)
+	include $(BUILD_PREBUILT)
 endif
 
 ifeq ($(AB_OTA_UPDATER),true)
diff --git a/etc/init.rc b/etc/init.rc
index a85ce90..c6f750b 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -49,6 +49,8 @@
 
     chown root shell /tmp
     chmod 0775 /tmp
+    mkdir /tmp/misc
+    mkdir /tmp/misc/keystore/
 
     write /proc/sys/kernel/panic_on_oops 1
     write /proc/sys/vm/max_map_count 1000000
diff --git a/etc/init/android.system.keystore2-service.xml b/etc/init/android.system.keystore2-service.xml
new file mode 100644
index 0000000..6b8d0cb
--- /dev/null
+++ b/etc/init/android.system.keystore2-service.xml
@@ -0,0 +1,9 @@
+<manifest version="1.0" type="framework">
+    <hal format="aidl">
+        <name>android.system.keystore2</name>
+        <interface>
+            <name>IKeystoreService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/etc/init/keystore2.rc b/etc/init/keystore2.rc
new file mode 100644
index 0000000..fa62662
--- /dev/null
+++ b/etc/init/keystore2.rc
@@ -0,0 +1,17 @@
+# Start the keystore2 service.
+# Keystore 2.0 changes its working directory to the first positional
+# command line option, i.e., /data/misc/keystore, where it stores its
+# database.
+# Keystore shall run as user keystore and groups keystore, readproc, and log.
+#
+# See system/core/init/README.md for information on the init.rc language.
+
+on late-init
+    start keystore2
+
+service keystore2 /system/bin/keystore2 /tmp/misc/keystore
+    class early_hal
+    user root
+    group keystore readproc log
+    writepid /dev/cpuset/foreground/tasks
+    seclabel u:r:recovery:s0
diff --git a/gui/libguitwrp_defaults.go b/gui/libguitwrp_defaults.go
index 290be25..9d7dcef 100644
--- a/gui/libguitwrp_defaults.go
+++ b/gui/libguitwrp_defaults.go
@@ -349,15 +349,6 @@
 	return srcs
 }
 
-func globalIncludes(ctx android.BaseContext) []string {
-	var includes []string
-
-	if getMakeVars(ctx, "TW_INCLUDE_CRYPTO") != "" {
-		includes = append(includes, "bootable/recovery/crypto/fscrypt")
-	}
-	return includes
-}
-
 func libGuiDefaults(ctx android.LoadHookContext) {
 	type props struct {
 		Target struct {
@@ -375,8 +366,6 @@
 	p.Cflags = globalFlags(ctx)
 	s := globalSrcs(ctx)
 	p.Srcs = s
-	i := globalIncludes(ctx)
-	p.Include_dirs = i
 	ctx.AppendProperties(p)
 	if copyTheme(ctx) == false {
 		os.Exit(-1)
diff --git a/libaosprecovery_defaults.go b/libaosprecovery_defaults.go
index 442f1e4..1289ffa 100644
--- a/libaosprecovery_defaults.go
+++ b/libaosprecovery_defaults.go
@@ -30,16 +30,6 @@
 	return srcs
 }
 
-func globalIncludes(ctx android.BaseContext) []string {
-	var includes []string
-
-	if getMakeVars(ctx, "TW_INCLUDE_CRYPTO") != "" {
-		includes = append(includes, "bootable/recovery/crypto/fscrypt")
-	}
-
-	return includes
-}
-
 func libAospRecoveryDefaults(ctx android.LoadHookContext) {
 	type props struct {
 		Target struct {
@@ -57,8 +47,6 @@
 	p.Cflags = globalFlags(ctx)
 	s := globalSrcs(ctx)
 	p.Srcs = s
-	i := globalIncludes(ctx)
-	p.Include_dirs = i
 	ctx.AppendProperties(p)
 }
 
diff --git a/libtar/Android.mk b/libtar/Android.mk
index 6ff8fc9..fac3772 100755
--- a/libtar/Android.mk
+++ b/libtar/Android.mk
@@ -14,14 +14,54 @@
 LOCAL_SHARED_LIBRARIES += libselinux
 
 ifeq ($(TW_INCLUDE_CRYPTO_FBE), true)
-    LOCAL_SHARED_LIBRARIES += libtwrpfscrypt
+    LOCAL_STATIC_LIBRARIES += libvold libscrypt_static
+    LOCAL_SHARED_LIBRARIES +=  \
+        android.hardware.boot@1.0 \
+        android.hardware.confirmationui@1.0 \
+        android.hardware.gatekeeper@1.0 \
+        android.hardware.keymaster@3.0 \
+        android.hardware.keymaster@4.0 \
+        android.hardware.keymaster@4.1 \
+        android.hardware.weaver@1.0 \
+        android.security.apc-ndk_platform \
+        android.system.keystore2-V1-ndk_platform \
+        android.security.authorization-ndk_platform \
+        android.security.maintenance-ndk_platform \
+        libselinux \
+        libbinder_ndk \
+        libext4_utils \
+        libbase \
+        libcrypto \
+        libcutils \
+        libf2fs_sparseblock \
+        libkeymaster_messages \
+        libkeymint_support \
+        libkeystoreinfo \
+        libkeystore-attestation-application-id \
+        libhardware \
+        libprotobuf-cpp-lite \
+        libfscrypt \
+        libhidlbase \
+        libutils \
+        libbinder \
+        libfs_mgr \
+        libkeymaster4support \
+        libkeymaster4_1support \
+        libf2fs_sparseblock \
+        libkeyutils \
+        liblog \
+        libhwbinder \
+        libchrome \
+        libbootloader_message \
+        libgatekeeper_aidl
+
     LOCAL_CFLAGS += -DUSE_FSCRYPT
     ifeq ($(TW_USE_FSCRYPT_POLICY), 1)
         LOCAL_CFLAGS += -DUSE_FSCRYPT_POLICY_V1
     else
         LOCAL_CFLAGS += -DUSE_FSCRYPT_POLICY_V2
     endif
-    LOCAL_C_INCLUDES += $(LOCAL_PATH)/../crypto/fscrypt
+    LOCAL_C_INCLUDES += system/vold
 endif
 
 ifeq ($(TW_LIBTAR_DEBUG),true)
@@ -44,9 +84,8 @@
 LOCAL_STATIC_LIBRARIES += libselinux
 
 ifeq ($(TW_INCLUDE_CRYPTO_FBE), true)
-    LOCAL_SHARED_LIBRARIES += libtwrpfscrypt
     LOCAL_CFLAGS += -DUSE_FSCRYPT
-    LOCAL_C_INCLUDES += $(LOCAL_PATH)/../crypto/fscrypt
+    LOCAL_C_INCLUDES += system/vold
 endif
 
 ifeq ($(TW_LIBTAR_DEBUG),true)
diff --git a/minuitwrp/libminuitwrp_defaults.go b/minuitwrp/libminuitwrp_defaults.go
index a6497a2..8cb176f 100644
--- a/minuitwrp/libminuitwrp_defaults.go
+++ b/minuitwrp/libminuitwrp_defaults.go
@@ -190,10 +190,6 @@
 func globalIncludes(ctx android.BaseContext) []string {
 	var includes []string
 
-	if getMakeVars(ctx, "TW_INCLUDE_CRYPTO") != "" {
-		includes = append(includes, "bootable/recovery/crypto/fscrypt")
-	}
-
 	if getMakeVars(ctx, "TW_TARGET_USES_QCOM_BSP") == "true" {
 		if getMakeVars(ctx, "TARGET_PREBUILT_KERNEL") != "" {
 			includes = append(includes, getMakeVars(ctx, "TARGET_OUT_INTERMEDIATES")+"/KERNEL_OBJ/usr/include")
diff --git a/partition.cpp b/partition.cpp
index 4854fbe..3bdc6d3 100755
--- a/partition.cpp
+++ b/partition.cpp
@@ -50,10 +50,9 @@
 #include "gui/gui.hpp"
 #include "adbbu/libtwadbbu.hpp"
 #ifdef TW_INCLUDE_CRYPTO
-	#include "crypto/fde/cryptfs.h"
+	// #include "crypto/fde/cryptfs.h"
+	#include "cryptfs.h"
 	#include "Decrypt.h"
-#else
-	#define CRYPT_FOOTER_OFFSET 0x4000
 #endif
 extern "C" {
 	#include "mtdutils/mtdutils.h"
@@ -76,6 +75,8 @@
 #include <sparse_format.h>
 #include "progresstracking.hpp"
 
+#define CRYPT_FOOTER_OFFSET 0x4000
+
 using namespace std;
 
 static int auto_index = 0; // v2 fstab allows you to specify a mount point of "auto" with no /. These items are given a mount point of /auto* where * == auto_index
@@ -677,30 +678,10 @@
 		DataManager::SetValue(TW_IS_ENCRYPTED, 0);
 	} else if (!Mount(false)) {
 		if (Is_Present) {
-			if (Key_Directory.empty()) {
-				set_partition_data(Use_Original_Path ? Original_Path.c_str() : Actual_Block_Device.c_str(), Crypto_Key_Location.c_str(),
-				Fstab_File_System.c_str());
-				if (cryptfs_check_footer() == 0) {
-					Is_Encrypted = true;
-					Is_Decrypted = false;
-					Can_Be_Mounted = false;
-					Current_File_System = "emmc";
-					Setup_Image();
-					DataManager::SetValue(TW_CRYPTO_PWTYPE, cryptfs_get_password_type());
-					DataManager::SetValue("tw_crypto_pwtype_0", cryptfs_get_password_type());
-					DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
-					DataManager::SetValue("tw_crypto_display", "");
-					if (datamedia)
-						Setup_Data_Media();
-				} else {
-					gui_err("mount_data_footer=Could not mount /data and unable to find crypto footer.");
-				}
-			} else {
-				Is_Encrypted = true;
-				Is_Decrypted = false;
-				if (datamedia)
-					Setup_Data_Media();
-			}
+			Is_Encrypted = true;
+			Is_Decrypted = false;
+			if (datamedia)
+				Setup_Data_Media();
 		} else if (Key_Directory.empty()) {
 			LOGERR("Primary block device '%s' for mount point '%s' is not present!\n",
 			Primary_Block_Device.c_str(), Mount_Point.c_str());
@@ -774,7 +755,7 @@
 	ExcludeAll(Mount_Point + "/gsi"); // cow devices
 
 	int retry_count = 3;
-	while (!Decrypt_DE() && --retry_count)
+	while (!android::keystore::Decrypt_DE() && --retry_count)
 		usleep(2000);
 	if (retry_count > 0) {
 		PartitionManager.Set_Crypto_State();
@@ -782,7 +763,7 @@
 		Is_Decrypted = false;
 		DataManager::SetValue(TW_IS_ENCRYPTED, 1);
 		string filename;
-		int pwd_type = Get_Password_Type(0, filename);
+		int pwd_type = android::keystore::Get_Password_Type(0, filename);
 		if (pwd_type < 0) {
 			LOGERR("This TWRP does not have synthetic password decrypt support\n");
 			pwd_type = 0;  // default password
@@ -3417,10 +3398,10 @@
 			thekey.append(buf, n);
 		}
 		close(fdkey);
-		unsigned char* key = (unsigned char*) thekey.data();
-		cryptfs_revert_ext_volume(part_guid);
+		// unsigned char* key = (unsigned char*) thekey.data();
+		// cryptfs_revert_ext_volume(part_guid);
 
-		ret = cryptfs_setup_ext_volume(part_guid, Adopted_Block_Device.c_str(), key, thekey.size(), crypto_blkdev);
+		// ret = cryptfs_setup_ext_volume(part_guid, Adopted_Block_Device.c_str(), key, thekey.size(), crypto_blkdev);
 		if (ret == 0) {
 			LOGINFO("adopted storage new block device: '%s'\n", crypto_blkdev);
 			Decrypted_Block_Device = crypto_blkdev;
@@ -3431,7 +3412,7 @@
 				LOGERR("Failed to mount decrypted adopted storage device\n");
 				Is_Decrypted = false;
 				Is_Encrypted = false;
-				cryptfs_revert_ext_volume(part_guid);
+				// cryptfs_revert_ext_volume(part_guid);
 				ret = 1;
 			} else {
 				UnMount(false);
@@ -3476,7 +3457,7 @@
 	if (!Adopted_GUID.empty()) {
 		PartitionManager.Remove_MTP_Storage(Mount_Point);
 		UnMount(false);
-		cryptfs_revert_ext_volume(Adopted_GUID.c_str());
+		// cryptfs_revert_ext_volume(Adopted_GUID.c_str());
 		Is_Adopted_Storage = false;
 		Is_Encrypted = false;
 		Is_Decrypted = false;
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index 01a108c..ebdada4 100755
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -93,13 +93,15 @@
 }
 
 #ifdef TW_INCLUDE_CRYPTO
-#include "crypto/fde/cryptfs.h"
+// #include "crypto/fde/cryptfs.h"
 #include "gui/rapidxml.hpp"
 #include "gui/pages.hpp"
 #ifdef TW_INCLUDE_FBE
 #include "Decrypt.h"
 #ifdef TW_INCLUDE_FBE_METADATA_DECRYPT
 	#ifdef USE_FSCRYPT
+	#include "cryptfs.h"
+	#include "fscrypt-common.h"
 	#include "MetadataCrypt.h"
 	#endif
 #endif
@@ -431,7 +433,7 @@
 			Set_Crypto_Type("file");
 #ifdef TW_INCLUDE_FBE_METADATA_DECRYPT
 #ifdef USE_FSCRYPT
-			if (fscrypt_mount_metadata_encrypted(Decrypt_Data->Actual_Block_Device, Decrypt_Data->Mount_Point, false)) {
+			if (android::vold::fscrypt_mount_metadata_encrypted(Decrypt_Data->Actual_Block_Device, Decrypt_Data->Mount_Point, false, false, Decrypt_Data->Current_File_System)) {
 				std::string crypto_blkdev = android::base::GetProperty("ro.crypto.fs_crypto_blkdev", "error");
 				Decrypt_Data->Decrypted_Block_Device = crypto_blkdev;
 				LOGINFO("Successfully decrypted metadata encrypted data partition with new block device: '%s'\n", crypto_blkdev.c_str());
@@ -1885,7 +1887,7 @@
 			}
 
 			string filename;
-			user.type = Get_Password_Type(userId, filename);
+			user.type = android::keystore::Get_Password_Type(userId, filename);
 
 			user.isDecrypted = false;
 			if (strcmp(user_check_result, "1") == 0)
@@ -1973,7 +1975,7 @@
 		while (!TWFunc::Path_Exists("/data/system/users/gatekeeper.password.key") && --retry_count)
 			usleep(2000); // A small sleep is needed after mounting /data to ensure reliable decrypt...maybe because of DE?
 		gui_msg(Msg("decrypting_user_fbe=Attempting to decrypt FBE for user {1}...")(user_id));
-		if (Decrypt_User(user_id, Password)) {
+		if (android::keystore::Decrypt_User(user_id, Password)) {
 			gui_msg(Msg("decrypt_user_success_fbe=User {1} Decrypted Successfully")(user_id));
 			Mark_User_Decrypted(user_id);
 			if (user_id == 0) {
@@ -1985,8 +1987,8 @@
 
 					int tmp_user_id = atoi((*iter).userId.c_str());
 					gui_msg(Msg("decrypting_user_fbe=Attempting to decrypt FBE for user {1}...")(tmp_user_id));
-					if (Decrypt_User(tmp_user_id, Password) ||
-					(Password != "!" && Decrypt_User(tmp_user_id, "!"))) { // "!" means default password
+					if (android::keystore::Decrypt_User(tmp_user_id, Password) ||
+					(Password != "!" && android::keystore::Decrypt_User(tmp_user_id, "!"))) { // "!" means default password
 						gui_msg(Msg("decrypt_user_success_fbe=User {1} Decrypted Successfully")(tmp_user_id));
 						Mark_User_Decrypted(tmp_user_id);
 					} else {
diff --git a/prebuilt/Android.mk b/prebuilt/Android.mk
index d611f4a..0252173 100755
--- a/prebuilt/Android.mk
+++ b/prebuilt/Android.mk
@@ -82,6 +82,7 @@
 RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libchrome.so
 RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libevent.so
 RECOVERY_BINARY_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/keystore
+RECOVERY_BINARY_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/keystore_auth
 RECOVERY_BINARY_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/keystore_cli_v2
 RECOVERY_BINARY_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/hwservicemanager
 RECOVERY_BINARY_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/servicemanager
@@ -184,15 +185,38 @@
     # FBE files
     ifeq ($(TW_INCLUDE_CRYPTO_FBE), true)
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libtwrpfscrypt.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.security.maintenance-ndk_platform.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.system.keystore2-V1-ndk_platform.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.security.apc-ndk_platform.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.security.authorization-ndk_platform.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeymint_support.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.hardware.security.keymint-V1-ndk_platform.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.frameworks.stats-V1-ndk_platform.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.hardware.security.secureclock-V1-ndk_platform.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libgatekeeper.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libgatekeeper_aidl.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeymaster_messages.so
-        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeystore_binder.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libbinder.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libprotobuf-cpp-lite.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libsoftkeymasterdevice.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.hardware.gatekeeper@1.0.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeystore2_aaid.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeystore2_apc_compat.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeystore2_crypto.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkm_compat_service.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeystore2_vintf_cpp.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.security.compat-ndk_platform.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkm_compat.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeymint.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/lib_android_keymaster_keymint_utils.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libcppbor_external.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libcppbor.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libpuresoftkeymasterdevice.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libcppcose_rkp.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.hardware.security.sharedsecret-V1-ndk_platform.so
         RECOVERY_BINARY_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/avbctl
         RECOVERY_BINARY_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/keystore
+        RECOVERY_BINARY_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/keystore2
         RECOVERY_BINARY_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/keystore_cli
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.system.wifi.keystore@1.0.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.hardware.vibrator@1.0.so
@@ -203,6 +227,15 @@
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libstatslog.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libsoft_attestation_cert.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libxml2.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libdiskconfig.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libhardware_legacy.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libincfs.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.hardware.health.storage@1.0.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.hardware.health.storage@1.0.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.hardware.health.storage-V1-ndk_platform.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libhardware_legacy.so
+        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.system.suspend@1.0.so
+        RECOVERY_BINARY_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/fscryptpolicyget
 
         ifneq ($(wildcard system/keymaster/keymaster_stl.cpp),)
             RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeymaster_portable.so
@@ -223,8 +256,6 @@
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/android.hardware.keymaster@4.1.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeymaster4support.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeymaster4_1support.so
-        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeystore_aidl.so
-        RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libkeystore_parcelables.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libutilscallstack.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libdexfile.so
         RECOVERY_LIBRARY_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libservices.so
@@ -418,12 +449,21 @@
     cp $(TARGET_OUT_ETC)/selinux/plat_service_contexts $(TARGET_RECOVERY_ROOT_OUT)/system/etc/selinux/plat_service_contexts && \
     cp $(TARGET_OUT_ETC)/selinux/plat_hwservice_contexts $(TARGET_RECOVERY_ROOT_OUT)/system/etc/selinux/plat_hwservice_contexts && \
     cp $(TARGET_OUT_VENDOR_ETC)/selinux/vndservice_contexts $(TARGET_RECOVERY_ROOT_OUT)/vendor/etc/selinux/vndservice_contexts && \
-    cp $(TARGET_OUT_VENDOR_ETC)/selinux/vendor_hwservice_contexts $(TARGET_RECOVERY_ROOT_OUT)/vendor/etc/selinux/vendor_hwservice_contexts
+    cp $(TARGET_OUT_VENDOR_ETC)/selinux/vendor_hwservice_contexts $(TARGET_RECOVERY_ROOT_OUT)/vendor/etc/selinux/vendor_hwservice_contexts && \
+    cp $(TARGET_OUT_ETC)/selinux/plat_keystore2_key_contexts $(TARGET_RECOVERY_ROOT_OUT)/system/etc/selinux/plat_keystore2_key_contexts
     ifeq ($(TARGET_USES_MKE2FS), true)
         LOCAL_POST_INSTALL_CMD += \
             && cp $(TARGET_OUT_ETC)/mke2fs.conf $(TARGET_RECOVERY_ROOT_OUT)/system/etc/mke2fs.conf
     endif
-LOCAL_REQUIRED_MODULES += init_second_stage.recovery reboot.recovery plat_service_contexts plat_hwservice_contexts plat_hardware_contexts vndservice_contexts vendor_hwservice_contexts
+LOCAL_REQUIRED_MODULES += init_second_stage.recovery \
+    reboot.recovery \
+    plat_service_contexts \
+    plat_hwservice_contexts \
+    plat_hardware_contexts \
+    vndservice_contexts \
+    plat_keystore2_key_contexts \
+    vendor_hwservice_contexts
+
 include $(BUILD_PHONY_PACKAGE)
 
 # copy license file for OpenAES
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index 7ee5139..22a9a06 100755
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -1411,43 +1411,6 @@
 	}
 }
 
-#ifdef TW_INCLUDE_CRYPTO
-#ifdef USE_FSCRYPT_POLICY_V1
-bool TWFunc::Get_Encryption_Policy(struct fscrypt_policy_v1 &policy, std::string path) {
-#else
-bool TWFunc::Get_Encryption_Policy(struct fscrypt_policy_v2 &policy, std::string path) {
-#endif
-	if (!TWFunc::Path_Exists(path)) {
-		LOGERR("Unable to find %s to get policy\n", path.c_str());
-		return false;
-	}
-	if (!fscrypt_policy_get_struct(path.c_str(), &policy)) {
-		LOGERR("No policy set for path %s\n", path.c_str());
-		return false;
-	}
-	return true;
-}
-
-#ifdef USE_FSCRYPT_POLICY_V1
-bool TWFunc::Set_Encryption_Policy(std::string path, struct fscrypt_policy_v1 &policy) {
-#else
-bool TWFunc::Set_Encryption_Policy(std::string path, struct fscrypt_policy_v2 &policy) {
-#endif
-	if (!TWFunc::Path_Exists(path)) {
-		LOGERR("unable to find %s to set policy\n", path.c_str());
-		return false;
-	}
-	uint8_t binary_policy[FS_KEY_DESCRIPTOR_SIZE];
-	char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
-	bytes_to_hex(binary_policy, FS_KEY_DESCRIPTOR_SIZE, policy_hex);
-	if (!fscrypt_policy_set_struct(path.c_str(), &policy)) {
-		LOGERR("unable to set policy for path: %s\n", path.c_str());
-		return false;
-	}
-	return true;
-}
-#endif
-
 string TWFunc::Check_For_TwrpFolder() {
 	string oldFolder = "";
 	vector<string> customTWRPFolders;
diff --git a/twrp-functions.hpp b/twrp-functions.hpp
index 6221741..825d667 100755
--- a/twrp-functions.hpp
+++ b/twrp-functions.hpp
@@ -119,15 +119,6 @@
 	static bool Is_TWRP_App_In_System(); // Check if the TWRP app is installed in the system partition
 	static void checkforapp();
 	static int Property_Override(string Prop_Name, string Prop_Value); // Override properties (including ro. properties)
-#ifdef TW_INCLUDE_CRYPTO
-#ifdef USE_FSCRYPT_POLICY_V1
-	static bool Get_Encryption_Policy(struct fscrypt_policy_v1 &policy, std::string path); // return encryption policy for path
-	static bool Set_Encryption_Policy(std::string path, struct fscrypt_policy_v1 &policy); // set encryption policy for path
-#else
-	static bool Get_Encryption_Policy(struct fscrypt_policy_v2 &policy, std::string path); // return encryption policy for path
-	static bool Set_Encryption_Policy(std::string path, struct fscrypt_policy_v2 &policy); // set encryption policy for path
-#endif
-#endif
 	static void List_Mounts(); // List current mounts by the kernel
 	static void Clear_Bootloader_Message(); // Removes the bootloader message from misc for next boot
 	static string Check_For_TwrpFolder(); // Gets user defined path on storage where backups should be stored
diff --git a/twrp.cpp b/twrp.cpp
index 69c8218..6566e04 100644
--- a/twrp.cpp
+++ b/twrp.cpp
@@ -67,6 +67,11 @@
 }
 #endif
 
+#ifdef TW_INCLUDE_CRYPTO
+#include "FsCrypt.h"
+#include "Decrypt.h"
+#endif
+
 //extern int adb_server_main(int is_daemon, int server_port, int /* reply_fd */);
 
 TWPartitionManager PartitionManager;
@@ -251,8 +256,11 @@
 	}
 	LOGINFO("Backup of TWRP ramdisk done.\n");
 #endif
-
+#ifdef TW_INCLUDE_CRYPTO
+	android::keystore::copySqliteDb();
+#endif
 	Decrypt_Page(skip_decryption, datamedia);
+
 	// Check for and load custom theme if present
 	TWFunc::check_selinux_support();
 	gui_loadCustomResources();
@@ -350,7 +358,6 @@
 	gui_msg(Msg("rebooting=Rebooting..."));
 	TWFunc::Update_Log_File();
 	string Reboot_Arg;
-
 	DataManager::GetValue("tw_reboot_arg", Reboot_Arg);
 	if (Reboot_Arg == "recovery")
 		TWFunc::tw_reboot(rb_recovery);
diff --git a/twrpinstall/Android.bp b/twrpinstall/Android.bp
index 81fe3fb..a5ef145 100755
--- a/twrpinstall/Android.bp
+++ b/twrpinstall/Android.bp
@@ -65,7 +65,6 @@
         "bootable/recovery",
         "bootable/recovery/install/include",
         "bootable/recovery/recovery_utils/include",
-        "bootable/recovery/crypto/fscrypt"
     ],
 
     srcs: [