diff --git a/crypto/ext4crypt/Android.mk b/crypto/ext4crypt/Android.mk
deleted file mode 100755
index 8b1372b..0000000
--- a/crypto/ext4crypt/Android.mk
+++ /dev/null
@@ -1,111 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-ifeq ($(TW_INCLUDE_CRYPTO), true)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libe4crypt
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS :=
-LOCAL_SRC_FILES := Decrypt.cpp ScryptParameters.cpp Utils.cpp HashPassword.cpp ext4_crypt.cpp
-LOCAL_SHARED_LIBRARIES := libselinux libc libc++ libext4_utils libbase libcrypto libcutils libkeymaster_messages libhardware libprotobuf-cpp-lite
-LOCAL_STATIC_LIBRARIES := libscrypt_static
-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
-
-ifneq ($(wildcard hardware/libhardware/include/hardware/keymaster0.h),)
-    LOCAL_CFLAGS += -DTW_CRYPTO_HAVE_KEYMASTERX
-    LOCAL_C_INCLUDES +=  external/boringssl/src/include
-endif
-ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26; echo $$?),0)
-    #8.0 or higher
-    LOCAL_CFLAGS += -DHAVE_GATEKEEPER1
-    ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 29; echo $$?),0)
-        LOCAL_SHARED_LIBRARIES += android.hardware.confirmationui@1.0
-    endif
-    LOCAL_SHARED_LIBRARIES += android.hardware.keymaster@3.0 libkeystore_binder libhidlbase libutils libbinder android.hardware.gatekeeper@1.0
-    ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 28; echo $$?),0)
-        #9.0 rules
-        LOCAL_CFLAGS += -DUSE_KEYSTORAGE_4 -Wno-unused-variable -Wno-sign-compare -Wno-unused-parameter -Wno-comment
-        LOCAL_SRC_FILES += Ext4CryptPie.cpp Keymaster4.cpp KeyStorage4.cpp KeyUtil.cpp MetadataCrypt.cpp KeyBuffer.cpp
-        LOCAL_SHARED_LIBRARIES += android.hardware.keymaster@4.0 libkeymaster4support
-        LOCAL_SHARED_LIBRARIES += android.hardware.gatekeeper@1.0 libkeystore_parcelables libkeystore_aidl
-        LOCAL_CFLAGS += -DHAVE_SYNTH_PWD_SUPPORT
-        LOCAL_SRC_FILES += Weaver1.cpp
-        LOCAL_SHARED_LIBRARIES += android.hardware.weaver@1.0
-        LOCAL_CFLAGS += -DHAVE_LIBKEYUTILS
-        LOCAL_SHARED_LIBRARIES += libkeyutils
-    else
-        #8.0 rules
-        LOCAL_CFLAGS += -DUSE_KEYSTORAGE_3
-        LOCAL_SRC_FILES += Ext4Crypt.cpp Keymaster3.cpp KeyStorage3.cpp
-        ifneq ($(wildcard hardware/interfaces/weaver/Android.bp),)
-            #only present in some 8.0 trees and should be in all 8.1 trees
-            LOCAL_CFLAGS += -DHAVE_SYNTH_PWD_SUPPORT
-            LOCAL_SRC_FILES += Weaver1.cpp
-            LOCAL_SHARED_LIBRARIES += android.hardware.weaver@1.0
-        endif
-        ifneq ($(wildcard system/core/libkeyutils/Android.bp),)
-            #only present in some 8.0 trees and should be in all 8.1 trees
-            LOCAL_CFLAGS += -DHAVE_LIBKEYUTILS
-            LOCAL_SHARED_LIBRARIES += libkeyutils
-        endif
-    endif
-    ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 28; echo $$?),0)
-        LOCAL_REQUIRED_MODULES := keystore_auth
-    else
-        LOCAL_ADDITIONAL_DEPENDENCIES := keystore_auth
-    endif
-else
-    #7.x rules
-    LOCAL_SRC_FILES += Ext4Crypt.cpp Keymaster.cpp KeyStorage.cpp
-endif
-ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 28; echo $$?),0)
-    LOCAL_SHARED_LIBRARIES += libsoftkeymaster
-endif
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := twrpfbe
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/
-LOCAL_SRC_FILES := main.cpp
-LOCAL_SHARED_LIBRARIES := libe4crypt
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := e4policyget
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/
-LOCAL_SRC_FILES := e4policyget.cpp
-LOCAL_SHARED_LIBRARIES := libe4crypt
-LOCAL_LDFLAGS += -Wl,-dynamic-linker,/system/bin/linker64
-
-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)/
-LOCAL_SRC_FILES := keystore_auth.cpp
-LOCAL_SHARED_LIBRARIES := libc libkeystore_binder libutils libbinder liblog
-ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 28; echo $$?),0)
-    #9.0
-    LOCAL_CFLAGS += -DUSE_SECURITY_NAMESPACE
-    LOCAL_SHARED_LIBRARIES += libkeystore_aidl
-endif
-LOCAL_LDFLAGS += -Wl,-dynamic-linker,/system/bin/linker64
-
-include $(BUILD_EXECUTABLE)
-
-endif
diff --git a/crypto/ext4crypt/Decrypt.cpp b/crypto/ext4crypt/Decrypt.cpp
deleted file mode 100755
index 3f82aa1..0000000
--- a/crypto/ext4crypt/Decrypt.cpp
+++ /dev/null
@@ -1,1361 +0,0 @@
-/*
- * Copyright (C) 2016 The 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 "Decrypt.h"
-#ifdef USE_KEYSTORAGE_4
-#include "Ext4CryptPie.h"
-#else
-#include "Ext4Crypt.h"
-#endif
-
-#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
-
-#ifdef HAVE_SYNTH_PWD_SUPPORT
-#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 "ext4_crypt.h"
-
-#ifdef USE_KEYSTORAGE_4
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <android/security/BnConfirmationPromptCallback.h>
-#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>
-
-#include <algorithm>
-extern "C" {
-#include "crypto_scrypt.h"
-}
-#else
-#include "ext4_crypt.h"
-#endif //ifdef HAVE_SYNTH_PWD_SUPPORT
-
-#ifdef HAVE_GATEKEEPER1
-#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
-#else
-#include <hardware/gatekeeper.h>
-#endif
-#include "HashPassword.h"
-
-#include <android-base/file.h>
-
-#ifdef USE_KEYSTORAGE_4
-using android::security::keystore::IKeystoreService;
-#endif
-
-// Store main DE raw ref / policy
-extern std::string de_raw_ref;
-extern std::map<userid_t, std::string> s_de_key_raw_refs;
-extern std::map<userid_t, std::string> s_ce_key_raw_refs;
-
-static bool lookup_ref_key_internal(std::map<userid_t, std::string>& key_map, const char* policy, userid_t* user_id) {
-    for (std::map<userid_t, std::string>::iterator it=key_map.begin(); it!=key_map.end(); ++it) {
-        if (strncmp(it->second.c_str(), policy, it->second.size()) == 0) {
-            *user_id = it->first;
-            return true;
-        }
-    }
-    return false;
-}
-
-extern "C" bool lookup_ref_key(const char* policy, char* policy_type) {
-    userid_t user_id = 0;
-    if (strncmp(de_raw_ref.c_str(), policy, de_raw_ref.size()) == 0) {
-        strcpy(policy_type, "1DK");
-        return true;
-    }
-    if (!lookup_ref_key_internal(s_de_key_raw_refs, policy, &user_id)) {
-        if (!lookup_ref_key_internal(s_ce_key_raw_refs, policy, &user_id)) {
-            return false;
-		} else
-		    sprintf(policy_type, "1CE%d", user_id);
-    } else
-        sprintf(policy_type, "1DE%d", user_id);
-    return true;
-}
-
-extern "C" bool lookup_ref_tar(const char* policy_type, char* policy) {
-    if (strncmp(policy_type, "1", 1) != 0) {
-        printf("Unexpected version %c\n", policy_type[0]);
-        return false;
-    }
-    const char* ptr = policy_type + 1; // skip past the version number
-    if (strncmp(ptr, "DK", 2) == 0) {
-        strncpy(policy, de_raw_ref.data(), de_raw_ref.size());
-        return true;
-    }
-    userid_t user_id = atoi(ptr + 2);
-    std::string raw_ref;
-    if (*ptr == 'D') {
-        if (lookup_key_ref(s_de_key_raw_refs, user_id, &raw_ref)) {
-            strncpy(policy, raw_ref.data(), raw_ref.size());
-        } else
-            return false;
-    } else if (*ptr == 'C') {
-        if (lookup_key_ref(s_ce_key_raw_refs, user_id, &raw_ref)) {
-            strncpy(policy, raw_ref.data(), raw_ref.size());
-        } else
-            return false;
-    } else {
-        printf("unknown policy type '%s'\n", policy_type);
-        return false;
-    }
-    return true;
-}
-
-#ifndef HAVE_GATEKEEPER1
-int gatekeeper_device_initialize(gatekeeper_device_t **dev) {
-	int ret;
-	const hw_module_t *mod;
-	ret = hw_get_module_by_class(GATEKEEPER_HARDWARE_MODULE_ID, NULL, &mod);
-
-	if (ret!=0) {
-		printf("failed to get hw module\n");
-		return ret;
-	}
-
-	ret = gatekeeper_open(mod, dev);
-
-	if (ret!=0)
-		printf("failed to open gatekeeper\n");
-	return ret;
-}
-#endif //ifndef HAVE_GATEKEEPER1
-
-bool Decrypt_DE() {
-	if (!e4crypt_initialize_global_de()) { // this deals with the overarching device encryption
-		printf("e4crypt_initialize_global_de returned fail\n");
-		return false;
-	}
-	if (!e4crypt_init_user0()) {
-		printf("e4crypt_init_user0 returned fail\n");
-		return false;
-	}
-	return true;
-}
-
-#ifdef HAVE_SYNTH_PWD_SUPPORT
-// 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 */
-sp<IBinder> getKeystoreBinder() {
-	sp<IServiceManager> sm = defaultServiceManager();
-    return sm->getService(String16("android.security.keystore"));
-}
-
-sp<IBinder> getKeystoreBinderRetry() {
-	printf("Starting keystore...\n");
-    property_set("ctl.start", "keystore");
-	int retry_count = 50;
-	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 = "";
-
-	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
-	sp<IBinder> binder = getKeystoreBinderRetry();
-#ifdef USE_KEYSTORAGE_4
-	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");
-		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_V1) {
-		printf("spblob v1\n");
-		/* We're now going to handle decryptSPBlob: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#115
-		 * Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#879
-		 * This small function ends up being quite a headache. The call to get data from the keystore basically is not needed in TWRP at this time.
-		 * The keystore data seems to be the serialized data from an entire class in Java. Specifically I think it represents:
-		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
-		 * or perhaps
-		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
-		 * but the only things we "need" from this keystore are a user ID and the keyAlias which ends up being USRSKEY_synthetic_password_{handle_str}
-		 * the latter of which we already have. We may need to figure out how to get the user ID if we ever support decrypting mulitple users.
-		 * There are 2 calls to a Java decrypt funcion that is overloaded. These 2 calls go in completely different directions despite the seemingly
-		 * similar use of decrypt() and decrypt parameters. To figure out where things were going, I added logging to:
-		 * https://android.googlesource.com/platform/libcore/+/android-8.0.0_r23/ojluni/src/main/java/javax/crypto/Cipher.java#2575
-		 * Logger.global.severe("Cipher tryCombinations " + prov.getName() + " - " + prov.getInfo());
-		 * To make logging work in libcore, import java.util.logging.Logger; and either set a better logging level or modify the framework to log everything
-		 * regardless of logging level. This will give you some strings that you can grep for and find the actual crypto provider in use. In our case there were
-		 * 2 different providers in use. The first stage to get the intermediate key used:
-		 * https://android.googlesource.com/platform/external/conscrypt/+/android-8.0.0_r23/common/src/main/java/org/conscrypt/OpenSSLProvider.java
-		 * which is a pretty straight-forward OpenSSL implementation of AES/GCM/NoPadding. */
-		// 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) {
-			printf("malloc personalized_application_id\n");
-			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* iv = (const unsigned char*)byteptr; // The IV is the first 12 bytes of the spblob
-		//printf("iv: "); output_hex((const unsigned char*)iv, 12); printf("\n");
-		const unsigned char* cipher_text = (const unsigned char*)byteptr + 12; // The cipher text comes immediately after the IV
-		//printf("cipher_text: "); output_hex((const unsigned char*)cipher_text, spblob_data.size() - 2 - 12); printf("\n");
-		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, iv);
-		std::vector<unsigned char> intermediate_key;
-		intermediate_key.resize(spblob_data.size() - 2 - 12, '\0');
-		EVP_DecryptUpdate(d_ctx, &intermediate_key[0], &actual_size, cipher_text, spblob_data.size() - 2 - 12);
-		unsigned char tag[AES_BLOCK_SIZE];
-		EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, tag);
-		EVP_DecryptFinal_ex(d_ctx, &intermediate_key[actual_size], &final_size);
-		EVP_CIPHER_CTX_free(d_ctx);
-		free(personalized_application_id);
-		//printf("spblob_data size: %lu actual_size %i, final_size: %i\n", spblob_data.size(), actual_size, final_size);
-		intermediate_key.resize(actual_size + final_size - 16, '\0');// not sure why we have to trim the size by 16 as I don't see where this is done in Java side
-		//printf("intermediate key: "); output_hex((const unsigned char*)intermediate_key.data(), intermediate_key.size()); printf("\n");
-
-		// 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;
-
-		/* We only need a keyAlias which is USRSKEY_synthetic_password_b6f71045af7bd042 which we find and a uid which is -1 or 1000, I forget which
-		 * as the key data will be read again by the begin function later via the keystore.
-		 * The data is in a hidl_vec format which consists of a type and a value. */
-		/*::keystore::hidl_vec<uint8_t> data;
-		std::string keystoreid = SYNTHETIC_PASSWORD_KEY_PREFIX;
-		keystoreid += handle_str;
-
-		ret = service->get(String16(keystoreid.c_str()), user_id, &data);
-		if (ret < 0) {
-			printf("Could not connect to keystore service %i\n", ret);
-			return disk_decryption_secret_key;
-		} else if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*//*) {
-			printf("keystore error: (%d)\n", /*responses[ret],*//* ret);
-			return disk_decryption_secret_key;
-		} else {
-			printf("keystore returned: "); output_hex(&data[0], data.size()); printf("\n");
-		}*/
-
-		// Now we'll break up the intermediate key into the IV (first 12 bytes) and the cipher text (the rest of it).
-		std::vector<unsigned char> nonce = intermediate_key;
-		nonce.resize(12);
-		intermediate_key.erase (intermediate_key.begin(),intermediate_key.begin()+12);
-		//printf("nonce: "); output_hex((const unsigned char*)nonce.data(), nonce.size()); printf("\n");
-		//printf("cipher text: "); output_hex((const unsigned char*)intermediate_key.data(), intermediate_key.size()); printf("\n");
-
-		/* Now we will begin the second decrypt call found in
-		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#122
-		 * This time 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 */
-		size_t maclen = 128;
-		::keystore::AuthorizationSetBuilder begin_params;
-		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, nonce);
-		begin_params.Authorization(::keystore::TAG_MAC_LENGTH, maclen);
-		//keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
-		//keymasterArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
-		//keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
-		//keymasterArgs.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mTagLengthBits);
-		::keystore::hidl_vec<uint8_t> entropy; // No entropy is needed for decrypt
-		entropy.resize(0);
-		std::string keystore_alias = mKey_Prefix;
-		keystore_alias += keystore_alias_subid;
-		String16 keystore_alias16(keystore_alias.c_str());
-#ifdef USE_KEYSTORAGE_4
-		android::hardware::keymaster::V4_0::KeyPurpose purpose = android::hardware::keymaster::V4_0::KeyPurpose::DECRYPT;
-		security::keymaster::OperationResult begin_result;
-		security::keymaster::OperationResult update_result;
-		security::keymaster::OperationResult finish_result;
-		::android::security::keymaster::KeymasterArguments empty_params;
-		// These parameters are mostly driven by the cipher.init call https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#63
-		service->begin(binder, keystore_alias16, (int32_t)purpose, true, android::security::keymaster::KeymasterArguments(begin_params.hidl_data()), entropy, -1, &begin_result);
-#else
-		::keystore::KeyPurpose purpose = ::keystore::KeyPurpose::DECRYPT;
-		OperationResult begin_result;
-		OperationResult update_result;
-		OperationResult finish_result;
-		::keystore::hidl_vec<::keystore::KeyParameter> empty_params;
-		empty_params.resize(0);
-		// These parameters are mostly driven by the cipher.init call https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#63
-		service->begin(binder, keystore_alias16, purpose, true, begin_params.hidl_data(), entropy, -1, &begin_result);
-#endif
-		ret = begin_result.resultCode;
-		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
-			printf("keystore begin error: (%d)\n", /*responses[ret],*/ ret);
-			return disk_decryption_secret_key;
-		} else {
-			//printf("keystore begin operation successful\n");
-		}
-		// 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
-		service->update(begin_result.token, empty_params, intermediate_key, &update_result);
-		ret = update_result.resultCode;
-		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
-			printf("keystore update error: (%d)\n", /*responses[ret],*/ ret);
-			return disk_decryption_secret_key;
-		} else {
-			//printf("keystore update operation successful\n");
-			//printf("keystore update returned: "); output_hex(&update_result.data[0], update_result.data.size()); printf("\n"); // this ends up being the synthetic password
-		}
-		// We must use the data in update_data.data before we call finish below or the data will be gone
-		// 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!
-		disk_decryption_secret_key = PersonalizedHash(PERSONALIZATION_FBE_KEY, (const char*)&update_result.data[0], update_result.data.size());
-		//printf("disk_decryption_secret_key: '%s'\n", disk_decryption_secret_key.c_str());
-		::keystore::hidl_vec<uint8_t> signature;
-		service->finish(begin_result.token, empty_params, signature, entropy, &finish_result);
-		ret = finish_result.resultCode;
-		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
-			printf("keystore finish error: (%d)\n", /*responses[ret],*/ ret);
-			return disk_decryption_secret_key;
-		} else {
-			//printf("keystore finish operation successful\n");
-		}
-		stop_keystore();
-		return disk_decryption_secret_key;
-	} else 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");
-		unsigned char* cipher_text = (unsigned char*)byteptr + 12; // The cipher text comes immediately after the IV
-		::keystore::hidl_vec<uint8_t> cipher_text_hidlvec;
-		cipher_text_hidlvec.setToExternal(cipher_text, spblob_data.size() - 14 /* 1 each for version and SYNTHETIC_PASSWORD_PASSWORD_BASED and 12 for the iv */);
-		::keystore::AuthorizationSetBuilder begin_params;
-		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);
-		std::string keystore_alias = mKey_Prefix;
-		keystore_alias += keystore_alias_subid;
-		String16 keystore_alias16(keystore_alias.c_str());
-#ifdef USE_KEYSTORAGE_4
-		android::hardware::keymaster::V4_0::KeyPurpose purpose = android::hardware::keymaster::V4_0::KeyPurpose::DECRYPT;
-		security::keymaster::OperationResult begin_result;
-		security::keymaster::OperationResult update_result;
-		security::keymaster::OperationResult finish_result;
-		::android::security::keymaster::KeymasterArguments empty_params;
-		// These parameters are mostly driven by the cipher.init call https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#63
-		service->begin(binder, keystore_alias16, (int32_t)purpose, true, android::security::keymaster::KeymasterArguments(begin_params.hidl_data()), entropy, -1, &begin_result);
-#else
-		::keystore::KeyPurpose purpose = ::keystore::KeyPurpose::DECRYPT;
-		OperationResult begin_result;
-		OperationResult update_result;
-		OperationResult finish_result;
-		::keystore::hidl_vec<::keystore::KeyParameter> empty_params;
-		empty_params.resize(0);
-		// These parameters are mostly driven by the cipher.init call https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#63
-		service->begin(binder, keystore_alias16, purpose, true, begin_params.hidl_data(), entropy, -1, &begin_result);
-#endif
-		ret = begin_result.resultCode;
-		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
-			printf("keystore begin error: (%d)\n", /*responses[ret],*/ ret);
-			return disk_decryption_secret_key;
-		} /*else {
-			printf("keystore begin operation successful\n");
-		}*/
-		// 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
-		service->update(begin_result.token, empty_params, cipher_text_hidlvec, &update_result);
-		ret = update_result.resultCode;
-		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
-			printf("keystore update error: (%d)\n", /*responses[ret],*/ ret);
-			return disk_decryption_secret_key;
-		} /*else {
-			printf("keystore update operation successful\n");
-			printf("keystore update returned: "); output_hex(&update_result.data[0], update_result.data.size()); printf("\n"); // this ends up being the synthetic password
-		}*/
-		//printf("keystore resulting data: "); output_hex((unsigned char*)&update_result.data[0], update_result.data.size()); printf("\n");
-		// We must copy the data in update_data.data before we call finish below or the data will be gone
-		size_t keystore_result_size = update_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, &update_result.data[0], update_result.data.size());
-		//printf("keystore_result data: "); output_hex(keystore_result, keystore_result_size); printf("\n");
-		::keystore::hidl_vec<uint8_t> signature;
-		service->finish(begin_result.token, empty_params, signature, entropy, &finish_result);
-		ret = finish_result.resultCode;
-		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
-			printf("keystore finish error: (%d)\n", /*responses[ret],*/ ret);
-			free(keystore_result);
-			return disk_decryption_secret_key;
-		} /*else {
-			printf("keystore finish operation successful\n");
-		}*/
-		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;
-		//printf("intermediate_cipher_text: "); output_hex((const unsigned char*)intermediate_cipher_text, cipher_size); printf("\n");
-		// 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) {
-			printf("malloc personalized_application_id\n");
-			free(keystore_result);
-			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);
-		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 = FLAG_STORAGE_DE;
-    if (user_id == 0)
-		flags = FLAG_STORAGE_DE;
-	else
-		flags = FLAG_STORAGE_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 (!e4crypt_unlock_user_key(user_id, 0, token.c_str(), secret.c_str())) {
-		printf("e4crypt_unlock_user_key returned fail\n");
-		return Free_Return(retval, weaver_key, &pwd);
-	}
-/*#ifdef USE_KEYSTORAGE_4
-	if (!e4crypt_prepare_user_storage("", user_id, 0, flags)) {
-#else
-	if (!e4crypt_prepare_user_storage(nullptr, user_id, 0, flags)) {
-#endif
-		printf("failed to e4crypt_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);
-}
-#endif //HAVE_SYNTH_PWD_SUPPORT
-
-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) {
-#ifdef HAVE_SYNTH_PWD_SUPPORT
-		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;
-		}
-		if (pwd.password_type == 1) // In Android this means pattern
-			return 2; // In TWRP this means pattern
-                // In Android <11 type 2 is PIN or password
-                // In Android 11 type 3 is PIN and type 4 is password
-                else if (pwd.password_type > 1)
-			return 1; // In TWRP this means PIN or password
-		return 0; // We'll try the default password
-#else
-		printf("Synthetic password support not present in TWRP\n");
-		return -1;
-#endif
-	}
-	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 = FLAG_STORAGE_DE;
-    if (user_id == 0)
-		flags = FLAG_STORAGE_DE;
-	else
-		flags = FLAG_STORAGE_CE;
-	if (Default_Password) {
-		if (!e4crypt_unlock_user_key(user_id, 0, "!", "!")) {
-			printf("e4crypt_unlock_user_key returned fail\n");
-			return false;
-		}
-/*#ifdef USE_KEYSTORAGE_4
-		if (!e4crypt_prepare_user_storage("", user_id, 0, flags)) {
-#else
-		if (!e4crypt_prepare_user_storage(nullptr, user_id, 0, flags)) {
-#endif
-			printf("failed to e4crypt_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) {
-#ifdef HAVE_SYNTH_PWD_SUPPORT
-		printf("Using synthetic password method\n");
-		return Decrypt_User_Synth_Pass(user_id, Password);
-#else
-		printf("Synthetic password support not present in TWRP\n");
-		return false;
-#endif
-	}
-	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;
-#ifdef HAVE_GATEKEEPER1
-	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;
-	}
-#else
-	gatekeeper_device_t *gk_device;
-	ret = gatekeeper_device_initialize(&gk_device);
-    if (ret!=0)
-		return false;
-    ret = gk_device->verify(gk_device, user_id, 0, (const uint8_t *)handle.c_str(), st.st_size,
-                (const uint8_t *)Password.c_str(), (uint32_t)Password.size(), &auth_token, &auth_token_len,
-                &should_reenroll);
-    if (ret !=0) {
-		printf("failed to verify\n");
-		return false;
-	}
-#endif
-	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 (!e4crypt_unlock_user_key(user_id, 0, token_hex, secret.c_str())) {
-		printf("e4crypt_unlock_user_key returned fail\n");
-		return false;
-	}
-/*#ifdef USE_KEYSTORAGE_4
-		if (!e4crypt_prepare_user_storage("", user_id, 0, flags)) {
-#else
-		if (!e4crypt_prepare_user_storage(nullptr, user_id, 0, flags)) {
-#endif
-		printf("failed to e4crypt_prepare_user_storage\n");
-		return false;
-	}*/
-	printf("User %i Decrypted Successfully!\n", user_id);
-	return true;
-}
diff --git a/crypto/ext4crypt/Decrypt.h b/crypto/ext4crypt/Decrypt.h
deleted file mode 100644
index 56318e2..0000000
--- a/crypto/ext4crypt/Decrypt.h
+++ /dev/null
@@ -1,38 +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 << 0;
-static constexpr int STORAGE_FLAG_CE = 1 << 1;
-
-
-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/ext4crypt/Ext4Crypt.cpp b/crypto/ext4crypt/Ext4Crypt.cpp
deleted file mode 100644
index 9360b1a..0000000
--- a/crypto/ext4crypt/Ext4Crypt.cpp
+++ /dev/null
@@ -1,450 +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 "Ext4Crypt.h"
-#include "Decrypt.h"
-
-#ifdef USE_KEYSTORAGE_3
-#include "KeyStorage3.h"
-#else
-#include "KeyStorage.h"
-#endif
-#include "Utils.h"
-
-#include <algorithm>
-#include <iomanip>
-#include <map>
-#include <set>
-#include <sstream>
-#include <string>
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <openssl/sha.h>
-#include <selinux/android.h>
-#include <stdio.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <iostream>
-
-#include <private/android_filesystem_config.h>
-
-#ifdef HAVE_SYNTH_PWD_SUPPORT
-#include <ext4_utils/ext4_crypt.h>
-#else
-#include "ext4_crypt.h"
-#endif
-#ifndef HAVE_LIBKEYUTILS
-#include "key_control.h"
-#else
-#include <keyutils.h>
-#endif
-
-#include <hardware/gatekeeper.h>
-#include "HashPassword.h"
-
-#define EMULATED_USES_SELINUX 0
-#define MANAGE_MISC_DIRS 0
-
-#include <cutils/fs.h>
-#include <cutils/properties.h>
-
-#include <android-base/file.h>
-//#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-
-#define LOG(x) std::cout
-#define PLOG(x) std::cout
-#define DATA_MNT_POINT "/data"
-
-using android::base::StringPrintf;
-using android::vold::kEmptyAuthentication;
-
-// NOTE: keep in sync with StorageManager
-//static constexpr int FLAG_STORAGE_DE = 1 << 0; // moved to Decrypt.h
-//static constexpr int FLAG_STORAGE_CE = 1 << 1;
-
-// Store main DE raw ref / policy
-std::string de_raw_ref;
-// Map user ids to key references
-std::map<userid_t, std::string> s_de_key_raw_refs;
-std::map<userid_t, std::string> s_ce_key_raw_refs;
-
-namespace {
-const std::string device_key_dir = std::string() + DATA_MNT_POINT + e4crypt_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";
-
-bool s_global_de_initialized = false;
-
-// Some users are ephemeral, don't try to wipe their keys from disk
-std::set<userid_t> s_ephemeral_users;
-
-// TODO abolish this map. Keys should not be long-lived in user memory, only kernel memory.
-// See b/26948053
-std::map<userid_t, std::string> s_ce_keys;
-
-// ext4enc:TODO get this const from somewhere good
-const int EXT4_KEY_DESCRIPTOR_SIZE = 8;
-
-// ext4enc:TODO Include structure from somewhere sensible
-// MUST be in sync with ext4_crypto.c in kernel
-constexpr int EXT4_ENCRYPTION_MODE_AES_256_XTS = 1;
-constexpr int EXT4_AES_256_XTS_KEY_SIZE = 64;
-constexpr int EXT4_MAX_KEY_SIZE = 64;
-struct ext4_encryption_key {
-    uint32_t mode;
-    char raw[EXT4_MAX_KEY_SIZE];
-    uint32_t size;
-};
-}
-
-static bool e4crypt_is_emulated() {
-    return false; //property_get_bool("persist.sys.emulate_fbe", false);
-}
-
-static const char* escape_null(const char* value) {
-    return (value == nullptr) ? "null" : value;
-}
-
-// Get raw keyref - used to make keyname and to pass to ioctl
-static std::string generate_key_ref(const char* 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(EXT4_KEY_DESCRIPTOR_SIZE <= SHA512_DIGEST_LENGTH,
-                  "Hash too short for descriptor");
-    return std::string((char*)key_ref2, EXT4_KEY_DESCRIPTOR_SIZE);
-}
-
-static bool fill_key(const std::string& key, ext4_encryption_key* ext4_key) {
-    if (key.size() != EXT4_AES_256_XTS_KEY_SIZE) {
-        LOG(ERROR) << "Wrong size key " << key.size();
-        return false;
-    }
-    static_assert(EXT4_AES_256_XTS_KEY_SIZE <= sizeof(ext4_key->raw), "Key too long!");
-    ext4_key->mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
-    ext4_key->size = key.size();
-    memset(ext4_key->raw, 0, sizeof(ext4_key->raw));
-    memcpy(ext4_key->raw, key.data(), key.size());
-    return true;
-}
-
-static std::string keyname(const std::string& raw_ref) {
-    std::ostringstream o;
-    o << "ext4:";
-    for (auto i : raw_ref) {
-        o << std::hex << std::setw(2) << std::setfill('0') << (int)i;
-    }
-    LOG(INFO) << "keyname is " << o.str() << "\n";
-    return o.str();
-}
-
-// Get the keyring we store all keys in
-static bool e4crypt_keyring(key_serial_t* device_keyring) {
-    *device_keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring", "e4crypt", 0);
-    if (*device_keyring == -1) {
-        PLOG(ERROR) << "Unable to find device keyring\n";
-        return false;
-    }
-    return true;
-}
-
-// Install password into global keyring
-// Return raw key reference for use in policy
-static bool install_key(const std::string& key, std::string* raw_ref) {
-    ext4_encryption_key ext4_key;
-    if (!fill_key(key, &ext4_key)) return false;
-    *raw_ref = generate_key_ref(ext4_key.raw, ext4_key.size);
-    auto ref = keyname(*raw_ref);
-    key_serial_t device_keyring;
-    if (!e4crypt_keyring(&device_keyring)) return false;
-    key_serial_t key_id =
-        add_key("logon", ref.c_str(), (void*)&ext4_key, sizeof(ext4_key), device_keyring);
-    if (key_id == -1) {
-        PLOG(ERROR) << "Failed to insert key into keyring " << device_keyring << "\n";
-        return false;
-    }
-    LOG(DEBUG) << "Added key " << key_id << " (" << ref << ") to keyring " << device_keyring
-               << " in process " << getpid() << "\n";
-    return true;
-}
-
-static std::string get_de_key_path(userid_t user_id) {
-LOG(INFO) << "get_de_key_path " << user_id << " " << StringPrintf("%s/de/%d", user_key_dir.c_str(), user_id) << "\n";
-    return StringPrintf("%s/de/%d", user_key_dir.c_str(), user_id);
-}
-
-static std::string get_ce_key_directory_path(userid_t user_id) {
-LOG(INFO) << "get_ce_key_directory_path " << user_id << ": " << StringPrintf("%s/ce/%d", user_key_dir.c_str(), user_id) << "\n";
-    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(DEBUG) << "Skipping non-key " << entry->d_name;
-            continue;
-        }
-        result.emplace_back(directory_path + "/" + entry->d_name);
-        LOG(INFO) << "get_ce_key_paths adding: " << directory_path + "/" + entry->d_name << "\n";
-    }
-    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) {
-LOG(INFO) << "get_ce_key_current_path: " << directory_path + "/current\n";
-    return directory_path + "/current";
-}
-
-// 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) {
-            android::vold::destroyKey(other_path);
-        }
-    }
-    auto const current_path = get_ce_key_current_path(directory_path);
-    if (to_fix != current_path) {
-        LOG(DEBUG) << "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;
-        }
-    }
-}
-
-static bool read_and_fixate_user_ce_key(userid_t user_id,
-                                        const android::vold::KeyAuthentication& auth,
-                                        std::string *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(DEBUG) << "Trying user CE key " << ce_key_path;
-        if (android::vold::retrieveKey(ce_key_path, auth, ce_key)) {
-            LOG(DEBUG) << "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 read_and_install_user_ce_key(userid_t user_id,
-                                         const android::vold::KeyAuthentication& auth) {
-    if (s_ce_key_raw_refs.count(user_id) != 0) return true;
-    std::string ce_key;
-    if (!read_and_fixate_user_ce_key(user_id, auth, &ce_key)) return false;
-    std::string ce_raw_ref;
-    if (!install_key(ce_key, &ce_raw_ref)) return false;
-    s_ce_keys[user_id] = ce_key;
-    s_ce_key_raw_refs[user_id] = ce_raw_ref;
-    LOG(DEBUG) << "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(DEBUG) << "Preparing: " << dir << "\n";
-    return true;
-    return access(dir.c_str(), F_OK) == 0; // we don't want recovery creating directories or changing permissions at this point, so we will just return true if the path already exists
-    if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
-        PLOG(ERROR) << "Failed to prepare " << dir;
-        return false;
-    }
-    return true;
-}
-
-static bool path_exists(const std::string& path) {
-    return access(path.c_str(), F_OK) == 0;
-}
-
-bool lookup_key_ref(const std::map<userid_t, std::string>& 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;
-    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() {
-    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(DEBUG) << "Skipping non-de-key " << entry->d_name;
-            continue;
-        }
-        userid_t user_id = atoi(entry->d_name);
-        if (s_de_key_raw_refs.count(user_id) == 0) {
-            auto key_path = de_dir + "/" + entry->d_name;
-            std::string key;
-            if (!android::vold::retrieveKey(key_path, kEmptyAuthentication, &key)) return false;
-            std::string raw_ref;
-            if (!install_key(key, &raw_ref)) return false;
-            s_de_key_raw_refs[user_id] = raw_ref;
-            LOG(DEBUG) << "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");
-        }
-    }
-    // ext4enc: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;
-}
-
-bool e4crypt_initialize_global_de() {
-
-    if (s_global_de_initialized) {
-        LOG(INFO) << "Already initialized\n";
-        return true;
-    }
-
-    std::string device_key;
-    if (path_exists(device_key_path)) {
-        if (!android::vold::retrieveKey(device_key_path,
-                kEmptyAuthentication, &device_key)) return false;
-    } else {
-        LOG(INFO) << "NOT Creating new key\n";
-        return false;
-    }
-
-    std::string device_key_ref;
-    if (!install_key(device_key, &device_key_ref)) {
-        LOG(ERROR) << "Failed to install device key\n";
-        return false;
-    }
-
-    s_global_de_initialized = true;
-    de_raw_ref = device_key_ref;
-    return true;
-}
-
-bool e4crypt_init_user0() {
-    if (e4crypt_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 (!path_exists(get_de_key_path(0))) {
-            //if (!create_and_install_user_keys(0, false)) return false;
-            printf("de key path not found\n");
-            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;
-    }
-
-    // If this is a non-FBE device that recently left an emulated mode,
-    // restore user data directories to known-good state.
-    if (!e4crypt_is_native() && !e4crypt_is_emulated()) {
-        e4crypt_unlock_user_key(0, 0, "!", "!");
-    }
-
-    return true;
-}
-
-static bool parse_hex(const char* hex, std::string* result) {
-    if (strcmp("!", hex) == 0) {
-        *result = "";
-        return true;
-    }
-    if (android::vold::HexToStr(hex, *result) != 0) {
-        LOG(ERROR) << "Invalid FBE hex string";  // Don't log the string for security reasons
-        return false;
-    }
-    return true;
-}
-
-// TODO: rename to 'install' for consistency, and take flags to know which keys to install
-bool e4crypt_unlock_user_key(userid_t user_id, int serial __unused, const char* token_hex,
-                             const char* secret_hex) {
-    if (e4crypt_is_native()) {
-        if (s_ce_key_raw_refs.count(user_id) != 0) {
-            LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
-            return true;
-        }
-        std::string token, secret;
-        if (!parse_hex(token_hex, &token)) return false;
-        if (!parse_hex(secret_hex, &secret)) return false;
-        android::vold::KeyAuthentication auth(token, secret);
-        if (!read_and_install_user_ce_key(user_id, auth)) {
-            LOG(ERROR) << "Couldn't read key for " << user_id;
-            return false;
-        }
-    } else {
-		printf("Emulation mode not supported in TWRP\n");
-    }
-    return true;
-}
diff --git a/crypto/ext4crypt/Ext4Crypt.h b/crypto/ext4crypt/Ext4Crypt.h
deleted file mode 100644
index beb5d8f..0000000
--- a/crypto/ext4crypt/Ext4Crypt.h
+++ /dev/null
@@ -1,47 +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 <map>
-#include <string>
-
-__BEGIN_DECLS
-
-// General functions
-bool e4crypt_is_native();
-bool e4crypt_initialize_global_de();
-
-bool e4crypt_init_user0();
-//bool e4crypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral);
-//bool e4crypt_destroy_user_key(userid_t user_id);
-//bool e4crypt_add_user_key_auth(userid_t user_id, int serial, const char* token,
-//                               const char* secret);
-//bool e4crypt_fixate_newest_user_key_auth(userid_t user_id);
-
-bool e4crypt_unlock_user_key(userid_t user_id, int serial, const char* token, const char* secret);
-//bool e4crypt_lock_user_key(userid_t user_id);
-
-//bool e4crypt_prepare_user_storage(const char* volume_uuid, userid_t user_id, int serial, int flags);
-//bool e4crypt_destroy_user_storage(const char* volume_uuid, userid_t user_id, int flags);
-
-bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, userid_t user_id,
-                           std::string* raw_ref);
-
-__END_DECLS
diff --git a/crypto/ext4crypt/Ext4CryptPie.cpp b/crypto/ext4crypt/Ext4CryptPie.cpp
deleted file mode 100644
index 48b4ec9..0000000
--- a/crypto/ext4crypt/Ext4CryptPie.cpp
+++ /dev/null
@@ -1,477 +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 "Ext4CryptPie.h"
-
-#include "Keymaster4.h"
-#include "KeyStorage4.h"
-#include "KeyUtil.h"
-#include "Utils.h"
-#include "Decrypt.h"
-//#include "VoldUtil.h"
-
-#include <algorithm>
-#include <map>
-#include <set>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <limits.h>
-#include <selinux/android.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <private/android_filesystem_config.h>
-
-//#include "android/os/IVold.h"
-
-//#include "cryptfs.h"
-
-#define EMULATED_USES_SELINUX 0
-#define MANAGE_MISC_DIRS 0
-
-#include <cutils/fs.h>
-#include <cutils/properties.h>
-
-#include <ext4_utils/ext4_crypt.h>
-#include <keyutils.h>
-
-#include <android-base/file.h>
-//#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-
-#include <iostream>
-#define LOG(x) std::cout
-#define PLOG(x) std::cout
-#define DATA_MNT_POINT "/data"
-
-using android::base::StringPrintf;
-using android::base::WriteStringToFile;
-using android::vold::kEmptyAuthentication;
-using android::vold::KeyBuffer;
-using android::vold::Keymaster;
-using android::hardware::keymaster::V4_0::KeyFormat;
-
-// Store main DE raw ref / policy
-std::string de_raw_ref;
-// Map user ids to key references
-std::map<userid_t, std::string> s_de_key_raw_refs;
-std::map<userid_t, std::string> s_ce_key_raw_refs;
-// TODO abolish this map, per b/26948053
-std::map<userid_t, KeyBuffer> s_ce_keys;
-
-namespace {
-
-struct PolicyKeyRef {
-    std::string contents_mode;
-    std::string filenames_mode;
-    std::string key_raw_ref;
-};
-
-const std::string device_key_dir = std::string() + DATA_MNT_POINT + e4crypt_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";
-
-bool s_global_de_initialized = false;
-
-// Some users are ephemeral, don't try to wipe their keys from disk
-std::set<userid_t> s_ephemeral_users;
-
-}
-
-static bool e4crypt_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 << std::endl;
-        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 << std::endl;
-                return std::vector<std::string>();
-            }
-            break;
-        }
-        if (entry->d_type != DT_DIR || entry->d_name[0] != 'c') {
-            LOG(DEBUG) << "Skipping non-key " << entry->d_name << std::endl;
-            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";
-}
-
-// 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) {
-            android::vold::destroyKey(other_path);
-        }
-    }
-    auto const current_path = get_ce_key_current_path(directory_path);
-    if (to_fix != current_path) {
-        LOG(DEBUG) << "Renaming " << to_fix << " to " << current_path << std::endl;
-        if (rename(to_fix.c_str(), current_path.c_str()) != 0) {
-            PLOG(WARNING) << "Unable to rename " << to_fix << " to " << current_path << std::endl;
-        }
-    }
-}
-
-static bool read_and_fixate_user_ce_key(userid_t user_id,
-                                        const android::vold::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(DEBUG) << "Trying user CE key " << ce_key_path << std::endl;
-        if (android::vold::retrieveKey(ce_key_path, auth, ce_key)) {
-            LOG(DEBUG) << "Successfully retrieved key" << std::endl;
-            fixate_user_ce_key(directory_path, ce_key_path, paths);
-            return true;
-        }
-    }
-    LOG(ERROR) << "Failed to find working ce key for user " << user_id << std::endl;
-    return false;
-}
-
-static bool is_wrapped_key_supported_common(const std::string& mount_point) {
-    LOG(DEBUG) << "Determining wrapped-key support for " << mount_point << std::endl;
-    std::string wrapped_key_supported = android::base::GetProperty("fbe.data.wrappedkey", "false");
-    LOG(DEBUG) << "fbe.data.wrappedkey = " << wrapped_key_supported << std::endl;
-    if (mount_point == DATA_MNT_POINT && wrapped_key_supported == "true") {
-        LOG(DEBUG) << "Wrapped key supported on " << mount_point << std::endl;
-        return true;
-    } else {
-        return false;
-    }
-}
-
-bool is_wrapped_key_supported() {
-    return is_wrapped_key_supported_common(DATA_MNT_POINT);
-}
-
-bool is_wrapped_key_supported_external() {
-    return false;
-}
-
-static bool read_and_install_user_ce_key(userid_t user_id,
-                                         const android::vold::KeyAuthentication& auth) {
-    if (s_ce_key_raw_refs.count(user_id) != 0) return true;
-    KeyBuffer ce_key;
-    if (!read_and_fixate_user_ce_key(user_id, auth, &ce_key)) return false;
-    std::string ce_raw_ref;
-
-    if (is_wrapped_key_supported()) {
-        KeyBuffer ephemeral_wrapped_key;
-        if (!getEphemeralWrappedKey(KeyFormat::RAW, ce_key, &ephemeral_wrapped_key)) {
-           LOG(ERROR) << "Failed to export ce key";
-           return false;
-        }
-
-        ce_key = std::move(ephemeral_wrapped_key);
-    }
-    if (!android::vold::installKey(ce_key, &ce_raw_ref)) return false;
-    s_ce_keys[user_id] = std::move(ce_key);
-    s_ce_key_raw_refs[user_id] = ce_raw_ref;
-    LOG(DEBUG) << "Installed ce key for user " << user_id << std::endl;
-    return true;
-}
-
-static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid) {
-    LOG(DEBUG) << "Preparing: " << dir << std::endl;
-    if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
-        PLOG(ERROR) << "Failed to prepare " << dir << std::endl;
-        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) {
-    /*KeyBuffer de_key, ce_key;
-    if (!android::vold::randomKey(&de_key)) return false;
-    if (!android::vold::randomKey(&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 (!android::vold::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 (!android::vold::storeKeyAtomically(get_de_key_path(user_id), user_key_temp,
-                kEmptyAuthentication, de_key)) return false;
-    }
-    std::string de_raw_ref;
-    if (!android::vold::installKey(de_key, &de_raw_ref)) return false;
-    s_de_key_raw_refs[user_id] = de_raw_ref;
-    std::string ce_raw_ref;
-    if (!android::vold::installKey(ce_key, &ce_raw_ref)) return false;
-    s_ce_keys[user_id] = ce_key;
-    s_ce_key_raw_refs[user_id] = ce_raw_ref;
-    LOG(DEBUG) << "Created keys for user " << user_id;*/
-    LOG(DEBUG) << "TWRP not doing create_and_install_user_keys\n";
-    return true;
-}
-
-bool lookup_key_ref(const std::map<userid_t, std::string>& 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 << std::endl;
-        return false;
-    }
-    *raw_ref = refi->second;
-    return true;
-}
-
-static void get_data_file_encryption_modes(PolicyKeyRef* key_ref) {
-    /*struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab_default, DATA_MNT_POINT);
-    char const* contents_mode = strdup("ice");
-    char const* filenames_mode = strdup("aes-256-heh");
-    fs_mgr_get_file_encryption_modes(rec, &contents_mode, &filenames_mode);
-    key_ref->contents_mode = contents_mode;
-    key_ref->filenames_mode = filenames_mode;*/
-    LOG(INFO) << "contents mode '" << android::base::GetProperty("fbe.contents", "aes-256-xts") << "' filenames '" << android::base::GetProperty("fbe.filenames", "aes-256-heh") << "'\n";
-    key_ref->contents_mode =
-        android::base::GetProperty("fbe.contents", "aes-256-xts");
-    key_ref->filenames_mode =
-        android::base::GetProperty("fbe.filenames", "aes-256-heh");
-}
-
-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() {
-    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" << std::endl;
-        return false;
-    }
-    for (;;) {
-        errno = 0;
-        auto entry = readdir(dirp.get());
-        if (!entry) {
-            if (errno) {
-                PLOG(ERROR) << "Unable to read de key directory" << std::endl;
-                return false;
-            }
-            break;
-        }
-        if (entry->d_type != DT_DIR || !is_numeric(entry->d_name)) {
-            LOG(DEBUG) << "Skipping non-de-key " << entry->d_name << std::endl;
-            continue;
-        }
-        userid_t user_id = std::stoi(entry->d_name);
-        if (s_de_key_raw_refs.count(user_id) == 0) {
-            auto key_path = de_dir + "/" + entry->d_name;
-            KeyBuffer key;
-            if (!android::vold::retrieveKey(key_path, kEmptyAuthentication, &key)) return false;
-            std::string raw_ref;
-            if (is_wrapped_key_supported()) {
-                KeyBuffer ephemeral_wrapped_key;
-                if (!getEphemeralWrappedKey(KeyFormat::RAW, key, &ephemeral_wrapped_key)) {
-                   LOG(ERROR) << "Failed to export de_key in create_and_install_user_keys";
-                   return false;
-                }
-                key = std::move(ephemeral_wrapped_key);
-            }
-            if (!android::vold::installKey(key, &raw_ref)) return false;
-            s_de_key_raw_refs[user_id] = raw_ref;
-            LOG(DEBUG) << "Installed de key for user " << user_id << std::endl;
-
-            std::string user_prop = "twrp.user." + std::to_string(user_id) + ".decrypt";
-            property_set(user_prop.c_str(), "0");
-        }
-    }
-    // ext4enc: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;
-}
-
-bool e4crypt_initialize_global_de() {
-    LOG(INFO) << "e4crypt_initialize_global_de" << std::endl;
-    bool wrapped_key_supported = false;
-
-    if (s_global_de_initialized) {
-        LOG(INFO) << "Already initialized" << std::endl;
-        return true;
-    }
-
-    PolicyKeyRef device_ref;
-    wrapped_key_supported = is_wrapped_key_supported();
-    LOG(INFO) << "calling retrieveAndInstallKey\n";
-    if (!android::vold::retrieveAndInstallKey(true, kEmptyAuthentication, device_key_path,
-                                              device_key_temp, &device_ref.key_raw_ref, wrapped_key_supported))
-        return false;
-    get_data_file_encryption_modes(&device_ref);
-
-    std::string modestring = device_ref.contents_mode + ":" + device_ref.filenames_mode;
-    std::string mode_filename = std::string("/data") + e4crypt_key_mode;
-    if (!android::base::WriteStringToFile(modestring, mode_filename)) {
-        PLOG(ERROR) << "Cannot save type" << std::endl;
-        return false;
-    }
-
-    std::string ref_filename = std::string("/data") + e4crypt_key_ref;
-    if (!android::base::WriteStringToFile(device_ref.key_raw_ref, ref_filename)) {
-        PLOG(ERROR) << "Cannot save key reference to:" << ref_filename << std::endl;
-        return false;
-    }
-    LOG(INFO) << "Wrote system DE key reference to:" << ref_filename << std::endl;
-
-    s_global_de_initialized = true;
-    de_raw_ref = device_ref.key_raw_ref;
-    return true;
-}
-
-bool e4crypt_init_user0() {
-    LOG(DEBUG) << "e4crypt_init_user0\n";
-    if (e4crypt_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 (!android::vold::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;
-    }
-
-    // If this is a non-FBE device that recently left an emulated mode,
-    // restore user data directories to known-good state.
-    if (!e4crypt_is_native() && !e4crypt_is_emulated()) {
-        e4crypt_unlock_user_key(0, 0, "!", "!");
-    }
-
-    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 << std::endl;
-        // FIXME temporary workaround for b/26713622
-        if (e4crypt_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 << std::endl;
-        // FIXME temporary workaround for b/26713622
-        if (e4crypt_is_emulated()) return false;
-    }
-#endif
-    return true;
-}
-
-static bool parse_hex(const std::string& hex, std::string* result) {
-    if (hex == "!") {
-        *result = "";
-        return true;
-    }
-    if (android::vold::HexToStr(hex, *result) != 0) {
-        LOG(ERROR) << "Invalid FBE hex string" << std::endl;  // Don't log the string for security reasons
-        return false;
-    }
-    return true;
-}
-
-// TODO: rename to 'install' for consistency, and take flags to know which keys to install
-bool e4crypt_unlock_user_key(userid_t user_id, int serial, const std::string& token_hex,
-                             const std::string& secret_hex) {
-    LOG(DEBUG) << "e4crypt_unlock_user_key " << user_id << " serial=" << serial
-               << " token_present=" << (token_hex != "!") << std::endl;
-    if (e4crypt_is_native()) {
-        if (s_ce_key_raw_refs.count(user_id) != 0) {
-            LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id << std::endl;
-            return true;
-        }
-        std::string token, secret;
-        if (!parse_hex(token_hex, &token)) return false;
-        if (!parse_hex(secret_hex, &secret)) return false;
-        android::vold::KeyAuthentication auth(token, secret);
-        if (!read_and_install_user_ce_key(user_id, auth)) {
-            LOG(ERROR) << "Couldn't read key for " << user_id << std::endl;
-            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(android::vold::BuildDataSystemCePath(user_id), 0771) ||
-            !emulated_unlock(android::vold::BuildDataMiscCePath(user_id), 01771) ||
-            !emulated_unlock(android::vold::BuildDataMediaCePath("", user_id), 0770) ||
-            !emulated_unlock(android::vold::BuildDataUserCePath("", user_id), 0771)) {
-            LOG(ERROR) << "Failed to unlock user " << user_id << std::endl;
-            return false;
-        }
-    }
-    return true;
-}
diff --git a/crypto/ext4crypt/Ext4CryptPie.h b/crypto/ext4crypt/Ext4CryptPie.h
deleted file mode 100644
index 7236bc0..0000000
--- a/crypto/ext4crypt/Ext4CryptPie.h
+++ /dev/null
@@ -1,45 +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 <cutils/multiuser.h>
-
-bool e4crypt_initialize_global_de();
-
-bool e4crypt_init_user0();
-/*bool e4crypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral);
-bool e4crypt_destroy_user_key(userid_t user_id);
-bool e4crypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token,
-                               const std::string& secret);
-bool e4crypt_fixate_newest_user_key_auth(userid_t user_id);*/
-
-bool e4crypt_unlock_user_key(userid_t user_id, int serial, const std::string& token,
-                             const std::string& secret);
-//bool e4crypt_lock_user_key(userid_t user_id);
-
-/*bool e4crypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
-                                  int flags);*/
-/*bool e4crypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags);
-
-bool e4crypt_destroy_volume_keys(const std::string& volume_uuid);*/
-
-bool is_wrapped_key_supported();
-bool is_wrapped_key_supported_external();
-
-bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, userid_t user_id,
-                           std::string* raw_ref);
diff --git a/crypto/ext4crypt/HashPassword.cpp b/crypto/ext4crypt/HashPassword.cpp
deleted file mode 100644
index 07ecb1f..0000000
--- a/crypto/ext4crypt/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/ext4crypt/HashPassword.h b/crypto/ext4crypt/HashPassword.h
deleted file mode 100644
index 73880b1..0000000
--- a/crypto/ext4crypt/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/ext4crypt/KeyBuffer.cpp b/crypto/ext4crypt/KeyBuffer.cpp
deleted file mode 100644
index e7aede5..0000000
--- a/crypto/ext4crypt/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/ext4crypt/KeyBuffer.h b/crypto/ext4crypt/KeyBuffer.h
deleted file mode 100644
index 2087187..0000000
--- a/crypto/ext4crypt/KeyBuffer.h
+++ /dev/null
@@ -1,63 +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>
-
-namespace android {
-namespace vold {
-
-/**
- * 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);
-
-}  // namespace vold
-}  // namespace android
-
-#endif
-
diff --git a/crypto/ext4crypt/KeyStorage.cpp b/crypto/ext4crypt/KeyStorage.cpp
deleted file mode 100644
index 199520e..0000000
--- a/crypto/ext4crypt/KeyStorage.cpp
+++ /dev/null
@@ -1,349 +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 "Keymaster.h"
-#include "ScryptParameters.h"
-#include "Utils.h"
-
-#include <vector>
-
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <iostream>
-
-#include <openssl/sha.h>
-
-#include <android-base/file.h>
-//#include <android-base/logging.h>
-
-#include <cutils/properties.h>
-
-#include <hardware/hw_auth_token.h>
-
-#include <keymaster/authorization_set.h>
-
-extern "C" {
-
-#include "crypto_scrypt.h"
-}
-
-#define ERROR 1
-#define LOG(x) std::cout
-#define PLOG(x) std::cout
-
-namespace android {
-namespace vold {
-
-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 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* kFn_encrypted_key = "encrypted_key";
-static const char* kFn_keymaster_key_blob = "keymaster_key_blob";
-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 std::string hashSecdiscardable(const std::string& secdiscardable) {
-    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 secdiscardableHashingPrefix = "Android secdiscardable SHA512";
-    secdiscardableHashingPrefix.resize(SHA512_CBLOCK);
-    SHA512_Update(&c, secdiscardableHashingPrefix.data(), secdiscardableHashingPrefix.size());
-    SHA512_Update(&c, secdiscardable.data(), secdiscardable.size());
-    std::string res(SHA512_DIGEST_LENGTH, '\0');
-    SHA512_Final(reinterpret_cast<uint8_t*>(&res[0]), &c);
-    return res;
-}
-
-/*static bool generateKeymasterKey(Keymaster& keymaster, const KeyAuthentication& auth,
-                                 const std::string& appId, std::string* key) {
-    auto paramBuilder = keymaster::AuthorizationSetBuilder()
-                            .AesEncryptionKey(AES_KEY_BYTES * 8)
-                            .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_GCM)
-                            .Authorization(keymaster::TAG_MIN_MAC_LENGTH, GCM_MAC_BYTES * 8)
-                            .Authorization(keymaster::TAG_PADDING, KM_PAD_NONE);
-    addStringParam(&paramBuilder, keymaster::TAG_APPLICATION_ID, appId);
-    if (auth.token.empty()) {
-        LOG(DEBUG) << "Creating key that doesn't need auth token";
-        paramBuilder.Authorization(keymaster::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());
-        paramBuilder.Authorization(keymaster::TAG_USER_SECURE_ID, at->user_id);
-        paramBuilder.Authorization(keymaster::TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD);
-        paramBuilder.Authorization(keymaster::TAG_AUTH_TIMEOUT, AUTH_TIMEOUT);
-    }
-    return keymaster.generateKey(paramBuilder.build(), key);
-}*/
-
-static keymaster::AuthorizationSetBuilder beginParams(const KeyAuthentication& auth,
-                                                      const std::string& appId) {
-    auto paramBuilder = keymaster::AuthorizationSetBuilder()
-                            .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_GCM)
-                            .Authorization(keymaster::TAG_MAC_LENGTH, GCM_MAC_BYTES * 8)
-                            .Authorization(keymaster::TAG_PADDING, KM_PAD_NONE);
-    addStringParam(&paramBuilder, keymaster::TAG_APPLICATION_ID, appId);
-    if (!auth.token.empty()) {
-        LOG(DEBUG) << "Supplying auth token to Keymaster";
-        addStringParam(&paramBuilder, keymaster::TAG_AUTH_TOKEN, auth.token);
-    }
-    return paramBuilder;
-}
-
-/*static bool encryptWithKeymasterKey(Keymaster& keymaster, const std::string& key,
-                                    const KeyAuthentication& auth, const std::string& appId,
-                                    const std::string& message, std::string* ciphertext) {
-    auto params = beginParams(auth, appId).build();
-    keymaster::AuthorizationSet outParams;
-    auto opHandle = keymaster.begin(KM_PURPOSE_ENCRYPT, key, params, &outParams);
-    if (!opHandle) return false;
-    keymaster_blob_t nonceBlob;
-    if (!outParams.GetTagValue(keymaster::TAG_NONCE, &nonceBlob)) {
-        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.data), nonceBlob.data_length);
-    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.finishWithOutput(&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& key,
-                                    const KeyAuthentication& auth, const std::string& appId,
-                                    const std::string& ciphertext, std::string* message) {
-    auto nonce = ciphertext.substr(0, GCM_NONCE_BYTES);
-    auto bodyAndMac = ciphertext.substr(GCM_NONCE_BYTES);
-    auto params = addStringParam(beginParams(auth, appId), keymaster::TAG_NONCE, nonce).build();
-    auto opHandle = keymaster.begin(KM_PURPOSE_DECRYPT, key, params);
-    if (!opHandle) return false;
-    if (!opHandle.updateCompletely(bodyAndMac, message)) return false;
-    if (!opHandle.finish()) return false;
-    return true;
-}
-
-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 writeStringToFile(const std::string& payload, const std::string& filename) {
-    if (!android::base::WriteStringToFile(payload, filename)) {
-        PLOG(ERROR) << "Failed to write to " << filename;
-        return false;
-    }
-    return true;
-}*/
-
-static std::string getStretching() {
-    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,
-                          std::string* appId) {
-    std::string stretched;
-    if (!stretchSecret(stretching, auth.secret, salt, &stretched)) return false;
-    *appId = hashSecdiscardable(secdiscardable) + stretched;
-    return true;
-}
-
-/*bool storeKey(const std::string& dir, const KeyAuthentication& auth, const std::string& 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;
-    if (ReadRandomBytes(SECDISCARDABLE_BYTES, secdiscardable) != OK) {
-        // TODO status_t plays badly with PLOG, fix it.
-        LOG(ERROR) << "Random read failed";
-        return false;
-    }
-    if (!writeStringToFile(secdiscardable, dir + "/" + kFn_secdiscardable)) return false;
-    std::string stretching = auth.secret.empty() ? kStretch_nopassword : getStretching();
-    if (!writeStringToFile(stretching, dir + "/" + kFn_stretching)) return false;
-    std::string salt;
-    if (stretchingNeedsSalt(stretching)) {
-        if (ReadRandomBytes(SALT_BYTES, salt) != 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, &appId)) return false;
-    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;
-    std::string encryptedKey;
-    if (!encryptWithKeymasterKey(keymaster, kmKey, auth, appId, key, &encryptedKey)) return false;
-    if (!writeStringToFile(encryptedKey, dir + "/" + kFn_encrypted_key)) return false;
-    return true;
-}*/
-
-bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, std::string* key) {
-    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;
-    if (!readFileToString(dir + "/" + kFn_secdiscardable, &secdiscardable)) 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, &appId)) return false;
-    std::string kmKey;
-    if (!readFileToString(dir + "/" + kFn_keymaster_key_blob, &kmKey)) return false;
-    std::string encryptedMessage;
-    if (!readFileToString(dir + "/" + kFn_encrypted_key, &encryptedMessage)) return false;
-    Keymaster keymaster;
-    if (!keymaster) return false;
-    return decryptWithKeymasterKey(keymaster, kmKey, auth, appId, encryptedMessage, key);
-}
-
-static bool deleteKey(const std::string& dir) {
-    std::string kmKey;
-    if (!readFileToString(dir + "/" + kFn_keymaster_key_blob, &kmKey)) return false;
-    Keymaster keymaster;
-    if (!keymaster) return false;
-    if (!keymaster.deleteKey(kmKey)) return false;
-    return true;
-}
-
-static bool secdiscardSecdiscardable(const std::string& dir) {
-    if (ForkExecvp(
-            std::vector<std::string>{kSecdiscardPath, "--", dir + "/" + kFn_secdiscardable}) != 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.
-    success &= deleteKey(dir);
-    success &= secdiscardSecdiscardable(dir);
-    success &= recursiveDeleteKey(dir);
-    return success;
-}
-
-}  // namespace vold
-}  // namespace android
diff --git a/crypto/ext4crypt/KeyStorage.h b/crypto/ext4crypt/KeyStorage.h
deleted file mode 100644
index 63d38da..0000000
--- a/crypto/ext4crypt/KeyStorage.h
+++ /dev/null
@@ -1,53 +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 <string>
-
-namespace android {
-namespace vold {
-
-// 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 "secret" is nonempty, it is appended to the application-specific
-// binary needed to unlock.
-class KeyAuthentication {
-  public:
-    KeyAuthentication(std::string t, std::string s) : token{t}, secret{s} {};
-    const std::string token;
-    const std::string secret;
-};
-
-extern const KeyAuthentication kEmptyAuthentication;
-
-// 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 std::string& key);
-
-// Retrieve the key from the named directory.
-bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, std::string* key);
-
-// Securely destroy the key stored in the named directory and delete the directory.
-bool destroyKey(const std::string& dir);
-
-}  // namespace vold
-}  // namespace android
-
-#endif
diff --git a/crypto/ext4crypt/KeyStorage3.cpp b/crypto/ext4crypt/KeyStorage3.cpp
deleted file mode 100644
index a07212d..0000000
--- a/crypto/ext4crypt/KeyStorage3.cpp
+++ /dev/null
@@ -1,526 +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 "KeyStorage3.h"
-
-#include "Keymaster3.h"
-#include "ScryptParameters.h"
-#include "Utils.h"
-
-#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 <cutils/properties.h>
-
-#include <hardware/hw_auth_token.h>
-
-#include <keystore/authorization_set.h>
-#include <keystore/keystore_hidl_support.h>
-
-extern "C" {
-
-#include "crypto_scrypt.h"
-}
-
-#include <iostream>
-#define ERROR 1
-#define LOG(x) std::cout
-#define PLOG(x) std::cout
-
-namespace android {
-namespace vold {
-using namespace keystore;
-
-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 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 std::string hashWithPrefix(char const* prefix, const std::string& tohash) {
-    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());
-    std::string res(SHA512_DIGEST_LENGTH, '\0');
-    SHA512_Final(reinterpret_cast<uint8_t*>(&res[0]), &c);
-    return res;
-}
-
-/*static bool generateKeymasterKey(Keymaster& keymaster, const KeyAuthentication& auth,
-                                 const std::string& appId, std::string* key) {
-    auto paramBuilder = AuthorizationSetBuilder()
-                            .AesEncryptionKey(AES_KEY_BYTES * 8)
-                            .Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
-                            .Authorization(TAG_MIN_MAC_LENGTH, GCM_MAC_BYTES * 8)
-                            .Authorization(TAG_PADDING, PaddingMode::NONE)
-                            .Authorization(TAG_APPLICATION_ID, blob2hidlVec(appId));
-    if (auth.token.empty()) {
-        LOG(DEBUG) << "Creating key that doesn't need auth token";
-        paramBuilder.Authorization(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());
-        paramBuilder.Authorization(TAG_USER_SECURE_ID, at->user_id);
-        paramBuilder.Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD);
-        paramBuilder.Authorization(TAG_AUTH_TIMEOUT, AUTH_TIMEOUT);
-    }
-    return keymaster.generateKey(paramBuilder, key);
-}*/
-
-static AuthorizationSet beginParams(const KeyAuthentication& auth,
-                                               const std::string& appId) {
-    auto paramBuilder = AuthorizationSetBuilder()
-                            .Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
-                            .Authorization(TAG_MAC_LENGTH, GCM_MAC_BYTES * 8)
-                            .Authorization(TAG_PADDING, PaddingMode::NONE)
-                            .Authorization(TAG_APPLICATION_ID, blob2hidlVec(appId));
-    if (!auth.token.empty()) {
-        LOG(DEBUG) << "Supplying auth token to Keymaster";
-        paramBuilder.Authorization(TAG_AUTH_TOKEN, blob2hidlVec(auth.token));
-    }
-    return paramBuilder;
-}
-
-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 writeStringToFile(const std::string& payload, const std::string& filename) {
-    if (!android::base::WriteStringToFile(payload, filename)) {
-        PLOG(ERROR) << "Failed to write to " << filename;
-        return false;
-    }
-    return true;
-}
-
-static KeymasterOperation begin(Keymaster& keymaster, const std::string& dir,
-                                KeyPurpose purpose,
-                                const AuthorizationSet &keyParams,
-                                const AuthorizationSet &opParams,
-                                AuthorizationSet* outParams) {
-    auto kmKeyPath = dir + "/" + kFn_keymaster_key_blob;
-    std::string kmKey;
-    if (!readFileToString(kmKeyPath, &kmKey)) return KeymasterOperation();
-    AuthorizationSet inParams(keyParams);
-    inParams.append(opParams.begin(), opParams.end());
-    for (;;) {
-        auto opHandle = keymaster.begin(purpose, kmKey, inParams, outParams);
-        if (opHandle) {
-            return opHandle;
-        }
-        if (opHandle.errorCode() != ErrorCode::KEY_REQUIRES_UPGRADE) return opHandle;
-        LOG(DEBUG) << "Upgrading key: " << dir;
-        std::string newKey;
-        if (!keymaster.upgradeKey(kmKey, keyParams, &newKey)) return KeymasterOperation();
-        // Upgrade the key in memory but do not replace the key in storage
-        /*auto newKeyPath = dir + "/" + kFn_keymaster_key_blob_upgraded;
-        if (!writeStringToFile(newKey, newKeyPath)) return KeymasterOperation();
-        if (rename(newKeyPath.c_str(), kmKeyPath.c_str()) != 0) {
-            PLOG(ERROR) << "Unable to move upgraded key to location: " << kmKeyPath;
-            return KeymasterOperation();
-        }
-        if (!keymaster.deleteKey(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 AuthorizationSet &keyParams,
-                                    const std::string& message, std::string* ciphertext) {
-    AuthorizationSet opParams;
-    AuthorizationSet outParams;
-    auto opHandle = begin(keymaster, dir, KeyPurpose::ENCRYPT, keyParams, opParams, &outParams);
-    if (!opHandle) return false;
-    auto nonceBlob = outParams.GetTagValue(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 AuthorizationSet &keyParams,
-                                    const std::string& ciphertext, std::string* message) {
-    auto nonce = ciphertext.substr(0, GCM_NONCE_BYTES);
-    auto bodyAndMac = ciphertext.substr(GCM_NONCE_BYTES);
-    auto opParams = AuthorizationSetBuilder()
-            .Authorization(TAG_NONCE, blob2hidlVec(nonce));
-    auto opHandle = begin(keymaster, dir, KeyPurpose::DECRYPT, keyParams, opParams, nullptr);
-    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,
-                          std::string* appId) {
-    std::string stretched;
-    if (!stretchSecret(stretching, auth.secret, salt, &stretched)) return false;
-    *appId = hashWithPrefix(kHashPrefix_secdiscardable, secdiscardable) + stretched;
-    return true;
-}
-
-static bool readRandomBytesOrLog(size_t count, std::string* out) {
-    auto status = ReadRandomBytes(count, *out);
-    if (status != OK) {
-        LOG(ERROR) << "Random read failed with status: " << status;
-        return false;
-    }
-    return true;
-}
-
-static void logOpensslError() {
-    LOG(ERROR) << "Openssl error: " << ERR_get_error();
-}
-
-static bool encryptWithoutKeymaster(const std::string& preKey,
-                                    const std::string& plaintext, std::string* ciphertext) {
-    auto key = hashWithPrefix(kHashPrefix_keygen, preKey);
-    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, std::string* plaintext) {
-    if (ciphertext.size() < GCM_NONCE_BYTES + GCM_MAC_BYTES) {
-        LOG(ERROR) << "GCM ciphertext too small: " << ciphertext.size();
-        return false;
-    }
-    auto key = hashWithPrefix(kHashPrefix_keygen, preKey);
-    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->resize(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 storeKey(const std::string& dir, const KeyAuthentication& auth, const std::string& 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;
-    if (!readRandomBytesOrLog(SECDISCARDABLE_BYTES, &secdiscardable)) return false;
-    if (!writeStringToFile(secdiscardable, dir + "/" + kFn_secdiscardable)) 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) != 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, &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;
-        auto keyParams = beginParams(auth, appId);
-        if (!encryptWithKeymasterKey(keymaster, dir, keyParams, key, &encryptedKey)) return false;
-    } else {
-        if (!encryptWithoutKeymaster(appId, key, &encryptedKey)) return false;
-    }
-    if (!writeStringToFile(encryptedKey, dir + "/" + kFn_encrypted_key)) return false;
-    return true;
-}*/
-
-bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, std::string* key) {
-    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;
-    if (!readFileToString(dir + "/" + kFn_secdiscardable, &secdiscardable)) 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, &appId)) return false;
-    std::string encryptedMessage;
-    if (!readFileToString(dir + "/" + kFn_encrypted_key, &encryptedMessage)) return false;
-    if (auth.usesKeymaster()) {
-        Keymaster keymaster;
-        if (!keymaster) return false;
-        auto keyParams = beginParams(auth, appId);
-        if (!decryptWithKeymasterKey(keymaster, dir, keyParams, encryptedMessage, key)) 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;
-    Keymaster keymaster;
-    if (!keymaster) return false;
-    if (!keymaster.deleteKey(kmKey)) return false;
-    return true;
-}
-
-static bool runSecdiscard(const std::string& dir) {
-    if (ForkExecvp(
-            std::vector<std::string>{kSecdiscardPath, "--",
-                dir + "/" + kFn_encrypted_key,
-                dir + "/" + kFn_keymaster_key_blob,
-                dir + "/" + kFn_secdiscardable,
-                }) != 0) {
-        LOG(ERROR) << "secdiscard failed";
-        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.
-    success &= deleteKey(dir);
-    success &= runSecdiscard(dir);
-    success &= recursiveDeleteKey(dir);
-    return success;
-}
-
-}  // namespace vold
-}  // namespace android
diff --git a/crypto/ext4crypt/KeyStorage3.h b/crypto/ext4crypt/KeyStorage3.h
deleted file mode 100644
index bce6a99..0000000
--- a/crypto/ext4crypt/KeyStorage3.h
+++ /dev/null
@@ -1,58 +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 <string>
-
-namespace android {
-namespace vold {
-
-// 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(std::string t, 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;
-
-// 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 std::string& key);
-
-// Retrieve the key from the named directory.
-bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, std::string* key);
-
-// 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);
-}  // namespace vold
-}  // namespace android
-
-#endif
diff --git a/crypto/ext4crypt/KeyStorage4.cpp b/crypto/ext4crypt/KeyStorage4.cpp
deleted file mode 100644
index b086791..0000000
--- a/crypto/ext4crypt/KeyStorage4.cpp
+++ /dev/null
@@ -1,656 +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 "KeyStorage4.h"
-
-#include "Keymaster4.h"
-#include "ScryptParameters.h"
-#include "Utils.h"
-
-#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/unique_fd.h>
-
-#include <cutils/properties.h>
-
-#include <hardware/hw_auth_token.h>
-#include <keymasterV4_0/authorization_set.h>
-#include <keymasterV4_0/keymaster_utils.h>
-
-#include <iostream>
-#define ERROR 1
-#define LOG(x) std::cout
-#define PLOG(x) std::cout
-
-extern "C" {
-
-#include "crypto_scrypt.h"
-}
-
-namespace android {
-namespace vold {
-
-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
-constexpr int EXT4_AES_256_XTS_KEY_SIZE = 64;
-
-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 << std::endl;
-        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" << std::endl;
-        paramBuilder.Authorization(km::TAG_NO_AUTH_REQUIRED);
-    } else {
-        LOG(DEBUG) << "Auth token required for key" << std::endl;
-        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" << std::endl;
-            return false;
-        }
-        const hw_auth_token_t* at = reinterpret_cast<const hw_auth_token_t*>(auth.token.data());
-        paramBuilder.Authorization(km::TAG_USER_SECURE_ID, at->user_id);
-        paramBuilder.Authorization(km::TAG_USER_AUTH_TYPE, km::HardwareAuthenticatorType::PASSWORD);
-        paramBuilder.Authorization(km::TAG_AUTH_TIMEOUT, AUTH_TIMEOUT);
-    }
-    return keymaster.generateKey(paramBuilder, key);
-}
-
-bool generateWrappedKey(userid_t user_id, KeyType key_type,
-                                     KeyBuffer* key) {
-    Keymaster keymaster;
-    if (!keymaster) return false;
-    *key = KeyBuffer(EXT4_AES_256_XTS_KEY_SIZE);
-    std::string key_temp;
-    auto paramBuilder = km::AuthorizationSetBuilder()
-                               .AesEncryptionKey(AES_KEY_BYTES * 8)
-                               .GcmModeMinMacLen(GCM_MAC_BYTES * 8)
-                               .Authorization(km::TAG_USER_ID, user_id);
-    km::KeyParameter param1;
-    param1.tag = (km::Tag) (android::hardware::keymaster::V4_0::KM_TAG_FBE_ICE);
-    param1.f.boolValue = true;
-    paramBuilder.push_back(param1);
-    km::KeyParameter param2;
-    if ((key_type == KeyType::DE_USER) || (key_type == KeyType::DE_SYS)) {
-        param2.tag = (km::Tag) (android::hardware::keymaster::V4_0::KM_TAG_KEY_TYPE);
-        param2.f.integer = 0;
-    } else if (key_type == KeyType::CE_USER) {
-        param2.tag = (km::Tag) (android::hardware::keymaster::V4_0::KM_TAG_KEY_TYPE);
-        param2.f.integer = 1;
-    }
-    paramBuilder.push_back(param2);
-    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 getEphemeralWrappedKey(km::KeyFormat format, KeyBuffer& kmKey, KeyBuffer* key) {
-    std::string key_temp;
-    Keymaster keymaster;
-    if (!keymaster) return false;
-
-    //Export once, if upgrade needed, upgrade and export again
-    bool export_again = true;
-    while (export_again) {
-        export_again = false;
-        auto ret = keymaster.exportKey(format, kmKey, "!", "!", &key_temp);
-        if (ret == km::ErrorCode::OK) {
-            *key = KeyBuffer(key_temp.size());
-            memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
-            return true;
-        }
-        if (ret != km::ErrorCode::KEY_REQUIRES_UPGRADE) return false;
-        LOG(DEBUG) << "Upgrading key" << std::endl;
-        std::string kmKeyStr(reinterpret_cast<const char*>(kmKey.data()), kmKey.size());
-        std::string newKey;
-        if (!keymaster.upgradeKey(kmKeyStr, km::AuthorizationSet(), &newKey)) return false;
-        memcpy(reinterpret_cast<void*>(kmKey.data()), newKey.c_str(), kmKey.size());
-        LOG(INFO) << "Key upgraded" << std::endl;
-        export_again = true;
-    }
-    //Should never come here
-    return false;
-}
-
-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(DEBUG) << "Supplying auth token to Keymaster" << std::endl;
-        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 << std::endl;
-        return false;
-    }
-    return true;
-}
-
-static bool writeStringToFile(const std::string& payload, const std::string& filename) {
-	PLOG(ERROR) << __FUNCTION__ << " called for " << filename << " and being skipped\n";
-	return true;
-    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;
-}
-
-static bool readRandomBytesOrLog(size_t count, std::string* out) {
-    auto status = ReadRandomBytes(count, *out);
-    if (status != OK) {
-        LOG(ERROR) << "Random read failed with status: " << status << std::endl;
-        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 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) {
-    auto kmKeyPath = dir + "/" + kFn_keymaster_key_blob;
-    std::string kmKey;
-    if (!readFileToString(kmKeyPath, &kmKey)) return KeymasterOperation();
-    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 in memory only: " << dir << std::endl;
-        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 (rename(newKeyPath.c_str(), kmKeyPath.c_str()) != 0) {
-            PLOG(ERROR) << "Unable to move upgraded key to location: " << kmKeyPath;
-            return KeymasterOperation();
-        }
-        if (!keymaster.deleteKey(kmKey)) {
-            LOG(ERROR) << "Key deletion failed during upgrade, continuing anyway: " << dir;
-        }*/
-        kmKey = newKey;
-        LOG(INFO) << "Key upgraded in memory but not updated in folder: " << dir << std::endl;
-    }
-}
-
-static bool encryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
-                                    const km::AuthorizationSet& keyParams,
-                                    const km::HardwareAuthToken& authToken,
-                                    const KeyBuffer& message, std::string* ciphertext) {
-    km::AuthorizationSet opParams;
-    km::AuthorizationSet outParams;
-    auto opHandle =
-        begin(keymaster, dir, km::KeyPurpose::ENCRYPT, keyParams, opParams, authToken, &outParams);
-    if (!opHandle) return false;
-    auto nonceBlob = outParams.GetTagValue(km::TAG_NONCE);
-    if (!nonceBlob.isOk()) {
-        LOG(ERROR) << "GCM encryption but no nonce generated" << std::endl;
-        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) {
-    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);
-    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" << std::endl;
-            // 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 << std::endl;
-            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 << std::endl;
-            return false;
-        }
-    } else {
-        LOG(ERROR) << "Unknown stretching type: " << stretching << std::endl;
-        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() << std::endl;
-}
-
-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 << std::endl;
-        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 << std::endl;
-        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() << std::endl;
-        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 << std::endl;
-        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 << std::endl;
-        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 << std::endl;
-        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) != OK) {
-            LOG(ERROR) << "Random read failed" << std::endl;
-            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))
-            return false;
-    } else {
-        if (!encryptWithoutKeymaster(appId, key, &encryptedKey)) return false;
-    }
-    if (!writeStringToFile(encryptedKey, dir + "/" + kFn_encrypted_key)) 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 << std::endl;
-        return false;
-    }
-    if (pathExists(tmp_path)) {
-        LOG(DEBUG) << "Already exists, destroying: " << tmp_path << std::endl;
-        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 << std::endl;
-        return false;
-    }
-    LOG(DEBUG) << "Created key: " << key_path << std::endl;
-    return true;
-}
-
-bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, KeyBuffer* key) {
-    std::string version;
-    if (!readFileToString(dir + "/" + kFn_version, &version)) return false;
-    if (version != kCurrentVersion) {
-        LOG(ERROR) << "Version mismatch, expected " << kCurrentVersion << " got " << version << std::endl;
-        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))
-            return false;
-    } else {
-        if (!decryptWithoutKeymaster(appId, encryptedMessage, key)) return false;
-    }
-    return true;
-}
-
-static bool deleteKey(const std::string& dir) {
-	LOG(DEBUG) << "not deleting key in " << __FILE__ << std::endl;
-	return true;
-    std::string kmKey;
-    if (!readFileToString(dir + "/" + kFn_keymaster_key_blob, &kmKey)) return false;
-    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" << std::endl;
-        return false;
-    }
-    return true;
-}
-
-static bool recursiveDeleteKey(const std::string& dir) {
-	LOG(DEBUG) << "not recursively deleting key in " << __FILE__ << std::endl;
-	return true;
-    if (ForkExecvp(std::vector<std::string>{kRmPath, "-rf", dir}) != 0) {
-        LOG(ERROR) << "recursive delete failed" << std::endl;
-        return false;
-    }
-    return true;
-}
-
-bool destroyKey(const std::string& dir) {
-	LOG(DEBUG) << "not destroying key in " << __FILE__ << std::endl;
-	return true;
-    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" << std::endl;
-        success = false;
-    }
-    success &= recursiveDeleteKey(dir);
-    return success;
-}
-
-}  // namespace vold
-}  // namespace android
diff --git a/crypto/ext4crypt/KeyStorage4.h b/crypto/ext4crypt/KeyStorage4.h
deleted file mode 100644
index f74865f..0000000
--- a/crypto/ext4crypt/KeyStorage4.h
+++ /dev/null
@@ -1,86 +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_TWRP_KEYSTORAGE_H
-#define ANDROID_TWRP_KEYSTORAGE_H
-
-#include "Keymaster4.h"
-#include "KeyBuffer.h"
-#include <ext4_utils/ext4_crypt.h>
-
-#include <string>
-
-namespace android {
-namespace vold {
-
-namespace km = ::android::hardware::keymaster::V4_0;
-
-// 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(std::string t, std::string s) : token{t}, secret{s} {};
-
-    bool usesKeymaster() const { return !token.empty() || secret.empty(); };
-
-    const std::string token;
-    const std::string secret;
-};
-
-enum class KeyType {
-    DE_SYS,
-    DE_USER,
-    CE_USER
-};
-
-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);
-
-// 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);
-
-bool generateWrappedKey(userid_t user_id, KeyType key_type, KeyBuffer* key);
-bool getEphemeralWrappedKey(km::KeyFormat format, KeyBuffer& kmKey, KeyBuffer* key);
-}  // namespace vold
-}  // namespace android
-
-#endif
diff --git a/crypto/ext4crypt/KeyUtil.cpp b/crypto/ext4crypt/KeyUtil.cpp
deleted file mode 100644
index 3dc0500..0000000
--- a/crypto/ext4crypt/KeyUtil.cpp
+++ /dev/null
@@ -1,241 +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 <openssl/sha.h>
-
-#include <android-base/file.h>
-//#include <android-base/logging.h>
-#include <keyutils.h>
-
-#include "KeyStorage4.h"
-#include "Ext4CryptPie.h"
-#include "Utils.h"
-
-#include <iostream>
-#define LOG(x) std::cout
-#define PLOG(x) std::cout
-#include <sys/types.h>
-#include <unistd.h>
-
-#define MAX_USER_ID 0xFFFFFFFF
-
-using android::hardware::keymaster::V4_0::KeyFormat;
-using android::vold::KeyType;
-
-namespace android {
-namespace vold {
-
-// ext4enc:TODO get this const from somewhere good
-const int EXT4_KEY_DESCRIPTOR_SIZE = 8;
-
-// ext4enc:TODO Include structure from somewhere sensible
-// MUST be in sync with ext4_crypto.c in kernel
-constexpr int EXT4_ENCRYPTION_MODE_AES_256_XTS = 1;
-constexpr int EXT4_AES_256_XTS_KEY_SIZE = 64;
-constexpr int EXT4_MAX_KEY_SIZE = 64;
-struct ext4_encryption_key {
-    uint32_t mode;
-    char raw[EXT4_MAX_KEY_SIZE];
-    uint32_t size;
-};
-
-bool randomKey(KeyBuffer* key) {
-    *key = KeyBuffer(EXT4_AES_256_XTS_KEY_SIZE);
-    if (ReadRandomBytes(key->size(), key->data()) != 0) {
-        // TODO status_t plays badly with PLOG, fix it.
-        LOG(ERROR) << "Random read failed" << std::endl;
-        return false;
-    }
-    return true;
-}
-
-// Get raw keyref - used to make keyname and to pass to ioctl
-static std::string generateKeyRef(const char* 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(EXT4_KEY_DESCRIPTOR_SIZE <= SHA512_DIGEST_LENGTH,
-                  "Hash too short for descriptor");
-    return std::string((char*)key_ref2, EXT4_KEY_DESCRIPTOR_SIZE);
-}
-
-static bool fillKey(const KeyBuffer& key, ext4_encryption_key* ext4_key) {
-    if (key.size() != EXT4_AES_256_XTS_KEY_SIZE) {
-        LOG(ERROR) << "Wrong size key " << key.size();
-        return false;
-    }
-    static_assert(EXT4_AES_256_XTS_KEY_SIZE <= sizeof(ext4_key->raw), "Key too long!");
-    ext4_key->mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
-    ext4_key->size = key.size();
-    memset(ext4_key->raw, 0, sizeof(ext4_key->raw));
-    memcpy(ext4_key->raw, key.data(), key.size());
-    return true;
-}
-
-static char const* const NAME_PREFIXES[] = {
-    "ext4",
-    "f2fs",
-    "fscrypt",
-    nullptr
-};
-
-static std::string keyname(const std::string& prefix, const std::string& raw_ref) {
-    std::ostringstream o;
-    o << prefix << ":";
-    for (unsigned char i : raw_ref) {
-        o << std::hex << std::setw(2) << std::setfill('0') << (int)i;
-    }
-    return o.str();
-}
-
-// Get the keyring we store all keys in
-static bool e4cryptKeyring(key_serial_t* device_keyring) {
-    *device_keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring", "e4crypt", 0);
-    if (*device_keyring == -1) {
-        PLOG(ERROR) << "Unable to find device keyring" << std::endl;
-        return false;
-    }
-    return true;
-}
-
-// Install password into global keyring
-// Return raw key reference for use in policy
-bool installKey(const KeyBuffer& key, std::string* raw_ref) {
-    // Place ext4_encryption_key into automatically zeroing buffer.
-    KeyBuffer ext4KeyBuffer(sizeof(ext4_encryption_key));
-    ext4_encryption_key &ext4_key = *reinterpret_cast<ext4_encryption_key*>(ext4KeyBuffer.data());
-
-    if (!fillKey(key, &ext4_key)) return false;
-    if (is_wrapped_key_supported()) {
-        /* 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. */
-        *raw_ref = generateKeyRef(ext4_key.raw, (ext4_key.size)/2);
-    } else {
-        *raw_ref = generateKeyRef(ext4_key.raw, ext4_key.size);
-    }
-    key_serial_t device_keyring;
-    if (!e4cryptKeyring(&device_keyring)) return false;
-    for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
-        auto ref = keyname(*name_prefix, *raw_ref);
-        key_serial_t key_id =
-            add_key("logon", ref.c_str(), (void*)&ext4_key, sizeof(ext4_key), device_keyring);
-        if (key_id == -1) {
-            PLOG(ERROR) << "Failed to insert key into keyring " << device_keyring << std::endl;
-            return false;
-        }
-        LOG(DEBUG) << "Added key " << key_id << " (" << ref << ") to keyring " << device_keyring
-                   << " in process " << getpid() << std::endl;
-    }
-    return true;
-}
-
-bool evictKey(const std::string& raw_ref) {
-	LOG(ERROR) << "not actually evicting key\n";
-	return true;
-    key_serial_t device_keyring;
-    if (!e4cryptKeyring(&device_keyring)) return false;
-    bool success = true;
-    for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
-        auto ref = keyname(*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(DEBUG) << "Unlinked key with serial " << key_serial << " ref " << ref;
-        }
-    }
-    return success;
-}
-
-bool retrieveAndInstallKey(bool create_if_absent, const KeyAuthentication& key_authentication,
-                           const std::string& key_path, const std::string& tmp_path,
-                           std::string* key_ref, bool wrapped_key_supported) {
-    KeyBuffer key;
-    if (pathExists(key_path)) {
-        LOG(DEBUG) << "Key exists, using: " << key_path << std::endl;
-        if (!retrieveKey(key_path, key_authentication, &key)) return false;
-    } else {
-        if (!create_if_absent) {
-           LOG(ERROR) << "No key found in " << key_path << std::endl;
-           return false;
-        }
-        LOG(INFO) << "Creating new key in " << key_path << std::endl;
-        if (wrapped_key_supported) {
-            if(!generateWrappedKey(MAX_USER_ID, KeyType::DE_SYS, &key)) return false;
-        } else {
-            if (!randomKey(&key)) return false;
-        }
-        if (!storeKeyAtomically(key_path, tmp_path, key_authentication, key)) return false;
-    }
-
-    if (wrapped_key_supported) {
-        KeyBuffer ephemeral_wrapped_key;
-        if (!getEphemeralWrappedKey(KeyFormat::RAW, key, &ephemeral_wrapped_key)) {
-            LOG(ERROR) << "Failed to export key in retrieveAndInstallKey";
-            return false;
-        }
-        key = std::move(ephemeral_wrapped_key);
-    }
-
-    if (!installKey(key, key_ref)) {
-        LOG(ERROR) << "Failed to install key in " << key_path << std::endl;
-        return false;
-    }
-    return true;
-}
-
-bool retrieveKey(bool create_if_absent, const std::string& key_path,
-                 const std::string& tmp_path, KeyBuffer* key) {
-    if (pathExists(key_path)) {
-        LOG(DEBUG) << "Key exists, using: " << key_path << std::endl;
-        if (!retrieveKey(key_path, kEmptyAuthentication, key)) return false;
-    } else {
-        if (!create_if_absent) {
-           LOG(ERROR) << "No key found in " << key_path << std::endl;
-           return false;
-        }
-        LOG(INFO) << "Creating new key in " << key_path << std::endl;
-        if (!randomKey(key)) return false;
-        if (!storeKeyAtomically(key_path, tmp_path,
-                kEmptyAuthentication, *key)) return false;
-    }
-    return true;
-}
-
-}  // namespace vold
-}  // namespace android
diff --git a/crypto/ext4crypt/KeyUtil.h b/crypto/ext4crypt/KeyUtil.h
deleted file mode 100644
index 46a3124..0000000
--- a/crypto/ext4crypt/KeyUtil.h
+++ /dev/null
@@ -1,42 +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 "KeyStorage4.h"
-#include "Keymaster4.h"
-
-#include <string>
-#include <memory>
-
-namespace android {
-namespace vold {
-
-bool randomKey(KeyBuffer* key);
-bool installKey(const KeyBuffer& key, std::string* raw_ref);
-bool evictKey(const std::string& raw_ref);
-bool retrieveAndInstallKey(bool create_if_absent, const KeyAuthentication& key_authentication,
-                           const std::string& key_path, const std::string& tmp_path,
-                           std::string* key_ref, bool wrapped_key_supported);
-bool retrieveKey(bool create_if_absent, const std::string& key_path,
-                 const std::string& tmp_path, KeyBuffer* key);
-
-}  // namespace vold
-}  // namespace android
-
-#endif
diff --git a/crypto/ext4crypt/Keymaster.cpp b/crypto/ext4crypt/Keymaster.cpp
deleted file mode 100644
index 3c21aa2..0000000
--- a/crypto/ext4crypt/Keymaster.cpp
+++ /dev/null
@@ -1,254 +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 <hardware/hardware.h>
-#include <hardware/keymaster1.h>
-#include <hardware/keymaster2.h>
-
-#include <iostream>
-#define ERROR 1
-#define LOG(x) std::cout
-
-namespace android {
-namespace vold {
-
-class IKeymasterDevice {
-  public:
-    IKeymasterDevice() {}
-    virtual ~IKeymasterDevice() {}
-    /*virtual keymaster_error_t generate_key(const keymaster_key_param_set_t* params,
-                                           keymaster_key_blob_t* key_blob) const = 0;*/
-    virtual keymaster_error_t delete_key(const keymaster_key_blob_t* key) const = 0;
-    virtual keymaster_error_t begin(keymaster_purpose_t purpose, const keymaster_key_blob_t* key,
-                                    const keymaster_key_param_set_t* in_params,
-                                    keymaster_key_param_set_t* out_params,
-                                    keymaster_operation_handle_t* operation_handle) const = 0;
-    virtual keymaster_error_t update(keymaster_operation_handle_t operation_handle,
-                                     const keymaster_key_param_set_t* in_params,
-                                     const keymaster_blob_t* input, size_t* input_consumed,
-                                     keymaster_key_param_set_t* out_params,
-                                     keymaster_blob_t* output) const = 0;
-    virtual keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
-                                     const keymaster_key_param_set_t* in_params,
-                                     const keymaster_blob_t* signature,
-                                     keymaster_key_param_set_t* out_params,
-                                     keymaster_blob_t* output) const = 0;
-    virtual keymaster_error_t abort(keymaster_operation_handle_t operation_handle) const = 0;
-
-  protected:
-    DISALLOW_COPY_AND_ASSIGN(IKeymasterDevice);
-};
-
-template <typename T> class KeymasterDevice : public IKeymasterDevice {
-  public:
-    KeymasterDevice(T* d) : mDevice{d} {}
-    /*keymaster_error_t generate_key(const keymaster_key_param_set_t* params,
-                                   keymaster_key_blob_t* key_blob) const override final {
-        return mDevice->generate_key(mDevice, params, key_blob, nullptr);
-    }*/
-    keymaster_error_t delete_key(const keymaster_key_blob_t* key) const override final {
-        if (mDevice->delete_key == nullptr) return KM_ERROR_OK;
-        return mDevice->delete_key(mDevice, key);
-    }
-    keymaster_error_t begin(keymaster_purpose_t purpose, const keymaster_key_blob_t* key,
-                            const keymaster_key_param_set_t* in_params,
-                            keymaster_key_param_set_t* out_params,
-                            keymaster_operation_handle_t* operation_handle) const override final {
-        return mDevice->begin(mDevice, purpose, key, in_params, out_params, operation_handle);
-    }
-    keymaster_error_t update(keymaster_operation_handle_t operation_handle,
-                             const keymaster_key_param_set_t* in_params,
-                             const keymaster_blob_t* input, size_t* input_consumed,
-                             keymaster_key_param_set_t* out_params,
-                             keymaster_blob_t* output) const override final {
-        return mDevice->update(mDevice, operation_handle, in_params, input, input_consumed,
-                               out_params, output);
-    }
-    keymaster_error_t abort(keymaster_operation_handle_t operation_handle) const override final {
-        return mDevice->abort(mDevice, operation_handle);
-    }
-
-  protected:
-    T* const mDevice;
-};
-
-class Keymaster1Device : public KeymasterDevice<keymaster1_device_t> {
-  public:
-    Keymaster1Device(keymaster1_device_t* d) : KeymasterDevice<keymaster1_device_t>{d} {}
-    ~Keymaster1Device() override final { keymaster1_close(mDevice); }
-    keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
-                             const keymaster_key_param_set_t* in_params,
-                             const keymaster_blob_t* signature,
-                             keymaster_key_param_set_t* out_params,
-                             keymaster_blob_t* output) const override final {
-        return mDevice->finish(mDevice, operation_handle, in_params, signature, out_params, output);
-    }
-};
-
-class Keymaster2Device : public KeymasterDevice<keymaster2_device_t> {
-  public:
-    Keymaster2Device(keymaster2_device_t* d) : KeymasterDevice<keymaster2_device_t>{d} {}
-    ~Keymaster2Device() override final { keymaster2_close(mDevice); }
-    keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
-                             const keymaster_key_param_set_t* in_params,
-                             const keymaster_blob_t* signature,
-                             keymaster_key_param_set_t* out_params,
-                             keymaster_blob_t* output) const override final {
-        return mDevice->finish(mDevice, operation_handle, in_params, nullptr, signature, out_params,
-                               output);
-    }
-};
-
-KeymasterOperation::~KeymasterOperation() {
-    if (mDevice) mDevice->abort(mOpHandle);
-}
-
-bool KeymasterOperation::updateCompletely(const std::string& input, std::string* output) {
-    output->clear();
-    auto it = input.begin();
-    while (it != input.end()) {
-        size_t toRead = static_cast<size_t>(input.end() - it);
-        keymaster_blob_t inputBlob{reinterpret_cast<const uint8_t*>(&*it), toRead};
-        keymaster_blob_t outputBlob;
-        size_t inputConsumed;
-        auto error =
-            mDevice->update(mOpHandle, nullptr, &inputBlob, &inputConsumed, nullptr, &outputBlob);
-        if (error != KM_ERROR_OK) {
-            LOG(ERROR) << "update failed, code " << error;
-            mDevice = nullptr;
-            return false;
-        }
-        output->append(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
-        free(const_cast<uint8_t*>(outputBlob.data));
-        if (inputConsumed > toRead) {
-            LOG(ERROR) << "update reported too much input consumed";
-            mDevice = nullptr;
-            return false;
-        }
-        it += inputConsumed;
-    }
-    return true;
-}
-
-bool KeymasterOperation::finish() {
-    auto error = mDevice->finish(mOpHandle, nullptr, nullptr, nullptr, nullptr);
-    mDevice = nullptr;
-    if (error != KM_ERROR_OK) {
-        LOG(ERROR) << "finish failed, code " << error;
-        return false;
-    }
-    return true;
-}
-
-bool KeymasterOperation::finishWithOutput(std::string* output) {
-    keymaster_blob_t outputBlob;
-    auto error = mDevice->finish(mOpHandle, nullptr, nullptr, nullptr, &outputBlob);
-    mDevice = nullptr;
-    if (error != KM_ERROR_OK) {
-        LOG(ERROR) << "finish failed, code " << error;
-        return false;
-    }
-    output->assign(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
-    free(const_cast<uint8_t*>(outputBlob.data));
-    return true;
-}
-
-Keymaster::Keymaster() {
-    mDevice = nullptr;
-    const hw_module_t* module;
-    int ret = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &module);
-    if (ret != 0) {
-        LOG(ERROR) << "hw_get_module_by_class returned " << ret;
-        return;
-    }
-    if (module->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
-        keymaster1_device_t* device;
-        ret = keymaster1_open(module, &device);
-        if (ret != 0) {
-            LOG(ERROR) << "keymaster1_open returned " << ret;
-            return;
-        }
-        mDevice = std::make_shared<Keymaster1Device>(device);
-    } else if (module->module_api_version == KEYMASTER_MODULE_API_VERSION_2_0) {
-        keymaster2_device_t* device;
-        ret = keymaster2_open(module, &device);
-        if (ret != 0) {
-            LOG(ERROR) << "keymaster2_open returned " << ret;
-            return;
-        }
-        mDevice = std::make_shared<Keymaster2Device>(device);
-    } else {
-        LOG(ERROR) << "module_api_version is " << module->module_api_version;
-        return;
-    }
-}
-
-/*bool Keymaster::generateKey(const keymaster::AuthorizationSet& inParams, std::string* key) {
-    keymaster_key_blob_t keyBlob;
-    auto error = mDevice->generate_key(&inParams, &keyBlob);
-    if (error != KM_ERROR_OK) {
-        LOG(ERROR) << "generate_key failed, code " << error;
-        return false;
-    }
-    key->assign(reinterpret_cast<const char*>(keyBlob.key_material), keyBlob.key_material_size);
-    free(const_cast<uint8_t*>(keyBlob.key_material));
-    return true;
-}*/
-
-bool Keymaster::deleteKey(const std::string& key) {
-    keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
-    auto error = mDevice->delete_key(&keyBlob);
-    if (error != KM_ERROR_OK) {
-        LOG(ERROR) << "delete_key failed, code " << error;
-        return false;
-    }
-    return true;
-}
-
-KeymasterOperation Keymaster::begin(keymaster_purpose_t purpose, const std::string& key,
-                                    const keymaster::AuthorizationSet& inParams,
-                                    keymaster::AuthorizationSet* outParams) {
-    keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
-    keymaster_operation_handle_t mOpHandle;
-    keymaster_key_param_set_t outParams_set;
-    auto error = mDevice->begin(purpose, &keyBlob, &inParams, &outParams_set, &mOpHandle);
-    if (error != KM_ERROR_OK) {
-        LOG(ERROR) << "begin failed, code " << error;
-        return KeymasterOperation(nullptr, mOpHandle);
-    }
-    outParams->Clear();
-    outParams->push_back(outParams_set);
-    keymaster_free_param_set(&outParams_set);
-    return KeymasterOperation(mDevice, mOpHandle);
-}
-
-KeymasterOperation Keymaster::begin(keymaster_purpose_t purpose, const std::string& key,
-                                    const keymaster::AuthorizationSet& inParams) {
-    keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
-    keymaster_operation_handle_t mOpHandle;
-    auto error = mDevice->begin(purpose, &keyBlob, &inParams, nullptr, &mOpHandle);
-    if (error != KM_ERROR_OK) {
-        LOG(ERROR) << "begin failed, code " << error;
-        return KeymasterOperation(nullptr, mOpHandle);
-    }
-    return KeymasterOperation(mDevice, mOpHandle);
-}
-
-}  // namespace vold
-}  // namespace android
diff --git a/crypto/ext4crypt/Keymaster.h b/crypto/ext4crypt/Keymaster.h
deleted file mode 100644
index bd3f219..0000000
--- a/crypto/ext4crypt/Keymaster.h
+++ /dev/null
@@ -1,111 +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 <memory>
-#include <string>
-#include <utility>
-
-#include <keymaster/authorization_set.h>
-#include "Utils.h"
-
-namespace android {
-namespace vold {
-
-using namespace keymaster;
-
-// C++ wrappers to the Keymaster C interface.
-// This is tailored to the needs of KeyStorage, but could be extended to be
-// a more general interface.
-
-// Class that wraps a keymaster1_device_t or keymaster2_device_t and provides methods
-// they have in common. Also closes the device on destruction.
-class IKeymasterDevice;
-
-// Wrapper for a keymaster_operation_handle_t 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() { return mDevice != nullptr; }
-    // Call "update" repeatedly until all of the input is consumed, and
-    // concatenate the output. Return true on success.
-    bool updateCompletely(const std::string& input, std::string* output);
-    // Finish; pass nullptr for the "output" param.
-    bool finish();
-    // Finish and write the output to this string.
-    bool finishWithOutput(std::string* output);
-    // Move constructor
-    KeymasterOperation(KeymasterOperation&& rhs) {
-        mOpHandle = std::move(rhs.mOpHandle);
-        mDevice = std::move(rhs.mDevice);
-    }
-
-  private:
-    KeymasterOperation(std::shared_ptr<IKeymasterDevice> d, keymaster_operation_handle_t h)
-        : mDevice{d}, mOpHandle{h} {}
-    std::shared_ptr<IKeymasterDevice> mDevice;
-    keymaster_operation_handle_t mOpHandle;
-    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 != nullptr; }
-    // Generate a key in the keymaster from the given params.
-    //bool generateKey(const AuthorizationSet& inParams, std::string* key);
-    // If the keymaster supports it, permanently delete a key.
-    bool deleteKey(const std::string& key);
-    // Begin a new cryptographic operation, collecting output parameters.
-    KeymasterOperation begin(keymaster_purpose_t purpose, const std::string& key,
-                             const AuthorizationSet& inParams, AuthorizationSet* outParams);
-    // Begin a new cryptographic operation; don't collect output parameters.
-    KeymasterOperation begin(keymaster_purpose_t purpose, const std::string& key,
-                             const AuthorizationSet& inParams);
-
-  private:
-    std::shared_ptr<IKeymasterDevice> mDevice;
-    DISALLOW_COPY_AND_ASSIGN(Keymaster);
-};
-
-template <keymaster_tag_t Tag>
-inline AuthorizationSetBuilder& addStringParam(AuthorizationSetBuilder&& params,
-                                               TypedTag<KM_BYTES, Tag> tag,
-                                               const std::string& val) {
-    return params.Authorization(tag, val.data(), val.size());
-}
-
-template <keymaster_tag_t Tag>
-inline void addStringParam(AuthorizationSetBuilder* params, TypedTag<KM_BYTES, Tag> tag,
-                           const std::string& val) {
-    params->Authorization(tag, val.data(), val.size());
-}
-
-}  // namespace vold
-}  // namespace android
-
-#endif
diff --git a/crypto/ext4crypt/Keymaster3.cpp b/crypto/ext4crypt/Keymaster3.cpp
deleted file mode 100644
index 7862044..0000000
--- a/crypto/ext4crypt/Keymaster3.cpp
+++ /dev/null
@@ -1,348 +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 "Keymaster3.h"
-
-//#include <android-base/logging.h>
-#include <keystore/keymaster_tags.h>
-#include <keystore/authorization_set.h>
-#include <keystore/keystore_hidl_support.h>
-
-#include <iostream>
-#define ERROR 1
-#define LOG(x) std::cout
-
-using namespace ::keystore;
-using android::hardware::hidl_string;
-
-namespace android {
-namespace vold {
-
-KeymasterOperation::~KeymasterOperation() {
-    if (mDevice.get()) mDevice->abort(mOpHandle);
-}
-
-bool KeymasterOperation::updateCompletely(const std::string& input, std::string* output) {
-    if (output)
-        output->clear();
-    auto it = input.begin();
-    uint32_t inputConsumed;
-
-    ErrorCode km_error;
-    auto hidlCB = [&] (ErrorCode ret, uint32_t _inputConsumed,
-            const hidl_vec<KeyParameter>& /*ignored*/, const hidl_vec<uint8_t>& _output) {
-        km_error = ret;
-        if (km_error != ErrorCode::OK) return;
-        inputConsumed = _inputConsumed;
-        if (output)
-            output->append(reinterpret_cast<const char*>(&_output[0]), _output.size());
-    };
-
-    while (it != input.end()) {
-        size_t toRead = static_cast<size_t>(input.end() - it);
-        auto inputBlob = blob2hidlVec(reinterpret_cast<const uint8_t*>(&*it), toRead);
-        auto error = mDevice->update(mOpHandle, hidl_vec<KeyParameter>(), inputBlob, hidlCB);
-        if (!error.isOk()) {
-            LOG(ERROR) << "update failed: " << error.description();
-            mDevice = nullptr;
-            return false;
-        }
-        if (km_error != ErrorCode::OK) {
-            LOG(ERROR) << "update failed, code " << int32_t(km_error);
-            mDevice = nullptr;
-            return false;
-        }
-        if (inputConsumed > toRead) {
-            LOG(ERROR) << "update reported too much input consumed";
-            mDevice = nullptr;
-            return false;
-        }
-        it += inputConsumed;
-    }
-    return true;
-}
-
-bool KeymasterOperation::finish(std::string* output) {
-    ErrorCode km_error;
-    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<KeyParameter>& /*ignored*/,
-            const hidl_vec<uint8_t>& _output) {
-        km_error = ret;
-        if (km_error != ErrorCode::OK) return;
-        if (output)
-            output->assign(reinterpret_cast<const char*>(&_output[0]), _output.size());
-    };
-    auto error = mDevice->finish(mOpHandle, hidl_vec<KeyParameter>(), hidl_vec<uint8_t>(),
-            hidl_vec<uint8_t>(), hidlCb);
-    mDevice = nullptr;
-    if (!error.isOk()) {
-        LOG(ERROR) << "finish failed: " << error.description();
-        return false;
-    }
-    if (km_error != ErrorCode::OK) {
-        LOG(ERROR) << "finish failed, code " << int32_t(km_error);
-        return false;
-    }
-    return true;
-}
-
-Keymaster::Keymaster() {
-    mDevice = ::android::hardware::keymaster::V3_0::IKeymasterDevice::getService();
-}
-
-/*bool Keymaster::generateKey(const AuthorizationSet& inParams, std::string* key) {
-    ErrorCode km_error;
-    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
-            const KeyCharacteristics& /*ignored* /) {
-        km_error = ret;
-        if (km_error != 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 != ErrorCode::OK) {
-        LOG(ERROR) << "generate_key failed, code " << int32_t(km_error);
-        return false;
-    }
-    return true;
-}*/
-
-bool Keymaster::deleteKey(const std::string& key) {
-	LOG(ERROR) << "NOT deleting key in TWRP";
-	return false;
-    /*auto keyBlob = blob2hidlVec(key);
-    auto error = mDevice->deleteKey(keyBlob);
-    if (!error.isOk()) {
-        LOG(ERROR) << "delete_key failed: " << error.description();
-        return false;
-    }
-    if (ErrorCode(error) != ErrorCode::OK) {
-        LOG(ERROR) << "delete_key failed, code " << uint32_t(ErrorCode(error));
-        return false;
-    }
-    return true;*/
-}
-
-bool Keymaster::upgradeKey(const std::string& oldKey, const AuthorizationSet& inParams,
-                           std::string* newKey) {
-    auto oldKeyBlob = blob2hidlVec(oldKey);
-    ErrorCode km_error;
-    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
-        km_error = ret;
-        if (km_error != 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 != ErrorCode::OK) {
-        LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error);
-        return false;
-    }
-    return true;
-}
-
-KeymasterOperation Keymaster::begin(KeyPurpose purpose, const std::string& key,
-                                    const AuthorizationSet& inParams,
-                                    AuthorizationSet* outParams) {
-    auto keyBlob = blob2hidlVec(key);
-    uint64_t mOpHandle;
-    ErrorCode km_error;
-
-    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<KeyParameter>& _outParams,
-            uint64_t operationHandle) {
-        km_error = ret;
-        if (km_error != ErrorCode::OK) return;
-        if (outParams)
-            *outParams = _outParams;
-        mOpHandle = operationHandle;
-    };
-
-    auto error = mDevice->begin(purpose, keyBlob, inParams.hidl_data(), hidlCb);
-    if (!error.isOk()) {
-        LOG(ERROR) << "begin failed: " << error.description();
-        return KeymasterOperation(ErrorCode::UNKNOWN_ERROR);
-    }
-    if (km_error != ErrorCode::OK) {
-        LOG(ERROR) << "begin failed, code " << int32_t(km_error);
-        return KeymasterOperation(km_error);
-    }
-    return KeymasterOperation(mDevice, mOpHandle);
-}
-bool Keymaster::isSecure() {
-    bool _isSecure = false;
-    auto rc = mDevice->getHardwareFeatures(
-            [&] (bool isSecure, bool, bool, bool, bool, const hidl_string&, const hidl_string&) {
-                _isSecure = isSecure; });
-    return rc.isOk() && _isSecure;
-}
-
-}  // namespace vold
-}  // namespace android
-
-using namespace ::android::vold;
-
-/*
-int keymaster_compatibility_cryptfs_scrypt() {
-    Keymaster dev;
-    if (!dev) {
-        LOG(ERROR) << "Failed to initiate keymaster session";
-        return -1;
-    }
-    return dev.isSecure();
-}
-*/
-
-/*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)
-{
-    Keymaster dev;
-    std::string key;
-    if (!dev) {
-        LOG(ERROR) << "Failed to initiate keymaster session";
-        return -1;
-    }
-    if (!key_buffer || !key_out_size) {
-        LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
-        return -1;
-    }
-    if (key_out_size) {
-        *key_out_size = 0;
-    }
-
-    auto paramBuilder = AuthorizationSetBuilder()
-                            .Authorization(TAG_ALGORITHM, Algorithm::RSA)
-                            .Authorization(TAG_KEY_SIZE, rsa_key_size)
-                            .Authorization(TAG_RSA_PUBLIC_EXPONENT, rsa_exponent)
-                            .Authorization(TAG_PURPOSE, KeyPurpose::SIGN)
-                            .Authorization(TAG_PADDING, PaddingMode::NONE)
-                            .Authorization(TAG_DIGEST, Digest::NONE)
-                            .Authorization(TAG_BLOB_USAGE_REQUIREMENTS,
-                                    KeyBlobUsageRequirements::STANDALONE)
-                            .Authorization(TAG_NO_AUTH_REQUIRED)
-                            .Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, ratelimit);
-
-    if (!dev.generateKey(paramBuilder, &key)) {
-        return -1;
-    }
-
-    if (key_out_size) {
-        *key_out_size = key.size();
-    }
-
-    if (key_buffer_size < key.size()) {
-        return -1;
-    }
-
-    std::copy(key.data(), key.data() + key.size(), key_buffer);
-    return 0;
-}*/
-
-int 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,
-                                             uint8_t* key_buffer,
-                                             uint32_t key_buffer_size,
-                                             uint32_t* key_out_size)
-{
-    Keymaster dev;
-    if (!dev) {
-        LOG(ERROR) << "Failed to initiate keymaster session";
-        return -1;
-    }
-    if (!key_blob || !object || !signature_buffer || !signature_buffer_size) {
-        LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
-        return -1;
-    }
-
-    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 = AuthorizationSetBuilder()
-                            .Authorization(TAG_PADDING, PaddingMode::NONE)
-                            .Authorization(TAG_DIGEST, Digest::NONE);
-
-    while (true) {
-        op = dev.begin(KeyPurpose::SIGN, key, paramBuilder, &outParams);
-        if (op.errorCode() == ErrorCode::KEY_RATE_LIMIT_EXCEEDED) {
-            sleep(ratelimit);
-            continue;
-        } else if (op.errorCode() == ErrorCode::KEY_REQUIRES_UPGRADE) {
-            std::string newKey;
-            bool ret = dev.upgradeKey(key, paramBuilder, &newKey);
-            if(ret == false) {
-                LOG(ERROR) << "Error upgradeKey: ";
-                return -1;
-            }
-
-            if (key_out_size) {
-                *key_out_size = newKey.size();
-            }
-
-            if (key_buffer_size < newKey.size()) {
-                LOG(ERROR) << "key buffer size is too small";
-                return -1;
-            }
-
-            std::copy(newKey.data(), newKey.data() + newKey.size(), key_buffer);
-            key = newKey;
-        } else break;
-    }
-
-    if (op.errorCode() != ErrorCode::OK) {
-        LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode());
-        return -1;
-    }
-
-    if (!op.updateCompletely(input, &output)) {
-        LOG(ERROR) << "Error sending data to keymaster signature transaction: "
-                   << uint32_t(op.errorCode());
-        return -1;
-    }
-
-    if (!op.finish(&output)) {
-        LOG(ERROR) << "Error finalizing keymaster signature transaction: " << int32_t(op.errorCode());
-        return -1;
-    }
-
-    *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size()));
-    if (*signature_buffer == nullptr) {
-        LOG(ERROR) << "Error allocation buffer for keymaster signature";
-        return -1;
-    }
-    *signature_buffer_size = output.size();
-    std::copy(output.data(), output.data() + output.size(), *signature_buffer);
-    return 0;
-}
diff --git a/crypto/ext4crypt/Keymaster3.h b/crypto/ext4crypt/Keymaster3.h
deleted file mode 100644
index cb5b644..0000000
--- a/crypto/ext4crypt/Keymaster3.h
+++ /dev/null
@@ -1,151 +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
-
-#ifdef __cplusplus
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <keystore/authorization_set.h>
-#include "Utils.h"
-
-namespace android {
-namespace vold {
-using ::android::hardware::keymaster::V3_0::IKeymasterDevice;
-using ::keystore::ErrorCode;
-using ::keystore::KeyPurpose;
-using ::keystore::AuthorizationSet;
-
-// 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() { return mError == ErrorCode::OK; }
-    ErrorCode errorCode() { return mError; }
-    // Call "update" repeatedly until all of the input is consumed, and
-    // concatenate the output. Return true on success.
-    bool updateCompletely(const std::string& input, std::string* output);
-    // Finish and write the output to this string, unless pointer is null.
-    bool finish(std::string* output);
-    // Move constructor
-    KeymasterOperation(KeymasterOperation&& rhs) {
-        mDevice = std::move(rhs.mDevice);
-        mOpHandle = std::move(rhs.mOpHandle);
-        mError = std::move(rhs.mError);
-    }
-    // Construct an object in an error state for error returns
-    KeymasterOperation()
-        : mDevice{nullptr}, mOpHandle{0},
-          mError {ErrorCode::UNKNOWN_ERROR} {}
-    // Move Assignment
-    KeymasterOperation& operator= (KeymasterOperation&& rhs) {
-        mDevice = std::move(rhs.mDevice);
-        mOpHandle = std::move(rhs.mOpHandle);
-        mError = std::move(rhs.mError);
-        rhs.mError = ErrorCode::UNKNOWN_ERROR;
-        rhs.mOpHandle = 0;
-        return *this;
-    }
-
-  private:
-    KeymasterOperation(const sp<IKeymasterDevice>& d, uint64_t h)
-        : mDevice{d}, mOpHandle{h}, mError {ErrorCode::OK} {}
-    KeymasterOperation(ErrorCode error)
-        : mDevice{nullptr}, mOpHandle{0},
-          mError {error} {}
-    sp<IKeymasterDevice> mDevice;
-    uint64_t mOpHandle;
-    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 AuthorizationSet& inParams, 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 AuthorizationSet& inParams,
-                    std::string* newKey);
-    // Begin a new cryptographic operation, collecting output parameters if pointer is non-null
-    KeymasterOperation begin(KeyPurpose purpose, const std::string& key,
-                             const AuthorizationSet& inParams, AuthorizationSet* outParams);
-    bool isSecure();
-
-  private:
-    sp<hardware::keymaster::V3_0::IKeymasterDevice> mDevice;
-    DISALLOW_COPY_AND_ASSIGN(Keymaster);
-};
-
-}  // namespace vold
-}  // namespace android
-
-#endif // __cplusplus
-
-
-/*
- * 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.
- */
-__BEGIN_DECLS
-
-//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_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,
-                                             uint8_t* key_buffer,
-                                             uint32_t key_buffer_size,
-                                             uint32_t* key_out_size);
-
-__END_DECLS
-
-#endif
diff --git a/crypto/ext4crypt/Keymaster4.cpp b/crypto/ext4crypt/Keymaster4.cpp
deleted file mode 100644
index 6507bb1..0000000
--- a/crypto/ext4crypt/Keymaster4.cpp
+++ /dev/null
@@ -1,382 +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 "Keymaster4.h"
-
-//#include <android-base/logging.h>
-#include <keymasterV4_0/authorization_set.h>
-#include <keymasterV4_0/keymaster_utils.h>
-
-#include <iostream>
-#define LOG(x) std::cout
-#define PLOG(x) std::cout
-
-namespace android {
-namespace vold {
-
-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() << std::endl;
-            mDevice = nullptr;
-            return false;
-        }
-        if (km_error != km::ErrorCode::OK) {
-            LOG(ERROR) << "update failed, code " << int32_t(km_error) << std::endl;
-            mDevice = nullptr;
-            return false;
-        }
-        if (inputConsumed > inputLen) {
-            LOG(ERROR) << "update reported too much input consumed" << std::endl;
-            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() << std::endl;
-        return false;
-    }
-    if (km_error != km::ErrorCode::OK) {
-        LOG(ERROR) << "finish failed, code " << int32_t(km_error) << std::endl;
-        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() << std::endl;
-}
-
-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() << std::endl;
-        return false;
-    }
-    if (km_error != km::ErrorCode::OK) {
-        LOG(ERROR) << "generate_key failed, code " << int32_t(km_error) << std::endl;
-        return false;
-    }
-    return true;
-}
-
-km::ErrorCode Keymaster::exportKey(km::KeyFormat format, KeyBuffer& kmKey, const std::string& clientId,
-                          const std::string& appData, std::string* key) {
-    auto kmKeyBlob = km::support::blob2hidlVec(std::string(kmKey.data(), kmKey.size()));
-    auto emptyAssign = NULL;
-    auto kmClientId = (clientId == "!") ? emptyAssign: km::support::blob2hidlVec(clientId);
-    auto kmAppData = (appData == "!") ? emptyAssign: km::support::blob2hidlVec(appData);
-    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(format, kmKeyBlob, kmClientId, kmAppData, 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) {
-    LOG(ERROR) << "not actually deleting key\n";
-    return true;
-    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() << std::endl;
-        return false;
-    }
-    if (km_error != km::ErrorCode::OK) {
-        LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error) << std::endl;
-        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() << std::endl;
-        return KeymasterOperation(km::ErrorCode::UNKNOWN_ERROR);
-    }
-    if (km_error != km::ErrorCode::OK) {
-        LOG(ERROR) << "begin failed, code " << int32_t(km_error) << std::endl;
-        return KeymasterOperation(km_error);
-    }
-    return KeymasterOperation(mDevice.get(), mOpHandle);
-}
-
-bool Keymaster::isSecure() {
-    return mDevice->halVersion().securityLevel != km::SecurityLevel::SOFTWARE;
-}
-
-}  // namespace vold
-}  // namespace android
-
-using namespace ::android::vold;
-
-/*
-int keymaster_compatibility_cryptfs_scrypt() {
-    Keymaster dev;
-    if (!dev) {
-        LOG(ERROR) << "Failed to initiate keymaster session" << std::endl;
-        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" << std::endl;
-        return false;
-    }
-    *out_size = towrite.size();
-    if (buffer_size < towrite.size()) {
-        LOG(ERROR) << "Buffer too small " << buffer_size << " < " << towrite.size() << std::endl;
-        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" << std::endl;
-        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" << std::endl;
-        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" << std::endl;
-        return KeymasterSignResult::error;
-    }
-    if (!key_blob || !object || !signature_buffer || !signature_buffer_size) {
-        LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument" << std::endl;
-        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" << std::endl;
-        return KeymasterSignResult::upgrade;
-    }
-
-    if (op.errorCode() != km::ErrorCode::OK) {
-        LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode()) << std::endl;
-        return KeymasterSignResult::error;
-    }
-
-    if (!op.updateCompletely(input, &output)) {
-        LOG(ERROR) << "Error sending data to keymaster signature transaction: "
-                   << uint32_t(op.errorCode()) << std::endl;
-        return KeymasterSignResult::error;
-    }
-
-    if (!op.finish(&output)) {
-        LOG(ERROR) << "Error finalizing keymaster signature transaction: "
-                   << int32_t(op.errorCode()) << std::endl;
-        return KeymasterSignResult::error;
-    }
-
-    *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size()));
-    if (*signature_buffer == nullptr) {
-        LOG(ERROR) << "Error allocation buffer for keymaster signature" << std::endl;
-        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/ext4crypt/Keymaster4.h b/crypto/ext4crypt/Keymaster4.h
deleted file mode 100644
index 704cc2c..0000000
--- a/crypto/ext4crypt/Keymaster4.h
+++ /dev/null
@@ -1,162 +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_TWRP_KEYMASTER_H
-#define ANDROID_TWRP_KEYMASTER_H
-
-#include "KeyBuffer.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <android-base/macros.h>
-#include <keymasterV4_0/Keymaster.h>
-#include <keymasterV4_0/authorization_set.h>
-
-namespace android {
-namespace vold {
-
-namespace km = ::android::hardware::keymaster::V4_0;
-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() { return mError == km::ErrorCode::OK; }
-    km::ErrorCode errorCode() { 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);
-    // Export a key from keymaster.
-    km::ErrorCode exportKey(km::KeyFormat format, KeyBuffer& kmKey, const std::string& clientId,
-                   const std::string& appData, 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();
-
-  private:
-    std::unique_ptr<KmDevice> mDevice;
-    DISALLOW_COPY_AND_ASSIGN(Keymaster);
-    static bool hmacKeyGenerated;
-};
-
-}  // namespace vold
-}  // namespace android
-
-// 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/ext4crypt/MetadataCrypt.cpp b/crypto/ext4crypt/MetadataCrypt.cpp
deleted file mode 100644
index b195fa0..0000000
--- a/crypto/ext4crypt/MetadataCrypt.cpp
+++ /dev/null
@@ -1,271 +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 "KeyBuffer.h"
-#include "MetadataCrypt.h"
-
-#include <string>
-#include <thread>
-#include <vector>
-#include <algorithm>
-
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <linux/dm-ioctl.h>
-
-//#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/unique_fd.h>
-#include <cutils/fs.h>
-//#include <fs_mgr.h>
-
-//#include "EncryptInplace.h"
-#include "KeyStorage4.h"
-#include "KeyUtil.h"
-//#include "secontext.h"
-#include "Utils.h"
-//#include "VoldUtil.h"
-
-#include <iostream>
-#define LOG(x) std::cout
-#define PLOG(x) std::cout
-#include <linux/fs.h>
-
-#define DM_CRYPT_BUF_SIZE 4096
-#define TABLE_LOAD_RETRIES 10
-#define DEFAULT_KEY_TARGET_TYPE "default-key"
-
-using android::vold::KeyBuffer;
-
-static const std::string kDmNameUserdata = "userdata";
-
-void get_blkdev_size(int fd, unsigned long* nr_sec) {
-  if ((ioctl(fd, BLKGETSIZE, nr_sec)) == -1) {
-    *nr_sec = 0;
-  }
-}
-
-static const char* kLookup = "0123456789abcdef";
-
-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;
-}
-
-/*static bool mount_via_fs_mgr(const char* mount_point, const char* blk_device) {
-    // fs_mgr_do_mount runs fsck. Use setexeccon to run trusted
-    // partitions in the fsck domain.
-    if (setexeccon(secontextFsck())) {
-        PLOG(ERROR) << "Failed to setexeccon";
-        return false;
-    }
-    auto mount_rc = fs_mgr_do_mount(fstab_default, const_cast<char*>(mount_point),
-                                    const_cast<char*>(blk_device), nullptr);
-    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(DEBUG) << "Mounted " << mount_point;
-    return true;
-}*/
-
-static bool read_key(const std::string& key_dir, bool create_if_absent, KeyBuffer* key) {
-    /*if (!data_rec->key_dir) {
-        LOG(ERROR) << "Failed to get key_dir";
-        return false;
-    }
-    std::string key_dir = data_rec->key_dir;*/
-    auto dir = key_dir + "/key";
-    LOG(DEBUG) << "key_dir/key: " << dir << "\n";
-    /*if (fs_mkdirs(dir.c_str(), 0700)) {
-        PLOG(ERROR) << "Creating directories: " << dir;
-        return false;
-    }*/
-    auto temp = key_dir + "/tmp";
-    if (!android::vold::retrieveKey(create_if_absent, dir, temp, key)) return false;
-    return true;
-}
-
-static KeyBuffer default_key_params(const std::string& real_blkdev, const KeyBuffer& key) {
-    KeyBuffer hex_key;
-    if (/*android::vold::*/StrToHex(key, hex_key) != android::OK) {
-        LOG(ERROR) << "Failed to turn key to hex\n";
-        return KeyBuffer();
-    }
-    auto res = KeyBuffer() + "AES-256-XTS " + hex_key + " " + real_blkdev.c_str() + " 0";
-    return res;
-}
-
-static bool get_number_of_sectors(const std::string& real_blkdev, uint64_t *nr_sec) {
-    android::base::unique_fd dev_fd(TEMP_FAILURE_RETRY(open(
-        real_blkdev.c_str(), O_RDONLY | O_CLOEXEC, 0)));
-    if (dev_fd == -1) {
-        PLOG(ERROR) << "Unable to open " << real_blkdev << " to measure size\n";
-        return false;
-    }
-    unsigned long res;
-    // TODO: should use BLKGETSIZE64
-    get_blkdev_size(dev_fd.get(), &res);
-    if (res == 0) {
-        PLOG(ERROR) << "Unable to measure size of " << real_blkdev << "\n";
-        return false;
-    }
-    *nr_sec = res;
-    return true;
-}
-
-static struct dm_ioctl* dm_ioctl_init(char *buffer, size_t buffer_size,
-                                      const std::string& dm_name) {
-    if (buffer_size < sizeof(dm_ioctl)) {
-        LOG(ERROR) << "dm_ioctl buffer too small\n";
-        return nullptr;
-    }
-
-    memset(buffer, 0, buffer_size);
-    struct dm_ioctl* io = (struct dm_ioctl*) buffer;
-    io->data_size = buffer_size;
-    io->data_start = sizeof(struct dm_ioctl);
-    io->version[0] = 4;
-    io->version[1] = 0;
-    io->version[2] = 0;
-    io->flags = 0;
-    dm_name.copy(io->name, sizeof(io->name));
-    return io;
-}
-
-static bool create_crypto_blk_dev(const std::string& dm_name, uint64_t nr_sec,
-                                  const std::string& target_type, const KeyBuffer& crypt_params,
-                                  std::string* crypto_blkdev) {
-    PLOG(INFO) << "starting create_crypto_blk_dev\n";
-    android::base::unique_fd dm_fd(TEMP_FAILURE_RETRY(open(
-        "/dev/device-mapper", O_RDWR | O_CLOEXEC, 0)));
-    if (dm_fd == -1) {
-        PLOG(ERROR) << "Cannot open device-mapper\n";
-        return false;
-    }
-    alignas(struct dm_ioctl) char buffer[DM_CRYPT_BUF_SIZE];
-    auto io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
-    if (!io || ioctl(dm_fd.get(), DM_DEV_CREATE, io) != 0) {
-        PLOG(ERROR) << "Cannot create dm-crypt device " << dm_name << "\n";
-        return false;
-    }
-
-    // Get the device status, in particular, the name of its device file
-    io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
-    if (ioctl(dm_fd.get(), DM_DEV_STATUS, io) != 0) {
-        PLOG(ERROR) << "Cannot retrieve dm-crypt device status " << dm_name << "\n";
-        return false;
-    }
-    *crypto_blkdev = std::string() + "/dev/block/dm-" + std::to_string(
-        (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00));
-
-    io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
-    size_t paramix = io->data_start + sizeof(struct dm_target_spec);
-    size_t nullix = paramix + crypt_params.size();
-    size_t endix = (nullix + 1 + 7) & 8; // Add room for \0 and align to 8 byte boundary
-
-    if (endix > sizeof(buffer)) {
-        LOG(ERROR) << "crypt_params too big for DM_CRYPT_BUF_SIZE\n";
-        return false;
-    }
-
-    io->target_count = 1;
-    auto tgt = (struct dm_target_spec *) (buffer + io->data_start);
-    tgt->status = 0;
-    tgt->sector_start = 0;
-    tgt->length = nr_sec;
-    target_type.copy(tgt->target_type, sizeof(tgt->target_type));
-    memcpy(buffer + paramix, crypt_params.data(),
-            std::min(crypt_params.size(), sizeof(buffer) - paramix));
-    buffer[nullix] = '\0';
-    tgt->next = endix;
-
-    for (int i = 0; ; i++) {
-        if (ioctl(dm_fd.get(), DM_TABLE_LOAD, io) == 0) {
-            break;
-        }
-        if (i+1 >= TABLE_LOAD_RETRIES) {
-            PLOG(ERROR) << "DM_TABLE_LOAD ioctl failed\n";
-            return false;
-        }
-        PLOG(INFO) << "DM_TABLE_LOAD ioctl failed, retrying\n";
-        usleep(500000);
-    }
-
-    // Resume this device to activate it
-    io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
-    if (ioctl(dm_fd.get(), DM_DEV_SUSPEND, io)) {
-        PLOG(ERROR) << "Cannot resume dm-crypt device " << dm_name << "\n";
-        return false;
-    }
-    return true;
-}
-
-bool e4crypt_mount_metadata_encrypted(const std::string& mount_point, bool needs_encrypt, const std::string& key_dir, const std::string& blk_device, std::string* crypto_blkdev) {
-    LOG(DEBUG) << "e4crypt_mount_metadata_encrypted: " << mount_point << " " << needs_encrypt << "\n";
-    /*auto encrypted_state = android::base::GetProperty("ro.crypto.state", "");
-    if (encrypted_state != "") {
-        LOG(DEBUG) << "e4crypt_enable_crypto got unexpected starting state: " << encrypted_state;
-        return false;
-    }
-    auto data_rec = fs_mgr_get_entry_for_mount_point(fstab_default, mount_point);
-    if (!data_rec) {
-        LOG(ERROR) << "Failed to get data_rec";
-        return false;
-    }*/
-    KeyBuffer key;
-    if (!read_key(key_dir, needs_encrypt, &key)) return false;
-    uint64_t nr_sec;
-    if (!get_number_of_sectors(blk_device, &nr_sec)) return false;
-    //std::string crypto_blkdev;
-    if (!create_crypto_blk_dev(kDmNameUserdata, nr_sec, DEFAULT_KEY_TARGET_TYPE,
-                               default_key_params(blk_device, key), /*&*/crypto_blkdev))
-        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(const_cast<char*>(crypto_blkdev.c_str()), data_rec->blk_device,
-                                   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(DEBUG) << "Mounting metadata-encrypted filesystem:" << mount_point;
-    mount_via_fs_mgr(data_rec->mount_point, crypto_blkdev.c_str());*/
-    LOG(DEBUG) << "crypto block device '" << *crypto_blkdev << "\n";
-    return true;
-}
diff --git a/crypto/ext4crypt/MetadataCrypt.h b/crypto/ext4crypt/MetadataCrypt.h
deleted file mode 100644
index 69addf3..0000000
--- a/crypto/ext4crypt/MetadataCrypt.h
+++ /dev/null
@@ -1,25 +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>
-__BEGIN_DECLS
-bool e4crypt_mount_metadata_encrypted(const std::string& mount_point, bool needs_encrypt, const std::string& key_dir, const std::string& blk_device, std::string* crypto_blkdev);
-__END_DECLS
-
-#endif
diff --git a/crypto/ext4crypt/ScryptParameters.cpp b/crypto/ext4crypt/ScryptParameters.cpp
deleted file mode 100644
index 669809b..0000000
--- a/crypto/ext4crypt/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/ext4crypt/ScryptParameters.h b/crypto/ext4crypt/ScryptParameters.h
deleted file mode 100644
index 1b43ea5..0000000
--- a/crypto/ext4crypt/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/ext4crypt/Utils.cpp b/crypto/ext4crypt/Utils.cpp
deleted file mode 100644
index 9711cef..0000000
--- a/crypto/ext4crypt/Utils.cpp
+++ /dev/null
@@ -1,307 +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 <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-
-#include <fcntl.h>
-#include <linux/fs.h>
-#include <stdlib.h>
-#include <sys/mount.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/statvfs.h>
-
-#include <selinux/android.h>
-
-using android::base::ReadFileToString;
-using android::base::StringPrintf;
-
-namespace android {
-namespace vold {
-
-static const char* kKeyPath = "/data/misc/vold";
-
-status_t ForkExecvp(const std::vector<std::string>& args) {
-    return ForkExecvp(args, nullptr);
-}
-
-status_t ForkExecvp(const std::vector<std::string>& args, security_context_t context) {
-    size_t argc = args.size();
-    char** argv = (char**) calloc(argc, sizeof(char*));
-    for (size_t i = 0; i < argc; i++) {
-        argv[i] = (char*) args[i].c_str();
-        if (i == 0) {
-            LOG(VERBOSE) << args[i];
-        } else {
-            LOG(VERBOSE) << "    " << args[i];
-        }
-    }
-
-    if (setexeccon(context)) {
-        LOG(ERROR) << "Failed to setexeccon" << std::endl;
-        abort();
-    }
-    abort();
-    status_t res = 1;//android_fork_execvp(argc, argv, NULL, false, true);
-    if (setexeccon(nullptr)) {
-        LOG(ERROR) << "Failed to setexeccon" << std::endl;
-        abort();
-    }
-
-    free(argv);
-    return res;
-}
-
-status_t ForkExecvp(const std::vector<std::string>& args,
-        std::vector<std::string>& output) {
-    return ForkExecvp(args, output, nullptr);
-}
-
-status_t ForkExecvp(const std::vector<std::string>& args,
-        std::vector<std::string>& output, security_context_t context) {
-    std::string cmd;
-    for (size_t i = 0; i < args.size(); i++) {
-        cmd += args[i] + " ";
-        if (i == 0) {
-            LOG(VERBOSE) << args[i];
-        } else {
-            LOG(VERBOSE) << "    " << args[i];
-        }
-    }
-    output.clear();
-
-    if (setexeccon(context)) {
-        LOG(ERROR) << "Failed to setexeccon" << std::endl;
-        abort();
-    }
-    FILE* fp = popen(cmd.c_str(), "r");
-    if (setexeccon(nullptr)) {
-        LOG(ERROR) << "Failed to setexeccon" << std::endl;
-        abort();
-    }
-
-    if (!fp) {
-        PLOG(ERROR) << "Failed to popen " << cmd << std::endl;
-        return -errno;
-    }
-    char line[1024];
-    while (fgets(line, sizeof(line), fp) != nullptr) {
-        LOG(VERBOSE) << line;
-        output.push_back(std::string(line));
-    }
-    if (pclose(fp) != 0) {
-        PLOG(ERROR) << "Failed to pclose " << cmd << std::endl;
-        return -errno;
-    }
-
-    return OK;
-}
-
-pid_t ForkExecvpAsync(const std::vector<std::string>& args) {
-    size_t argc = args.size();
-    char** argv = (char**) calloc(argc + 1, sizeof(char*));
-    for (size_t i = 0; i < argc; i++) {
-        argv[i] = (char*) args[i].c_str();
-        if (i == 0) {
-            LOG(VERBOSE) << args[i];
-        } else {
-            LOG(VERBOSE) << "    " << args[i];
-        }
-    }
-
-    pid_t pid = fork();
-    if (pid == 0) {
-        close(STDIN_FILENO);
-        close(STDOUT_FILENO);
-        close(STDERR_FILENO);
-
-        if (execvp(argv[0], argv)) {
-            PLOG(ERROR) << "Failed to exec" << std::endl;
-        }
-
-        _exit(1);
-    }
-
-    if (pid == -1) {
-        PLOG(ERROR) << "Failed to exec" << std::endl;
-    }
-
-    free(argv);
-    return pid;
-}
-
-status_t ReadRandomBytes(size_t bytes, std::string& out) {
-    out.resize(bytes);
-    return ReadRandomBytes(bytes, &out[0]);
-}
-
-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;
-    }
-
-    size_t n;
-    while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], bytes))) > 0) {
-        bytes -= n;
-        buf += n;
-    }
-    close(fd);
-
-    if (bytes == 0) {
-        return OK;
-    } else {
-        return -EIO;
-    }
-}
-
-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]) {
-        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;
-        }
-
-        if (even) {
-            cur = val << 4;
-        } else {
-            cur += val;
-            str.push_back(cur);
-            cur = 0;
-        }
-        even = !even;
-    }
-    return even ? OK : -EINVAL;
-}
-
-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(nullptr).c_str(), userId);
-}
-
-std::string BuildDataSystemCePath(userid_t userId) {
-    return StringPrintf("%s/system_ce/%u", BuildDataPath(nullptr).c_str(), userId);
-}
-
-std::string BuildDataSystemDePath(userid_t userId) {
-    return StringPrintf("%s/system_de/%u", BuildDataPath(nullptr).c_str(), userId);
-}
-
-std::string BuildDataMiscLegacyPath(userid_t userId) {
-    return StringPrintf("%s/misc/user/%u", BuildDataPath(nullptr).c_str(), userId);
-}
-
-std::string BuildDataMiscCePath(userid_t userId) {
-    return StringPrintf("%s/misc_ce/%u", BuildDataPath(nullptr).c_str(), userId);
-}
-
-std::string BuildDataMiscDePath(userid_t userId) {
-    return StringPrintf("%s/misc_de/%u", BuildDataPath(nullptr).c_str(), userId);
-}
-
-std::string BuildDataVendorCePath(userid_t userId) {
-    return StringPrintf("%s/vendor_ce/%u", BuildDataPath(nullptr).c_str(), userId);
-}
-
-std::string BuildDataVendorDePath(userid_t userId) {
-    return StringPrintf("%s/vendor_de/%u", BuildDataPath(nullptr).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(nullptr).c_str(), userId);
-}
-
-std::string BuildDataProfilesForeignDexDePath(userid_t userId) {
-    std::string profiles_path = BuildDataProfilesDePath(userId);
-    return StringPrintf("%s/foreign-dex", profiles_path.c_str());
-}
-
-std::string BuildDataPath(const char* volumeUuid) {
-    // TODO: unify with installd path generation logic
-    if (volumeUuid == nullptr) {
-        return "/data";
-    } else {
-        CHECK(isValidFilename(volumeUuid));
-        return StringPrintf("/mnt/expand/%s", volumeUuid);
-    }
-}
-
-std::string BuildDataMediaCePath(const char* 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 char* volumeUuid, userid_t userId) {
-    // TODO: unify with installd path generation logic
-    std::string data(BuildDataPath(volumeUuid));
-    if (volumeUuid == nullptr) {
-        if (userId == 0) {
-            return StringPrintf("%s/data", data.c_str());
-        } else {
-            return StringPrintf("%s/user/%u", data.c_str(), userId);
-        }
-    } else {
-        return StringPrintf("%s/user/%u", data.c_str(), userId);
-    }
-}
-
-std::string BuildDataUserDePath(const char* 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);
-}
-
-}  // namespace vold
-}  // namespace android
diff --git a/crypto/ext4crypt/Utils.h b/crypto/ext4crypt/Utils.h
deleted file mode 100644
index 253541c..0000000
--- a/crypto/ext4crypt/Utils.h
+++ /dev/null
@@ -1,76 +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 TWRP_VOLD_UTILS_H
-#define TWRP_VOLD_UTILS_H
-
-#include <utils/Errors.h>
-#include <cutils/multiuser.h>
-#include <selinux/selinux.h>
-
-#include <vector>
-#include <string>
-
-// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions. It goes in the private:
-// declarations in a class.
-#if !defined(DISALLOW_COPY_AND_ASSIGN)
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
-    TypeName(const TypeName&) = delete;  \
-    void operator=(const TypeName&) = delete
-#endif
-
-namespace android {
-namespace vold {
-
-/* Returns either WEXITSTATUS() status, or a negative errno */
-status_t ForkExecvp(const std::vector<std::string>& args);
-status_t ForkExecvp(const std::vector<std::string>& args, security_context_t context);
-
-status_t ForkExecvp(const std::vector<std::string>& args,
-        std::vector<std::string>& output);
-status_t ForkExecvp(const std::vector<std::string>& args,
-        std::vector<std::string>& output, security_context_t context);
-
-pid_t ForkExecvpAsync(const std::vector<std::string>& args);
-
-status_t ReadRandomBytes(size_t bytes, std::string& out);
-status_t ReadRandomBytes(size_t bytes, char* buffer);
-
-/* Converts hex string to raw bytes, ignoring [ :-] */
-status_t HexToStr(const std::string& hex, std::string& str);
-
-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 BuildDataProfilesForeignDexDePath(userid_t userid);
-std::string BuildDataVendorCePath(userid_t userid);
-std::string BuildDataVendorDePath(userid_t userid);
-
-std::string BuildDataPath(const char* volumeUuid);
-std::string BuildDataMediaCePath(const char* volumeUuid, userid_t userid);
-std::string BuildDataUserCePath(const char* volumeUuid, userid_t userid);
-std::string BuildDataUserDePath(const char* volumeUuid, userid_t userid);
-
-}  // namespace vold
-}  // namespace android
-
-#endif
diff --git a/crypto/ext4crypt/Weaver1.cpp b/crypto/ext4crypt/Weaver1.cpp
deleted file mode 100644
index ea357ed..0000000
--- a/crypto/ext4crypt/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/ext4crypt/Weaver1.h b/crypto/ext4crypt/Weaver1.h
deleted file mode 100644
index 22f401e..0000000
--- a/crypto/ext4crypt/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/ext4crypt/e4policyget.cpp b/crypto/ext4crypt/e4policyget.cpp
deleted file mode 100644
index 05de86f..0000000
--- a/crypto/ext4crypt/e4policyget.cpp
+++ /dev/null
@@ -1,41 +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 "ext4crypt_tar.h"
-
-#define EXT4_KEY_DESCRIPTOR_SIZE 8
-#define EXT4_KEY_DESCRIPTOR_SIZE_HEX 17
-
-int main(int argc, char *argv[]) {
-	bool ret = false;
-	if (argc != 2) {
-		printf("Must specify a path\n");
-		return -1;
-	} else  {
-		ext4_encryption_policy eep;
-		if (e4crypt_policy_get_struct(argv[1], &eep, sizeof(eep))) {
-			char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX];
-			policy_to_hex(eep.master_key_descriptor, policy_hex);
-			printf("%s\n", policy_hex);
-		} else {
-			printf("No policy set\n");
-		}
-	}
-	return 0;
-}
diff --git a/crypto/ext4crypt/ext4_crypt.cpp b/crypto/ext4crypt/ext4_crypt.cpp
deleted file mode 100644
index 5a3b4b2..0000000
--- a/crypto/ext4crypt/ext4_crypt.cpp
+++ /dev/null
@@ -1,207 +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.
- */
-
-/* TWRP NOTE: Kanged from system/extras/ext4_utils/ext4_crypt.cpp
- * because policy_to_hex, e4crypt_policy_set, and e4crypt_policy_get
- * are not exposed to be used. There was also a bug in e4crypt_policy_get
- * that may or may not be fixed in the user's local repo:
- * https://android.googlesource.com/platform/system/extras/+/30b93dd5715abcabd621235733733c0503f9c552
- */
-
-#include "ext4_crypt.h"
-#include "ext4crypt_tar.h"
-
-#include <dirent.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <fcntl.h>
-#include <asm/ioctl.h>
-#include <sys/syscall.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <cutils/properties.h>
-
-#define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy"
-#define EXT4_KEYREF_DELIMITER ((char)'.')
-
-#define EXT4_ENCRYPTION_MODE_AES_256_XTS    1
-#define EXT4_ENCRYPTION_MODE_AES_256_CTS    4
-#define EXT4_ENCRYPTION_MODE_AES_256_HEH    126
-#define EXT4_ENCRYPTION_MODE_PRIVATE        127
-
-static int encryption_mode = EXT4_ENCRYPTION_MODE_PRIVATE;
-
-#define HEX_LOOKUP "0123456789abcdef"
-
-extern "C" void policy_to_hex(const char* policy, char* hex) {
-    for (size_t i = 0, j = 0; i < EXT4_KEY_DESCRIPTOR_SIZE; i++) {
-        hex[j++] = HEX_LOOKUP[(policy[i] & 0xF0) >> 4];
-        hex[j++] = HEX_LOOKUP[policy[i] & 0x0F];
-    }
-    hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX - 1] = '\0';
-}
-
-extern "C" bool e4crypt_policy_set(const char *directory, const char *policy,
-                               size_t policy_length, int contents_encryption_mode) {
-    if (contents_encryption_mode == 0)
-        contents_encryption_mode = encryption_mode;
-    if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) {
-		printf("policy wrong length\n");
-        LOG(ERROR) << "Policy wrong length: " << policy_length;
-        return false;
-    }
-    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;
-    }
-
-    ext4_encryption_policy eep;
-    eep.version = 0;
-    eep.contents_encryption_mode = contents_encryption_mode;
-    eep.filenames_encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_CTS;
-    eep.flags = 0;
-    memcpy(eep.master_key_descriptor, policy, EXT4_KEY_DESCRIPTOR_SIZE);
-    if (ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &eep)) {
-		printf("failed to set policy for '%s' '%s'\n", directory, policy);
-        PLOG(ERROR) << "Failed to set encryption policy for " << directory;
-        close(fd);
-        return false;
-    }
-    close(fd);
-
-    char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX];
-    policy_to_hex(policy, policy_hex);
-    LOG(INFO) << "Policy for " << directory << " set to " << policy_hex;
-    return true;
-}
-
-extern "C" bool e4crypt_policy_get(const char *directory, char *policy,
-                               size_t policy_length, int contents_encryption_mode) {
-    if (contents_encryption_mode == 0)
-        contents_encryption_mode = encryption_mode;
-    if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) {
-        LOG(ERROR) << "Policy wrong length: " << policy_length;
-        return false;
-    }
-
-    int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open directory " << directory;
-        return false;
-    }
-
-    ext4_encryption_policy eep;
-    memset(&eep, 0, sizeof(ext4_encryption_policy));
-    if (ioctl(fd, EXT4_IOC_GET_ENCRYPTION_POLICY, &eep) != 0) {
-        PLOG(ERROR) << "Failed to get encryption policy for " << directory;
-        close(fd);
-        return false;
-    }
-    close(fd);
-
-    if ((eep.version != 0)
-            || (eep.contents_encryption_mode != contents_encryption_mode)
-            || (eep.filenames_encryption_mode != EXT4_ENCRYPTION_MODE_AES_256_CTS)
-            || (eep.flags != 0)) {
-        LOG(ERROR) << "Failed to find matching encryption policy for " << directory;
-        return false;
-    }
-    memcpy(policy, eep.master_key_descriptor, EXT4_KEY_DESCRIPTOR_SIZE);
-
-    return true;
-}
-
-extern "C" void e4crypt_policy_fill_default_struct(ext4_encryption_policy *eep) {
-	eep->version = 0;
-    eep->contents_encryption_mode = encryption_mode;
-    eep->filenames_encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_CTS;
-    eep->flags = 0;
-    memset((void*)&eep->master_key_descriptor[0], 0, EXT4_KEY_DESCRIPTOR_SIZE);
-}
-
-extern "C" bool e4crypt_policy_set_struct(const char *directory, const ext4_encryption_policy *eep) {
-    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 (ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, eep)) {
-		printf("failed to set policy for '%s'\n", directory);
-        PLOG(ERROR) << "Failed to set encryption policy for " << directory;
-        close(fd);
-        return false;
-    }
-    close(fd);
-    return true;
-}
-
-extern "C" bool e4crypt_policy_get_struct(const char *directory, ext4_encryption_policy *eep) {
-    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;
-    }
-    memset(eep, 0, sizeof(ext4_encryption_policy));
-    if (ioctl(fd, EXT4_IOC_GET_ENCRYPTION_POLICY, eep) != 0) {
-        PLOG(ERROR) << "Failed to get encryption policy for " << directory;
-        close(fd);
-        return false;
-    }
-    close(fd);
-    return true;
-}
-
-extern "C" bool e4crypt_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);
-    if (!strcmp(contents_encryption_mode, "software")) {
-        encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
-    } else if (!strcmp(contents_encryption_mode, "ice")) {
-        encryption_mode = EXT4_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;
-}
diff --git a/crypto/ext4crypt/ext4_crypt.h b/crypto/ext4crypt/ext4_crypt.h
deleted file mode 100644
index d410ccf..0000000
--- a/crypto/ext4crypt/ext4_crypt.h
+++ /dev/null
@@ -1,39 +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 _EXT4_CRYPT_H_
-#define _EXT4_CRYPT_H_
-
-#include <sys/cdefs.h>
-#include <stdbool.h>
-#include <cutils/multiuser.h>
-
-__BEGIN_DECLS
-
-bool e4crypt_is_native();
-
-int e4crypt_policy_ensure(const char *directory, const char *policy,
-                          size_t policy_length,
-                          const char *contents_encryption_mode,
-                          const char *filenames_encryption_mode);
-
-static const char* e4crypt_unencrypted_folder = "/unencrypted";
-static const char* e4crypt_key_ref = "/unencrypted/ref";
-static const char* e4crypt_key_mode = "/unencrypted/mode";
-
-__END_DECLS
-
-#endif // _EXT4_CRYPT_H_
diff --git a/crypto/ext4crypt/ext4crypt_tar.h b/crypto/ext4crypt/ext4crypt_tar.h
deleted file mode 100644
index c35d115..0000000
--- a/crypto/ext4crypt/ext4crypt_tar.h
+++ /dev/null
@@ -1,58 +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 __EXT4CRYPT_TAR_H
-#define __EXT4CRYPT_TAR_H
-
-#include <sys/cdefs.h>
-#include <stdbool.h>
-#include <cutils/multiuser.h>
-
-// ext4enc:TODO Include structure from somewhere sensible
-// MUST be in sync with ext4_crypto.c in kernel
-#define EXT4_KEY_DESCRIPTOR_SIZE 8
-#define EXT4_KEY_DESCRIPTOR_SIZE_HEX 17
-
-// ext4enc:TODO Get value from somewhere sensible
-#define EXT4_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct ext4_encryption_policy)
-#define EXT4_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct ext4_encryption_policy)
-
-__BEGIN_DECLS
-
-struct ext4_encryption_policy {
-    char version;
-    char contents_encryption_mode;
-    char filenames_encryption_mode;
-    char flags;
-    char master_key_descriptor[EXT4_KEY_DESCRIPTOR_SIZE];
-} __attribute__((__packed__));
-
-bool lookup_ref_key(const char* policy, char* policy_type);
-bool lookup_ref_tar(const char* policy_type, char* policy);
-
-void policy_to_hex(const char* policy, char* hex);
-bool e4crypt_policy_set(const char *directory, const char *policy,
-                               size_t policy_length, int contents_encryption_mode);
-bool e4crypt_policy_get(const char *directory, char *policy,
-                               size_t policy_length, int contents_encryption_mode);
-void e4crypt_policy_fill_default_struct(struct ext4_encryption_policy *eep);
-bool e4crypt_policy_set_struct(const char *directory, const struct ext4_encryption_policy *eep);
-bool e4crypt_policy_get_struct(const char *directory, struct ext4_encryption_policy *eep);
-
-bool e4crypt_set_mode();
-__END_DECLS
-
-#endif
diff --git a/crypto/ext4crypt/keystore_auth.cpp b/crypto/ext4crypt/keystore_auth.cpp
deleted file mode 100644
index 40d890f..0000000
--- a/crypto/ext4crypt/keystore_auth.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-	Copyright 2018 bigbiff/Dees_Troy 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/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;
-
-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<security::IKeystoreService> service = interface_cast<security::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/ext4crypt/main.cpp b/crypto/ext4crypt/main.cpp
deleted file mode 100644
index f0266ae..0000000
--- a/crypto/ext4crypt/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/fde/Android.mk b/crypto/fde/Android.mk
index f78697f..faf7da8 100755
--- a/crypto/fde/Android.mk
+++ b/crypto/fde/Android.mk
@@ -14,6 +14,8 @@
     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
diff --git a/crypto/fde/cryptfs.cpp b/crypto/fde/cryptfs.cpp
index 2d1595f..fa0dc78 100644
--- a/crypto/fde/cryptfs.cpp
+++ b/crypto/fde/cryptfs.cpp
@@ -60,12 +60,7 @@
 //#include "f2fs_sparseblock.h"
 //#include "EncryptInplace.h"
 //#include "Process.h"
-#if TW_KEYMASTER_MAX_API == 3
-#include "../ext4crypt/Keymaster3.h"
-#endif
-#if TW_KEYMASTER_MAX_API == 4
-#include "../ext4crypt/Keymaster4.h"
-#endif
+#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
@@ -879,7 +874,7 @@
     return -1;
   }
   if (fname[0] != '/') {
-    SLOGE("Unexpected value for crypto key location\n");
+    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) {
diff --git a/crypto/fscrypt/Android.mk b/crypto/fscrypt/Android.mk
index 0fa36c8..a10a7e6 100755
--- a/crypto/fscrypt/Android.mk
+++ b/crypto/fscrypt/Android.mk
@@ -5,16 +5,17 @@
 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
-LOCAL_SRC_FILES := Decrypt.cpp ScryptParameters.cpp Utils.cpp HashPassword.cpp \
-    FsCrypt.cpp KeyUtil.cpp Keymaster.cpp KeyStorage.cpp MetadataCrypt.cpp KeyBuffer.cpp \
-    Process.cpp EncryptInplace.cpp Weaver1.cpp fscrypt_policy.cpp
+    -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 libkeymaster4support libf2fs_sparseblock libkeystore_parcelables \
-libkeystore_aidl android.hardware.weaver@1.0 libkeyutils liblog libhwbinder libchrome
-LOCAL_STATIC_LIBRARIES := libscrypt_static
+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 \
@@ -32,7 +33,8 @@
     system/core/init/ \
     system/vold/model \
     system/vold/ \
-    system/extras/f2fs_utils/
+    system/extras/f2fs_utils/ \
+    bootable/recovery/bootloader_message/include
 
 ifneq ($(wildcard hardware/libhardware/include/hardware/keymaster0.h),)
     LOCAL_CFLAGS += -DTW_CRYPTO_HAVE_KEYMASTERX
@@ -43,7 +45,16 @@
 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
@@ -56,16 +67,6 @@
 include $(BUILD_EXECUTABLE)
 
 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_SRC_FILES := fscryptpolicyget.cpp
-LOCAL_SHARED_LIBRARIES := libtwrpfscrypt
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
 LOCAL_MODULE := keystore_auth
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
diff --git a/crypto/fscrypt/Checkpoint.cpp b/crypto/fscrypt/Checkpoint.cpp
new file mode 100644
index 0000000..cdfc8aa
--- /dev/null
+++ b/crypto/fscrypt/Checkpoint.cpp
@@ -0,0 +1,743 @@
+/*
+ * 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();
+    }
+    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
index 63ead83..cd17c78 100644
--- a/crypto/fscrypt/Checkpoint.h
+++ b/crypto/fscrypt/Checkpoint.h
@@ -20,8 +20,6 @@
 #include <binder/Status.h>
 #include <string>
 
-namespace android {
-namespace vold {
 
 android::binder::Status cp_supportsCheckpoint(bool& result);
 
@@ -39,13 +37,14 @@
 
 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();
 
-}  // namespace vold
-}  // namespace android
+void cp_resetCheckpoint();
 
 #endif
diff --git a/crypto/fscrypt/CryptoType.cpp b/crypto/fscrypt/CryptoType.cpp
new file mode 100644
index 0000000..cf1ef42
--- /dev/null
+++ b/crypto/fscrypt/CryptoType.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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
new file mode 100644
index 0000000..79ea93d
--- /dev/null
+++ b/crypto/fscrypt/CryptoType.h
@@ -0,0 +1,98 @@
+/*
+ * 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
index 44eae08..5878d15 100755
--- a/crypto/fscrypt/Decrypt.cpp
+++ b/crypto/fscrypt/Decrypt.cpp
@@ -16,6 +16,7 @@
 
 #include "Decrypt.h"
 #include "FsCrypt.h"
+#include <fscrypt/fscrypt.h>
 
 #include <map>
 #include <string>
@@ -72,39 +73,37 @@
 #include <keystore/OperationResult.h>
 #include "keystore_client.pb.h"
 
-#include <keymasterV4_0/authorization_set.h>
-#include <keymasterV4_0/keymaster_utils.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_0::support::blob2hidlVec;
+using android::hardware::keymaster::V4_1::support::blob2hidlVec;
 
-// Store main DE raw ref / policy
-extern std::string de_raw_ref;
-extern std::map<userid_t, std::string> s_de_key_raw_refs;
-extern std::map<userid_t, std::string> s_ce_key_raw_refs;
 
 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, std::string>& key_map, const uint8_t* policy, userid_t* user_id) {
-	char policy_string_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-	char key_map_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-	policy_to_hex(policy, policy_string_hex);
+static bool lookup_ref_key_internal(std::map<userid_t, android::fscrypt::EncryptionPolicy> key_map, const uint8_t* policy, userid_t* user_id) {
+	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);
 
-    for (std::map<userid_t, std::string>::iterator it=key_map.begin(); it!=key_map.end(); ++it) {
-		policy_to_hex(reinterpret_cast<const uint8_t*>(&it->second[0]), key_map_hex);
+    for (std::map<userid_t, android::fscrypt::EncryptionPolicy>::iterator it=key_map.begin(); it!=key_map.end(); ++it) {
+		bytes_to_hex(reinterpret_cast<const uint8_t*>(&it->second.key_raw_ref[0]), FSCRYPT_KEY_IDENTIFIER_SIZE, key_map_hex);
 		std::string key_map_hex_string = std::string(key_map_hex);
 		if (key_map_hex_string == policy_string_hex) {
             *user_id = it->first;
@@ -114,65 +113,72 @@
     return false;
 }
 
-extern "C" bool lookup_ref_key(const uint8_t* policy, uint8_t* policy_type) {
-    userid_t user_id = 0;
-	char policy_string_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-	char de_raw_ref_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-	policy_to_hex(policy, policy_string_hex);
-	policy_to_hex(reinterpret_cast<const uint8_t*>(&de_raw_ref[0]), de_raw_ref_hex);
-	std::string de_raw_ref_hex_string = std::string(de_raw_ref_hex);
-
+#ifdef USE_FSCRYPT_POLICY_V1
+extern "C" bool lookup_ref_key(fscrypt_policy_v1* v1, uint8_t* policy_type) {
+#else
+extern "C" bool lookup_ref_key(fscrypt_policy_v2* v2, uint8_t* policy_type) {
+#endif
+	userid_t user_id = 0;
 	std::string policy_type_string;
-	if (policy_string_hex == de_raw_ref_hex_string) {
+
+	char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
+	bytes_to_hex(v2->master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
+	if (std::strncmp((const char*) v2->master_key_identifier, de_key_raw_ref.c_str(), FSCRYPT_KEY_IDENTIFIER_SIZE) == 0) {
 		policy_type_string = "0DK";
 		memcpy(policy_type, policy_type_string.data(), policy_type_string.size());
 		return true;
 	}
-
-    if (!lookup_ref_key_internal(s_de_key_raw_refs, policy, &user_id)) {
-        if (!lookup_ref_key_internal(s_ce_key_raw_refs, policy, &user_id)) {
+    if (!lookup_ref_key_internal(s_de_policies, v2->master_key_identifier, &user_id)) {
+        if (!lookup_ref_key_internal(s_ce_policies, v2->master_key_identifier, &user_id)) {
             return false;
-		} else
+		} else {
 			policy_type_string = "0CE" + std::to_string(user_id);
-    } else
+		}
+    } else {
 			policy_type_string = "0DE" + std::to_string(user_id);
+	}
 	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);
-	char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-	policy_to_hex(policy_type, policy_hex);
+	char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
+	bytes_to_hex(policy_type, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
 
-	// Current encryption fscrypt policy is v1 (which is stored as version 0e)
+	userid_t user_id = atoi(policy_type_string.substr(3, 4).c_str());
+
+	// TODO Update version # and make magic strings
 	if (policy_type_string.substr(0,1) != "0") {
-        printf("Unexpected version %c\n", policy_type[0]);
+        LOG(ERROR) << "Unexpected version:" << policy_type[0];
         return false;
     }
 
 	if (policy_type_string.substr(1, 2) == "DK") {
-        memcpy(policy, de_raw_ref.data(), de_raw_ref.size());
+        memcpy(policy, de_key_raw_ref.data(), de_key_raw_ref.size());
         return true;
     }
 
-	userid_t user_id = atoi(policy_type_string.substr(3, 4).c_str());
     std::string raw_ref;
 
 	if (policy_type_string.substr(1, 1) == "D") {
-        if (lookup_key_ref(s_de_key_raw_refs, user_id, &raw_ref)) {
+        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) == "C") {
-        if (lookup_key_ref(s_ce_key_raw_refs, user_id, &raw_ref)) {
+        if (lookup_key_ref(s_ce_policies, user_id, &raw_ref)) {
             memcpy(policy, raw_ref.data(), raw_ref.size());
         } else
             return false;
     } else {
-        printf("unknown policy type '%s'\n", policy_type);
+        LOG(ERROR) << "unknown policy type: " << policy_type;
         return false;
     }
+
+	char found_policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
+	bytes_to_hex(policy, FSCRYPT_KEY_IDENTIFIER_SIZE, found_policy_hex);
     return true;
 }
 
@@ -688,14 +694,16 @@
         	return disk_decryption_secret_key;
     	}
 		OperationResult result = future.get();
-		auto handle = std::move(result.token);
+		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, handle, empty_params, cipher_text_hidlvec, &error_code);
+		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);
@@ -717,11 +725,10 @@
 		future = {};
 		promise = new OperationResultPromise();
 		future = promise->get_future();
-		std::tie(rc, keyBlob, charBlob, lockedEntry) = mKeyStore->getKeyForName(name8, callingUid, TYPE_KEYMASTER_10);
-		
-		auto hidlInput = blob2hidlVec(input_data);
-		::keystore::hidl_vec<uint8_t> signature;
-		binder_result = service->finish(promise, handle, empty_params, hidlInput, signature, entropy, &error_code);
+
+		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);
@@ -844,11 +851,7 @@
 
 	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 = FLAG_STORAGE_DE;
-    if (user_id == 0)
-		flags = FLAG_STORAGE_DE;
-	else
-		flags = FLAG_STORAGE_CE;
+	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;
@@ -1091,11 +1094,8 @@
 		printf("Unknown password type\n");
 		return false;
 	}
-    int flags = FLAG_STORAGE_DE;
-    if (user_id == 0)
-		flags = FLAG_STORAGE_DE;
-	else
-		flags = FLAG_STORAGE_CE;
+
+	int flags = android::os::IVold::STORAGE_FLAG_CE;
 
 	if (Default_Password) {
 		if (!fscrypt_unlock_user_key(user_id, 0, "!", "!")) {
diff --git a/crypto/fscrypt/Decrypt.h b/crypto/fscrypt/Decrypt.h
index 8fb5160..f397749 100755
--- a/crypto/fscrypt/Decrypt.h
+++ b/crypto/fscrypt/Decrypt.h
@@ -27,8 +27,8 @@
 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 << 0;
-static constexpr int STORAGE_FLAG_CE = 1 << 1;
+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);
diff --git a/crypto/fscrypt/EncryptInplace.cpp b/crypto/fscrypt/EncryptInplace.cpp
index 3755718..9d304da 100644
--- a/crypto/fscrypt/EncryptInplace.cpp
+++ b/crypto/fscrypt/EncryptInplace.cpp
@@ -391,6 +391,8 @@
     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;
@@ -423,9 +425,14 @@
 
     data.one_pct = data.tot_used_blocks / 100;
     data.cur_pct = 0;
-    data.time_started = time(NULL);
+    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";
diff --git a/crypto/fscrypt/EncryptInplace.h b/crypto/fscrypt/EncryptInplace.h
index bf0c314..a2b46cf 100644
--- a/crypto/fscrypt/EncryptInplace.h
+++ b/crypto/fscrypt/EncryptInplace.h
@@ -24,6 +24,11 @@
 #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);
diff --git a/crypto/fscrypt/FsCrypt.cpp b/crypto/fscrypt/FsCrypt.cpp
index ade9fe8..418164e 100755
--- a/crypto/fscrypt/FsCrypt.cpp
+++ b/crypto/fscrypt/FsCrypt.cpp
@@ -16,14 +16,14 @@
 
 #include "FsCrypt.h"
 
-#include "Keymaster.h"
 #include "KeyStorage.h"
 #include "KeyUtil.h"
 #include "Utils.h"
-// #include "VoldUtil.h"
+#include "VoldUtil.h"
 
 #include <algorithm>
 #include <map>
+#include <optional>
 #include <set>
 #include <sstream>
 #include <string>
@@ -40,10 +40,9 @@
 #include <unistd.h>
 
 #include <private/android_filesystem_config.h>
+#include <private/android_projectid_config.h>
 
-// #include "android/os/IVold.h"
-
-#include "cryptfs.h"
+#include "android/os/IVold.h"
 
 #define EMULATED_USES_SELINUX 0
 #define MANAGE_MISC_DIRS 0
@@ -52,37 +51,43 @@
 #include <cutils/properties.h>
 
 #include <fscrypt/fscrypt.h>
-#include <fs_mgr.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 android::vold::kEmptyAuthentication;
-using android::vold::KeyBuffer;
-using android::vold::Keymaster;
-using android::hardware::keymaster::V4_0::KeyFormat;
-// using android::vold::writeStringToFile;
+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;
 
-// Store main DE raw ref / policy
-std::string de_raw_ref;
-std::map<userid_t, std::string> s_de_key_raw_refs;
-std::map<userid_t, std::string> s_ce_key_raw_refs;
+// 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 {
 
-struct PolicyKeyRef {
-    std::string contents_mode;
-    std::string filenames_mode;
-    std::string key_raw_ref;
-};
-
 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";
@@ -93,21 +98,17 @@
 
 const std::string systemwide_volume_key_dir =
     std::string() + DATA_MNT_POINT + "/misc/vold/volume_keys";
-const int STORAGE_FLAG_DE = 1;
-const int STORAGE_FLAG_CE = 2;
-
-bool s_systemwide_keys_initialized = false;
-
-android::fs_mgr::Fstab fstab_default;
 
 // Some users are ephemeral, don't try to wipe their keys from disk
 std::set<userid_t> s_ephemeral_users;
 
-// TODO abolish this map, per b/26948053
-std::map<userid_t, KeyBuffer> s_ce_keys;
-
 }  // 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);
 }
@@ -143,7 +144,7 @@
             break;
         }
         if (entry->d_type != DT_DIR || entry->d_name[0] != 'c') {
-            LOG(DEBUG) << "Skipping non-key " << entry->d_name;
+            LOG(INFO) << "Skipping non-key " << entry->d_name;
             continue;
         }
         result.emplace_back(directory_path + "/" + entry->d_name);
@@ -179,29 +180,29 @@
                                const std::vector<std::string>& paths) {
     for (auto const other_path : paths) {
         if (other_path != to_fix) {
-            android::vold::destroyKey(other_path);
+            ::destroyKey(other_path);
         }
     }
     auto const current_path = get_ce_key_current_path(directory_path);
     if (to_fix != current_path) {
-        LOG(DEBUG) << "Renaming " << to_fix << " to " << 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;
         }
     }
-    android::vold::FsyncDirectory(directory_path);
+    ::FsyncDirectory(directory_path);
 }
 
 static bool read_and_fixate_user_ce_key(userid_t user_id,
-                                        const android::vold::KeyAuthentication& auth,
+                                        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(DEBUG) << "Trying user CE key " << ce_key_path;
-        if (android::vold::retrieveKey(ce_key_path, auth, ce_key)) {
-            LOG(DEBUG) << "Successfully retrieved key";
+        LOG(INFO) << "Trying user CE key " << ce_key_path;
+        if (retrieveKey(ce_key_path, auth, ce_key)) {
+            LOG(INFO) << "Successfully retrieved key";
             fixate_user_ce_key(directory_path, ce_key_path, paths);
             return true;
         }
@@ -210,65 +211,105 @@
     return false;
 }
 
-static bool is_wrapped_key_supported_common(const std::string& mount_point) {
-    LOG(DEBUG) << "Determining wrapped-key support for " << mount_point;
-    std::string wrapped_key_supported = android::base::GetProperty("fbe.data.wrappedkey", "false");
-    LOG(DEBUG) << "fbe.data.wrappedkey = " << wrapped_key_supported;
-    if (mount_point == DATA_MNT_POINT && wrapped_key_supported == "true") {
-        LOG(DEBUG) << "Wrapped key supported on " << mount_point;
-        return true;
-    } else {
+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 (!ReadDefaultFstab(&fstab_default)) {
+        PLOG(ERROR) << "Failed to open default fstab";
         return false;
     }
-}
-
-bool is_wrapped_key_supported() {
-    return is_wrapped_key_supported_common(DATA_MNT_POINT);
-}
-
-bool is_wrapped_key_supported_external() {
-    return false;
-}
-
-bool is_metadata_wrapped_key_supported_common(const std::string& mount_point) {
-	LOG(DEBUG) << "Determining metadata wrapped-key support for " << mount_point;
-	std::string wrapped_key_supported = android::base::GetProperty("fbe.metadata.wrappedkey", "false");
-	LOG(DEBUG) << "fbe.metadata.wrappedkey = " << wrapped_key_supported;
-    if (mount_point == METADATA_MNT_POINT && wrapped_key_supported == "true") {
-        LOG(DEBUG) << "Wrapped key supported on " << mount_point;
-        return true;
-    } else {
+    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->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;
 }
 
-bool is_metadata_wrapped_key_supported() {
-	return is_metadata_wrapped_key_supported_common(METADATA_MNT_POINT);
+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;
 }
 
 static bool read_and_install_user_ce_key(userid_t user_id,
-                                         const android::vold::KeyAuthentication& auth) {
-    if (s_ce_key_raw_refs.count(user_id) != 0) return true;
+                                         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;
-    std::string ce_raw_ref;
-    if (is_wrapped_key_supported()) {
-        KeyBuffer ephemeral_wrapped_key;
-        if (!getEphemeralWrappedKey(KeyFormat::RAW, ce_key, &ephemeral_wrapped_key)) {
-           LOG(ERROR) << "Failed to export ce key";
-           return false;
-        }
-        ce_key = std::move(ephemeral_wrapped_key);
-    }
-    if (!android::vold::installKey(ce_key, &ce_raw_ref)) return false;
-    s_ce_keys[user_id] = std::move(ce_key);
-    s_ce_key_raw_refs[user_id] = ce_raw_ref;
-    LOG(DEBUG) << "Installed ce key for user " << user_id;
+    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(DEBUG) << "Preparing: " << dir;
+    LOG(INFO) << "Preparing: " << dir;
     if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
         PLOG(ERROR) << "Failed to prepare " << dir;
         return false;
@@ -277,7 +318,7 @@
 }
 
 static bool destroy_dir(const std::string& dir) {
-    LOG(DEBUG) << "Destroying: " << dir;
+    LOG(INFO) << "Destroying: " << dir;
     if (rmdir(dir.c_str()) != 0 && errno != ENOENT) {
         PLOG(ERROR) << "Failed to destroy " << dir;
         return false;
@@ -288,16 +329,12 @@
 // 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(is_wrapped_key_supported()) {
-        if (!generateWrappedKey(user_id, android::vold::KeyType::DE_USER, &de_key)) return false;
-        if (!generateWrappedKey(user_id, android::vold::KeyType::CE_USER, &ce_key)) return false;
-    } else {
-        if (!android::vold::randomKey(&de_key)) return false;
-        if (!android::vold::randomKey(&ce_key)) return false;
-    }
-
+    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);
@@ -307,81 +344,37 @@
         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 (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, kEmptyAuthentication,
+        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 (!android::vold::storeKeyAtomically(get_de_key_path(user_id), user_key_temp,
+        if (!::storeKeyAtomically(get_de_key_path(user_id), user_key_temp,
                                                kEmptyAuthentication, de_key))
             return false;
     }
-
-    std::string ce_raw_ref;
-    if (is_wrapped_key_supported()) {
-        KeyBuffer ephemeral_wrapped_de_key;
-        KeyBuffer ephemeral_wrapped_ce_key;
-
-        /* Export and install the DE keys */
-        if (!getEphemeralWrappedKey(KeyFormat::RAW, de_key, &ephemeral_wrapped_de_key)) {
-           LOG(ERROR) << "Failed to export de_key";
-           return false;
-        }
-        /* Export and install the CE keys */
-        if (!getEphemeralWrappedKey(KeyFormat::RAW, ce_key, &ephemeral_wrapped_ce_key)) {
-           LOG(ERROR) << "Failed to export de_key";
-           return false;
-        }
-
-        de_key = std::move(ephemeral_wrapped_de_key);
-        ce_key = std::move(ephemeral_wrapped_ce_key);
-    }
-    if (!android::vold::installKey(de_key, &de_raw_ref)) return false;
-    if (!android::vold::installKey(ce_key, &ce_raw_ref)) return false;
-    s_ce_keys[user_id] = std::move(ce_key);
-
-    s_de_key_raw_refs[user_id] = de_raw_ref;
-    s_ce_key_raw_refs[user_id] = ce_raw_ref;
-
-    LOG(DEBUG) << "Created keys for user " << user_id;
+    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_key_ref(const std::map<userid_t, std::string>& 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) {
     auto refi = key_map.find(user_id);
     if (refi == key_map.end()) {
-        LOG(DEBUG) << "Cannot find key for " << user_id;
+        LOG(ERROR) << "Cannot find key for " << user_id;
         return false;
     }
-    *raw_ref = refi->second;
+    *policy = refi->second;
     return true;
 }
 
-static void get_data_file_encryption_modes(PolicyKeyRef* key_ref) {
-    if (!ReadDefaultFstab(&fstab_default)) {
-        PLOG(ERROR) << "Failed to open default fstab";
-        return;
-    }
-    /*auto entry = android::fs_mgr::GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
-    if (entry == nullptr) {
-        LOG(ERROR) << "get_data_file_encryption_modes::failed\n";
-        return;
-    }*/
-    LOG(INFO) << "contents mode '" << android::base::GetProperty("fbe.contents", "aes-256-xts") << "' filenames '" << android::base::GetProperty("fbe.filenames", "aes-256-heh") << "'\n";
-    key_ref->contents_mode =
-        android::base::GetProperty("fbe.contents", "aes-256-xts");
-    key_ref->filenames_mode =
-        android::base::GetProperty("fbe.filenames", "aes-256-heh");
-}
-
-static bool ensure_policy(const PolicyKeyRef& key_ref, const std::string& path) {
-	return true;
-    /*return fscrypt_policy_ensure(path.c_str(), key_ref.key_raw_ref.data(),
-                                 key_ref.key_raw_ref.size(), key_ref.contents_mode.c_str(),
-                                 key_ref.filenames_mode.c_str()) == 0;*/
-}
-
 static bool is_numeric(const char* name) {
     for (const char* p = name; *p != '\0'; p++) {
         if (!isdigit(*p)) return false;
@@ -390,6 +383,9 @@
 }
 
 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) {
@@ -407,86 +403,92 @@
             break;
         }
         if (entry->d_type != DT_DIR || !is_numeric(entry->d_name)) {
-            LOG(DEBUG) << "Skipping non-de-key " << entry->d_name;
+            LOG(INFO) << "Skipping non-de-key " << entry->d_name;
             continue;
         }
         userid_t user_id = std::stoi(entry->d_name);
-        if (s_de_key_raw_refs.count(user_id) == 0) {
-            auto key_path = de_dir + "/" + entry->d_name;
-            KeyBuffer key;
-            if (!android::vold::retrieveKey(key_path, kEmptyAuthentication, &key)) return false;
-            std::string raw_ref;
-            if (is_wrapped_key_supported()) {
-                KeyBuffer ephemeral_wrapped_key;
-                if (!getEphemeralWrappedKey(KeyFormat::RAW, key, &ephemeral_wrapped_key)) {
-                   LOG(ERROR) << "Failed to export de_key in create_and_install_user_keys";
-                   return false;
-                }
-                key = std::move(ephemeral_wrapped_key);
-            }
-            if (!android::vold::installKey(key, &raw_ref)) return false;
-            s_de_key_raw_refs[user_id] = raw_ref;
-            LOG(DEBUG) << "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");
+        auto key_path = de_dir + "/" + entry->d_name;
+        KeyBuffer de_key;
+        if (!retrieveKey(key_path, kEmptyAuthentication, &de_key)) 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";
-    bool wrapped_key_supported = false;
 
-    if (s_systemwide_keys_initialized) {
-        LOG(INFO) << "Already initialized";
-        return true;
-    }
+    EncryptionOptions options;
+    if (!get_data_file_encryption_options(&options)) return false;
 
-    PolicyKeyRef device_ref;
-    wrapped_key_supported = is_wrapped_key_supported();
-
-    if (!android::vold::retrieveAndInstallKey(true, kEmptyAuthentication,
-                       device_key_path, device_key_temp,
-                           &device_ref.key_raw_ref, wrapped_key_supported))
+    KeyBuffer device_key;
+    if (!retrieveOrGenerateKey(device_key_path, device_key_temp, kEmptyAuthentication,
+                               makeGen(options), &device_key))
         return false;
-    get_data_file_encryption_modes(&device_ref);
 
-    std::string modestring = device_ref.contents_mode + ":" + device_ref.filenames_mode;
-    std::string mode_filename = std::string("/data") + fscrypt_key_mode;
-    if (!android::vold::writeStringToFile(modestring, mode_filename)) return false;
+    EncryptionPolicy device_policy;
+    if (!install_storage_key(DATA_MNT_POINT, options, device_key, &device_policy)) return false;
 
-    std::string ref_filename = std::string("/data") + fscrypt_key_ref;
-    if (!android::vold::writeStringToFile(device_ref.key_raw_ref, ref_filename)) 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 (!android::vold::randomKey(&per_boot_key)) return false;
-    std::string per_boot_raw_ref;
-    if (!android::vold::installKey(per_boot_key, &per_boot_raw_ref)) return false;
+    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 (!android::vold::writeStringToFile(per_boot_raw_ref, per_boot_ref_filename)) return false;
+    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 (!android::vold::FsyncDirectory(device_key_dir)) return false;
-    s_systemwide_keys_initialized = true;
-    de_raw_ref = device_ref.key_raw_ref;
+    if (!::FsyncDirectory(device_key_dir)) return false;
     return true;
 }
 
 bool fscrypt_init_user0() {
-	if (!ReadDefaultFstab(&fstab_default)) {
+    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 (!android::vold::pathExists(get_de_key_path(0))) {
+        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
@@ -496,26 +498,37 @@
     // 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.
-    if (!fscrypt_prepare_user_storage("", 0, 0, STORAGE_FLAG_DE)) {
+    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(DEBUG) << "fscrypt_vold_create_user_key for " << user_id << " serial " << serial;
+    LOG(INFO) << "fscrypt_vold_create_user_key for " << user_id << " serial " << serial;
     if (!fscrypt_is_native()) {
-        return true;
+        return true; 
     }
     // FIXME test for existence of key that is not loaded yet
-    if (s_ce_key_raw_refs.count(user_id) != 0) {
+    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?
@@ -527,49 +540,60 @@
     return true;
 }
 
-static void drop_caches() {
-    // Clean any dirty pages (otherwise they won't be dropped).
+// "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();
-    // Drop inode and page caches.
-    if (!android::vold::writeStringToFile("3", "/proc/sys/vm/drop_caches")) {
+    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) {
-    s_ce_keys.erase(user_id);
     bool success = true;
-    std::string raw_ref;
+    EncryptionPolicy policy;
     // If we haven't loaded the CE key, no need to evict it.
-    if (lookup_key_ref(s_ce_key_raw_refs, user_id, &raw_ref)) {
-        success &= android::vold::evictKey(raw_ref);
-        drop_caches();
+    if (lookup_policy(s_ce_policies, user_id, &policy)) {
+        success &= ::evictKey(DATA_MNT_POINT, policy);
+        drop_caches_if_needed();
     }
-    s_ce_key_raw_refs.erase(user_id);
+    s_ce_policies.erase(user_id);
     return success;
 }
 
 bool fscrypt_destroy_user_key(userid_t user_id) {
-    LOG(DEBUG) << "fscrypt_destroy_user_key(" << user_id << ")";
+    LOG(INFO) << "fscrypt_destroy_user_key(" << user_id << ")";
     if (!fscrypt_is_native()) {
         return true;
     }
     bool success = true;
-    std::string raw_ref;
     success &= evict_ce_key(user_id);
-    success &=
-        lookup_key_ref(s_de_key_raw_refs, user_id, &raw_ref) && android::vold::evictKey(raw_ref);
-    s_de_key_raw_refs.erase(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 &= android::vold::destroyKey(path);
+            success &= ::destroyKey(path);
         }
         auto de_key_path = get_de_key_path(user_id);
-        if (android::vold::pathExists(de_key_path)) {
-            success &= android::vold::destroyKey(de_key_path);
+        if (::pathExists(de_key_path)) {
+            success &= ::destroyKey(de_key_path);
         } else {
             LOG(INFO) << "Not present so not erasing: " << de_key_path;
         }
@@ -612,13 +636,25 @@
         *result = "";
         return true;
     }
-    if (android::vold::HexToStr(hex, *result) != 0) {
+    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";
 }
@@ -628,19 +664,18 @@
 }
 
 static bool read_or_create_volkey(const std::string& misc_path, const std::string& volume_uuid,
-                                  PolicyKeyRef* key_ref) {
+                                  EncryptionPolicy* policy) {
     auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
     std::string secdiscardable_hash;
-    bool wrapped_key_supported = false;
-    if (android::vold::pathExists(secdiscardable_path)) {
-        if (!android::vold::readSecdiscardable(secdiscardable_path, &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 (!android::vold::createSecdiscardable(secdiscardable_path, &secdiscardable_hash))
+        if (!::createSecdiscardable(secdiscardable_path, &secdiscardable_hash))
             return false;
     }
     auto key_path = volkey_path(misc_path, volume_uuid);
@@ -648,107 +683,72 @@
         PLOG(ERROR) << "Creating directories for: " << key_path;
         return false;
     }
-    android::vold::KeyAuthentication auth("", secdiscardable_hash);
-    wrapped_key_supported = is_wrapped_key_supported_external();
+    ::KeyAuthentication auth("", secdiscardable_hash);
 
-    if (!android::vold::retrieveAndInstallKey(true, auth, key_path, key_path + "_tmp",
-                                              &key_ref->key_raw_ref, wrapped_key_supported))
+    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;
-    key_ref->contents_mode =
-        android::base::GetProperty("ro.crypto.volume.contents_mode", "aes-256-xts");
-    key_ref->filenames_mode =
-        android::base::GetProperty("ro.crypto.volume.filenames_mode", "aes-256-heh");
+    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 (!android::vold::pathExists(path)) return true;
-    return android::vold::destroyKey(path);
+    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)) {
+        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)) {
+        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(DEBUG) << "fscrypt_add_user_key_auth " << user_id << " serial=" << serial
+    LOG(INFO) << "fscrypt_add_user_key_auth " << user_id << " serial=" << serial
                << " token_present=" << (token_hex != "!");
     if (!fscrypt_is_native()) return true;
-    if (s_ephemeral_users.count(user_id) != 0) return true;
-    std::string token, secret;
-    if (!parse_hex(token_hex, &token)) return false;
-    if (!parse_hex(secret_hex, &secret)) return false;
-    auto auth =
-        secret.empty() ? kEmptyAuthentication : android::vold::KeyAuthentication(token, secret);
-    auto const directory_path = get_ce_key_directory_path(user_id);
-    auto const paths = get_ce_key_paths(directory_path);
-
-    KeyBuffer ce_key;
-    if(is_wrapped_key_supported()) {
-        std::string ce_key_current_path = get_ce_key_current_path(directory_path);
-        if (android::vold::retrieveKey(ce_key_current_path, kEmptyAuthentication, &ce_key)) {
-            LOG(DEBUG) << "Successfully retrieved key";
-        } else {
-            if (android::vold::retrieveKey(ce_key_current_path, auth, &ce_key)) {
-                LOG(DEBUG) << "Successfully retrieved key";
-            }
-        }
-    } else {
-        auto it = s_ce_keys.find(user_id);
-        if (it == s_ce_keys.end()) {
-            LOG(ERROR) << "Key not loaded into memory, can't change for user " << user_id;
-            return false;
-        }
-        ce_key = it->second;
-    }
-
-    std::string ce_key_path;
-    if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
-    if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, auth, ce_key)) return false;
-    if (!android::vold::FsyncDirectory(directory_path)) return false;
-    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(DEBUG) << "fscrypt_clear_user_key_auth " << user_id << " serial=" << serial
+    LOG(INFO) << "fscrypt_clear_user_key_auth " << user_id << " serial=" << serial
                << " token_present=" << (token_hex != "!");
     if (!fscrypt_is_native()) return true;
-    if (s_ephemeral_users.count(user_id) != 0) return true;
-    std::string token, secret;
-
-    if (!parse_hex(token_hex, &token)) return false;
-    if (!parse_hex(secret_hex, &secret)) return false;
-
-    if (is_wrapped_key_supported()) {
-        auto const directory_path = get_ce_key_directory_path(user_id);
-        auto const paths = get_ce_key_paths(directory_path);
-
-        KeyBuffer ce_key;
-        std::string ce_key_current_path = get_ce_key_current_path(directory_path);
-
-        auto auth = android::vold::KeyAuthentication(token, secret);
-        /* Retrieve key while removing a pin. A secret is needed */
-        if (android::vold::retrieveKey(ce_key_current_path, auth, &ce_key)) {
-            LOG(DEBUG) << "Successfully retrieved key";
-        } else {
-            /* Retrieve key when going None to swipe and vice versa when a
-               synthetic password is present */
-            if (android::vold::retrieveKey(ce_key_current_path, kEmptyAuthentication, &ce_key)) {
-                LOG(DEBUG) << "Successfully retrieved key";
-            }
-        }
-
-        std::string ce_key_path;
-        if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
-        if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, kEmptyAuthentication, ce_key))
-            return false;
-    } else {
-        if(!fscrypt_add_user_key_auth(user_id, serial, "!", "!")) return false;
-    }
-    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(DEBUG) << "fscrypt_fixate_newest_user_key_auth " << 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);
@@ -764,18 +764,16 @@
 // 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(DEBUG) << "fscrypt_unlock_user_key " << user_id << " serial=" << serial
+    LOG(INFO) << "fscrypt_unlock_user_key " << user_id << " serial=" << serial
                << " token_present=" << (token_hex != "!");
     if (fscrypt_is_native()) {
-        if (s_ce_key_raw_refs.count(user_id) != 0) {
+        if (s_ce_policies.count(user_id) != 0) {
             LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
             return true;
         }
-        std::string token, secret;
-        if (!parse_hex(token_hex, &token)) return false;
-        if (!parse_hex(secret_hex, &secret)) return false;
-        android::vold::KeyAuthentication auth(token, secret);
-        if (!read_and_install_user_ce_key(user_id, auth)) {
+        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;
         }
@@ -783,10 +781,10 @@
         // 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(android::vold::BuildDataSystemCePath(user_id), 0771) ||
-            !emulated_unlock(android::vold::BuildDataMiscCePath(user_id), 01771) ||
-            !emulated_unlock(android::vold::BuildDataMediaCePath("", user_id), 0770) ||
-            !emulated_unlock(android::vold::BuildDataUserCePath("", user_id), 0771)) {
+        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;
         }
@@ -796,15 +794,15 @@
 
 // TODO: rename to 'evict' for consistency
 bool fscrypt_lock_user_key(userid_t user_id) {
-    LOG(DEBUG) << "fscrypt_lock_user_key " << 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(android::vold::BuildDataSystemCePath(user_id)) ||
-            !emulated_lock(android::vold::BuildDataMiscCePath(user_id)) ||
-            !emulated_lock(android::vold::BuildDataMediaCePath("", user_id)) ||
-            !emulated_lock(android::vold::BuildDataUserCePath("", user_id))) {
+        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;
         }
@@ -815,7 +813,7 @@
 
 static bool prepare_subdirs(const std::string& action, const std::string& volume_uuid,
                             userid_t user_id, int flags) {
-    if (0 != android::vold::ForkExecvp(
+    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";
@@ -826,20 +824,20 @@
 
 bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
                                   int flags) {
-    LOG(DEBUG) << "fscrypt_prepare_user_storage for volume " << escape_empty(volume_uuid)
+    LOG(INFO) << "fscrypt_prepare_user_storage for volume " << escape_empty(volume_uuid)
                << ", user " << user_id << ", serial " << serial << ", flags " << flags;
 
-    if (flags & STORAGE_FLAG_DE) {
+    if (flags & android::os::IVold::STORAGE_FLAG_DE) {
         // DE_sys key
-        auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
-        auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
-        auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
+        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 = android::vold::BuildDataSystemDePath(user_id);
-        auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
-        auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
-        auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
+        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;
@@ -855,28 +853,27 @@
             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()) {
-            PolicyKeyRef de_ref;
+            EncryptionPolicy de_policy;
             if (volume_uuid.empty()) {
-                if (!lookup_key_ref(s_de_key_raw_refs, user_id, &de_ref.key_raw_ref)) return false;
-                get_data_file_encryption_modes(&de_ref);
-                if (!ensure_policy(de_ref, system_de_path)) return false;
-                if (!ensure_policy(de_ref, misc_de_path)) return false;
-                if (!ensure_policy(de_ref, vendor_de_path)) return false;
+                if (!lookup_policy(s_de_policies, user_id, &de_policy)) return false;
+                if (!EnsurePolicy(de_policy, system_de_path)) return false;
+                if (!EnsurePolicy(de_policy, misc_de_path)) return false;
+                if (!EnsurePolicy(de_policy, vendor_de_path)) return false;
             } else {
-                if (!read_or_create_volkey(misc_de_path, volume_uuid, &de_ref)) return false;
+                if (!read_or_create_volkey(misc_de_path, volume_uuid, &de_policy)) return false;
             }
-            if (!ensure_policy(de_ref, user_de_path)) return false;
+            if (!EnsurePolicy(de_policy, user_de_path)) return false;
         }
     }
-    if (flags & STORAGE_FLAG_CE) {
+
+    if (flags & android::os::IVold::STORAGE_FLAG_CE) {
         // CE_n key
-        auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
-        auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
-        auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
-        auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
-        auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
+        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;
@@ -884,31 +881,30 @@
             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()) {
-            PolicyKeyRef ce_ref;
+            EncryptionPolicy ce_policy;
             if (volume_uuid.empty()) {
-                if (!lookup_key_ref(s_ce_key_raw_refs, user_id, &ce_ref.key_raw_ref)) return false;
-                get_data_file_encryption_modes(&ce_ref);
-                if (!ensure_policy(ce_ref, system_ce_path)) return false;
-                if (!ensure_policy(ce_ref, misc_ce_path)) return false;
-                if (!ensure_policy(ce_ref, vendor_ce_path)) return false;
-
+                if (!lookup_policy(s_ce_policies, user_id, &ce_policy)) return false;
+                if (!EnsurePolicy(ce_policy, system_ce_path)) return false;
+                if (!EnsurePolicy(ce_policy, misc_ce_path)) return false;
+                if (!EnsurePolicy(ce_policy, vendor_ce_path)) return false;
             } else {
-                if (!read_or_create_volkey(misc_ce_path, volume_uuid, &ce_ref)) return false;
+                if (!read_or_create_volkey(misc_ce_path, volume_uuid, &ce_policy)) return false;
             }
-            if (!ensure_policy(ce_ref, media_ce_path)) return false;
-            if (!ensure_policy(ce_ref, user_ce_path)) return false;
+            if (!EnsurePolicy(ce_policy, media_ce_path)) return false;
+            if (!EnsurePolicy(ce_policy, user_ce_path)) return false;
         }
 
         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
-            android::vold::RestoreconRecursive(system_ce_path);
-            android::vold::RestoreconRecursive(vendor_ce_path);
-            android::vold::RestoreconRecursive(misc_ce_path);
+            ::RestoreconRecursive(system_ce_path);
+            ::RestoreconRecursive(vendor_ce_path);
+            ::RestoreconRecursive(misc_ce_path);
         }
     }
     if (!prepare_subdirs("prepare", volume_uuid, user_id, flags)) return false;
@@ -917,19 +913,19 @@
 }
 
 bool fscrypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags) {
-    LOG(DEBUG) << "fscrypt_destroy_user_storage for volume " << escape_empty(volume_uuid)
+    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 & STORAGE_FLAG_CE) {
+    if (flags & android::os::IVold::STORAGE_FLAG_CE) {
         // CE_n key
-        auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
-        auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
-        auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
-        auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
-        auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
+        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);
@@ -944,17 +940,17 @@
         }
     }
 
-    if (flags & STORAGE_FLAG_DE) {
+    if (flags & android::os::IVold::STORAGE_FLAG_DE) {
         // DE_sys key
-        auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
-        auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
-        auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
+        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 = android::vold::BuildDataSystemDePath(user_id);
-        auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
-        auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
-        auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
+        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()) {
@@ -994,7 +990,7 @@
             break;
         }
         if (entry->d_type != DT_DIR || entry->d_name[0] == '.') {
-            LOG(DEBUG) << "Skipping non-user " << entry->d_name;
+            LOG(INFO) << "Skipping non-user " << entry->d_name;
             continue;
         }
         res &= destroy_volkey(directory_path + "/" + entry->d_name, volume_uuid);
@@ -1004,10 +1000,21 @@
 
 bool fscrypt_destroy_volume_keys(const std::string& volume_uuid) {
     bool res = true;
-    LOG(DEBUG) << "fscrypt_destroy_volume_keys for volume " << escape_empty(volume_uuid);
+    LOG(INFO) << "fscrypt_destroy_volume_keys for volume " << escape_empty(volume_uuid);
     auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
-    res &= android::vold::runSecdiscardSingle(secdiscardable_path);
+    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
index c63e11f..f6db4b9 100755
--- a/crypto/fscrypt/FsCrypt.h
+++ b/crypto/fscrypt/FsCrypt.h
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
-#include <string>
 #include <map>
-#include <vector>
+#include <string>
 
+#include <fscrypt/fscrypt.h>
 #include <cutils/multiuser.h>
 
+using namespace android::fscrypt;
+
 bool fscrypt_initialize_systemwide_keys();
 
 bool fscrypt_init_user0();
@@ -27,8 +29,8 @@
 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_hex,
-                               const std::string& secret_hex);
+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,
@@ -40,8 +42,8 @@
 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 is_wrapped_key_supported();
-bool is_wrapped_key_supported_external();
-bool is_metadata_wrapped_key_supported();
-bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, userid_t user_id,
-                           std::string* raw_ref);
\ No newline at end of file
+
+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/KeyBuffer.h b/crypto/fscrypt/KeyBuffer.h
index 2087187..2de9ac9 100644
--- a/crypto/fscrypt/KeyBuffer.h
+++ b/crypto/fscrypt/KeyBuffer.h
@@ -21,8 +21,6 @@
 #include <memory>
 #include <vector>
 
-namespace android {
-namespace vold {
 
 /**
  * Variant of memset() that should never be optimized away. Borrowed from keymaster code.
@@ -56,8 +54,5 @@
 KeyBuffer operator+(KeyBuffer&& lhs, const KeyBuffer& rhs);
 KeyBuffer operator+(KeyBuffer&& lhs, const char* rhs);
 
-}  // namespace vold
-}  // namespace android
-
 #endif
 
diff --git a/crypto/fscrypt/KeyStorage.cpp b/crypto/fscrypt/KeyStorage.cpp
index 068c069..ad9d491 100755
--- a/crypto/fscrypt/KeyStorage.cpp
+++ b/crypto/fscrypt/KeyStorage.cpp
@@ -16,10 +16,10 @@
 
 #include "KeyStorage.h"
 
+#include "Checkpoint.h"
 #include "Keymaster.h"
 #include "ScryptParameters.h"
 #include "Utils.h"
-#include "Checkpoint.h"
 
 #include <thread>
 #include <vector>
@@ -37,23 +37,20 @@
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
-#include <android-base/unique_fd.h>
 #include <android-base/properties.h>
+#include <android-base/unique_fd.h>
 
 #include <cutils/properties.h>
 
 #include <hardware/hw_auth_token.h>
-#include <keymasterV4_0/authorization_set.h>
-#include <keymasterV4_0/keymaster_utils.h>
+#include <keymasterV4_1/authorization_set.h>
+#include <keymasterV4_1/keymaster_utils.h>
 
 extern "C" {
 
 #include "crypto_scrypt.h"
 }
 
-namespace android {
-namespace vold {
-
 const KeyAuthentication kEmptyAuthentication{"", ""};
 
 static constexpr size_t AES_KEY_BYTES = 32;
@@ -64,7 +61,6 @@
 static constexpr size_t STRETCHED_BYTES = 1 << 6;
 
 static constexpr uint32_t AUTH_TIMEOUT = 30;  // Seconds
-constexpr int EXT4_AES_256_XTS_KEY_SIZE = 64;
 
 static const char* kCurrentVersion = "1";
 static const char* kRmPath = "/system/bin/rm";
@@ -123,70 +119,42 @@
             return false;
         }
         const hw_auth_token_t* at = reinterpret_cast<const hw_auth_token_t*>(auth.token.data());
-        paramBuilder.Authorization(km::TAG_USER_SECURE_ID, at->user_id);
+        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);
     }
-    return keymaster.generateKey(paramBuilder, key);
+
+    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 generateWrappedKey(userid_t user_id, KeyType key_type,
-                                     KeyBuffer* key) {
+bool generateWrappedStorageKey(KeyBuffer* key) {
     Keymaster keymaster;
     if (!keymaster) return false;
-    *key = KeyBuffer(EXT4_AES_256_XTS_KEY_SIZE);
     std::string key_temp;
-    auto paramBuilder = km::AuthorizationSetBuilder()
-                               .AesEncryptionKey(AES_KEY_BYTES * 8)
-                               .GcmModeMinMacLen(GCM_MAC_BYTES * 8)
-                               .Authorization(km::TAG_USER_ID, user_id);
-    km::KeyParameter param1;
-    param1.tag = (km::Tag) (android::hardware::keymaster::V4_0::KM_TAG_FBE_ICE);
-    param1.f.boolValue = true;
-    paramBuilder.push_back(param1);
-
-    km::KeyParameter param2;
-    if ((key_type == KeyType::DE_USER) || (key_type == KeyType::DE_SYS || (key_type == KeyType::ME))) {
-        param2.tag = (km::Tag) (android::hardware::keymaster::V4_0::KM_TAG_KEY_TYPE);
-        param2.f.integer = 0;
-    } else if (key_type == KeyType::CE_USER) {
-        param2.tag = (km::Tag) (android::hardware::keymaster::V4_0::KM_TAG_KEY_TYPE);
-        param2.f.integer = 1;
-    }
-    paramBuilder.push_back(param2);
-
+    auto paramBuilder = km::AuthorizationSetBuilder().AesEncryptionKey(AES_KEY_BYTES * 8);
+    paramBuilder.Authorization(km::TAG_ROLLBACK_RESISTANCE);
+    paramBuilder.Authorization(km::TAG_STORAGE_KEY);
     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 getEphemeralWrappedKey(km::KeyFormat format, KeyBuffer& kmKey, KeyBuffer* key) {
-    std::string key_temp;
+bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key) {
     Keymaster keymaster;
     if (!keymaster) return false;
+    std::string key_temp;
 
-    //Export once, if upgrade needed, upgrade and export again
-    bool export_again = true;
-    while (export_again) {
-        export_again = false;
-        auto ret = keymaster.exportKey(format, kmKey, "!", "!", &key_temp);
-        if (ret == km::ErrorCode::OK) {
-            *key = KeyBuffer(key_temp.size());
-            memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
-            return true;
-        }
-        if (ret != km::ErrorCode::KEY_REQUIRES_UPGRADE) return false;
-        LOG(DEBUG) << "Upgrading key";
-        std::string kmKeyStr(reinterpret_cast<const char*>(kmKey.data()), kmKey.size());
-        std::string newKey;
-        if (!keymaster.upgradeKey(kmKeyStr, km::AuthorizationSet(), &newKey)) return false;
-        memcpy(reinterpret_cast<void*>(kmKey.data()), newKey.c_str(), kmKey.size());
-        LOG(INFO) << "Key upgraded";
-        export_again = true;
-    }
-    //Should never come here
-    return false;
+    if (!keymaster.exportKey(kmKey, &key_temp)) 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(
@@ -212,7 +180,7 @@
 
 static bool readRandomBytesOrLog(size_t count, std::string* out) {
     auto status = ReadRandomBytes(count, *out);
-    if (status != OK) {
+    if (status != android::OK) {
         LOG(ERROR) << "Random read failed with status: " << status;
         return false;
     }
@@ -234,27 +202,26 @@
     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";
-//     }
-// }
+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) {
-    return true;
-    // bool needs_cp = cp_needsCheckpoint();
+    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);
-    // }
+    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,
@@ -283,7 +250,7 @@
         //         PLOG(ERROR) << "Unable to move upgraded key to location: " << kmKeyPath;
         //         return KeymasterOperation();
         //     }
-        //     if (!android::vold::FsyncDirectory(dir)) {
+        //     if (!::FsyncDirectory(dir)) {
         //         LOG(ERROR) << "Key dir sync failed: " << dir;
         //         return KeymasterOperation();
         //     }
@@ -292,7 +259,7 @@
         //     }
         // }
         kmKey = newKey;
-        LOG(INFO) << "Key upgraded in memory: " << dir;
+        LOG(INFO) << "Key upgraded: " << dir;
     }
 }
 
@@ -522,7 +489,7 @@
     if (!writeStringToFile(stretching, dir + "/" + kFn_stretching)) return false;
     std::string salt;
     if (stretchingNeedsSalt(stretching)) {
-        if (ReadRandomBytes(SALT_BYTES, salt) != OK) {
+        if (ReadRandomBytes(SALT_BYTES, salt) != android::OK) {
             LOG(ERROR) << "Random read failed";
             return false;
         }
@@ -561,7 +528,7 @@
         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 (!::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;
@@ -653,6 +620,3 @@
     success &= recursiveDeleteKey(dir);
     return success;
 }
-
-}  // namespace vold
-}  // namespace android
diff --git a/crypto/fscrypt/KeyStorage.h b/crypto/fscrypt/KeyStorage.h
index 9959ce6..b88cdc6 100755
--- a/crypto/fscrypt/KeyStorage.h
+++ b/crypto/fscrypt/KeyStorage.h
@@ -17,13 +17,10 @@
 #ifndef ANDROID_VOLD_KEYSTORAGE_H
 #define ANDROID_VOLD_KEYSTORAGE_H
 
-#include "Keymaster.h"
 #include "KeyBuffer.h"
-#include <cutils/multiuser.h>
+
 #include <string>
 
-namespace android {
-namespace vold {
 
 // Represents the information needed to decrypt a disk encryption key.
 // If "token" is nonempty, it is passed in as a required Gatekeeper auth token.
@@ -40,13 +37,6 @@
     const std::string secret;
 };
 
-enum class KeyType {
-    DE_SYS,
-    DE_USER,
-    CE_USER,
-	ME,
-};
-
 extern const KeyAuthentication kEmptyAuthentication;
 
 // Checks if path "path" exists.
@@ -76,9 +66,10 @@
 bool destroyKey(const std::string& dir);
 
 bool runSecdiscardSingle(const std::string& file);
-bool generateWrappedKey(userid_t user_id, KeyType key_type, KeyBuffer* key);
-bool getEphemeralWrappedKey(km::KeyFormat format, KeyBuffer& kmKey, KeyBuffer* key);
-}  // namespace vold
-}  // namespace android
+
+// 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
index fa40640..8ec389f 100755
--- a/crypto/fscrypt/KeyUtil.cpp
+++ b/crypto/fscrypt/KeyUtil.cpp
@@ -16,32 +16,31 @@
 
 #include "KeyUtil.h"
 
-#include <linux/fs.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.h"
+#include <fscrypt_uapi.h>
 #include "KeyStorage.h"
 #include "Utils.h"
 
-#define MAX_USER_ID 0xFFFFFFFF
 
-using android::hardware::keymaster::V4_0::KeyFormat;
-using android::vold::KeyType;
-namespace android {
-namespace vold {
+const KeyGeneration neverGen() {
+    return KeyGeneration{0, false, false};
+}
 
-constexpr int FS_AES_256_XTS_KEY_SIZE = 64;
-
-bool randomKey(KeyBuffer* key) {
-    *key = KeyBuffer(FS_AES_256_XTS_KEY_SIZE);
+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";
@@ -50,6 +49,56 @@
     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;
@@ -64,35 +113,39 @@
     unsigned char key_ref2[SHA512_DIGEST_LENGTH];
     SHA512_Final(key_ref2, &c);
 
-    static_assert(FS_KEY_DESCRIPTOR_SIZE <= SHA512_DIGEST_LENGTH, "Hash too short for descriptor");
-    return std::string((char*)key_ref2, FS_KEY_DESCRIPTOR_SIZE);
+    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() != FS_AES_256_XTS_KEY_SIZE) {
+    if (key.size() != FSCRYPT_MAX_KEY_SIZE) {
         LOG(ERROR) << "Wrong size key " << key.size();
         return false;
     }
-    static_assert(FS_AES_256_XTS_KEY_SIZE <= sizeof(fs_key->raw), "Key too long!");
-    fs_key->mode = FS_ENCRYPTION_MODE_AES_256_XTS;
-    fs_key->size = key.size();
-    memset(fs_key->raw, 0, sizeof(fs_key->raw));
+    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 keyname(const std::string& prefix, const std::string& raw_ref) {
+static std::string keyrefstring(const std::string& raw_ref) {
     std::ostringstream o;
-    o << prefix << ":";
     for (unsigned char i : raw_ref) {
         o << std::hex << std::setw(2) << std::setfill('0') << (int)i;
     }
     return o.str();
 }
 
-// Get the keyring we store all keys in
+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) {
@@ -102,44 +155,169 @@
     return true;
 }
 
-// Install password into global keyring
-// Return raw key reference for use in policy
-bool installKey(const KeyBuffer& key, std::string* raw_ref) {
+// 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;
-    if (is_wrapped_key_supported()) {
-        /* 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. */
-        *raw_ref = generateKeyRef(fs_key.raw, (fs_key.size)/2);
-    } else {
-        *raw_ref = generateKeyRef(fs_key.raw, fs_key.size);
-    }
     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 = keyname(*name_prefix, *raw_ref);
+        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(DEBUG) << "Added key " << key_id << " (" << ref << ") to keyring " << device_keyring
+        LOG(INFO) << "Added key " << key_id << " (" << ref << ") to keyring " << device_keyring
                    << " in process " << getpid();
     }
     return true;
 }
 
-bool evictKey(const std::string& raw_ref) {
+// 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.
+            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 = keyname(*name_prefix, raw_ref);
+        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
@@ -150,88 +328,110 @@
             PLOG(ERROR) << "Failed to unlink key with serial " << key_serial << " ref " << ref;
             success = false;
         } else {
-            LOG(DEBUG) << "Unlinked key with serial " << key_serial << " ref " << ref;
+            LOG(ERROR) << "Unlinked key with serial " << key_serial << " ref " << ref;
         }
     }
     return success;
 }
 
-bool retrieveAndInstallKey(bool create_if_absent, const KeyAuthentication& key_authentication,
-                           const std::string& key_path, const std::string& tmp_path,
-                           std::string* key_ref, bool wrapped_key_supported) {
-    KeyBuffer key;
-    if (pathExists(key_path)) {
-        LOG(DEBUG) << "Key exists, using: " << key_path;
-        if (!retrieveKey(key_path, key_authentication, &key)) return false;
-    } else {
-        if (!create_if_absent) {
-            LOG(ERROR) << "No key found in " << key_path;
-            return false;
-        }
-        LOG(INFO) << "Creating new key in " << key_path;
-        if (wrapped_key_supported) {
-            if(!generateWrappedKey(MAX_USER_ID, KeyType::DE_SYS, &key)) return false;
-        } else {
-            if (!randomKey(&key)) return false;
-        }
-        if (!storeKeyAtomically(key_path, tmp_path, key_authentication, key)) return false;
+static bool evictProvisioningKey(const std::string& ref) {
+    key_serial_t device_keyring;
+    if (!fscryptKeyring(&device_keyring)) {
+        return false;
     }
 
-    if (wrapped_key_supported) {
-        KeyBuffer ephemeral_wrapped_key;
-        if (!getEphemeralWrappedKey(KeyFormat::RAW, key, &ephemeral_wrapped_key)) {
-            LOG(ERROR) << "Failed to export key in retrieveAndInstallKey";
-            return false;
-        }
-        key = std::move(ephemeral_wrapped_key);
+    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 (!installKey(key, key_ref)) {
-        LOG(ERROR) << "Failed to install key in " << key_path;
+    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 retrieveKey(bool create_if_absent, const std::string& key_path, const std::string& tmp_path,
-                 KeyBuffer* key, bool keepOld) {
-    LOG(ERROR) << "retreiveKey1";
+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(ERROR) << "Key exists, using: " << key_path;
-        if (!retrieveKey(key_path, kEmptyAuthentication, key, keepOld)) return false;
-			if (is_metadata_wrapped_key_supported()) {
-				KeyBuffer ephemeral_wrapped_key;
-				if (!getEphemeralWrappedKey(KeyFormat::RAW, *key, &ephemeral_wrapped_key)) {
-					LOG(ERROR) << "Failed to export key for retrieved key";
-					return false;
-				}
-				*key = std::move(ephemeral_wrapped_key);
-			}
+        LOG(INFO) << "Key exists, using: " << key_path;
+        if (!retrieveKey(key_path, key_authentication, key, keepOld)) return false;
     } else {
-        if (!create_if_absent) {
+        if (!gen.allow_gen) {
             LOG(ERROR) << "No key found in " << key_path;
             return false;
         }
-        LOG(ERROR) << "Creating new key in " << key_path;
-        if (is_metadata_wrapped_key_supported()) {
-            if(!generateWrappedKey(MAX_USER_ID, KeyType::ME, key)) return false;
-        } else {
-            if (!randomKey(key)) return false;
-        }
-		LOG(ERROR) << "retrieveKey1";
-        if (!storeKeyAtomically(key_path, tmp_path,
-                kEmptyAuthentication, *key)) return false;
-	if (is_metadata_wrapped_key_supported()) {
-            KeyBuffer ephemeral_wrapped_key;
-            if (!getEphemeralWrappedKey(KeyFormat::RAW, *key, &ephemeral_wrapped_key)) {
-                LOG(ERROR) << "Failed to export key for generated key";
-                return false;
-            }
-            *key = std::move(ephemeral_wrapped_key);
-        }
+        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;
 }
 
-}  // namespace vold
-}  // namespace android
+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
index 2839b4a..dcfcde8 100755
--- a/crypto/fscrypt/KeyUtil.h
+++ b/crypto/fscrypt/KeyUtil.h
@@ -19,24 +19,65 @@
 
 #include "KeyBuffer.h"
 #include "KeyStorage.h"
-#include "Keymaster.h"
+
+#include <fscrypt/fscrypt.h>
 
 #include <memory>
 #include <string>
 
-namespace android {
-namespace vold {
 
-bool randomKey(KeyBuffer* key);
-bool installKey(const KeyBuffer& key, std::string* raw_ref);
-bool evictKey(const std::string& raw_ref);
-bool retrieveAndInstallKey(bool create_if_absent, const KeyAuthentication& key_authentication,
-                           const std::string& key_path, const std::string& tmp_path,
-                           std::string* key_ref, bool wrapped_key_supported);
-bool retrieveKey(bool create_if_absent, const std::string& key_path, const std::string& tmp_path,
-                 KeyBuffer* key, bool keepOld = true);
+using namespace android::fscrypt;
 
-}  // namespace vold
-}  // namespace android
+// 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
index 706181d..27353f1 100755
--- a/crypto/fscrypt/Keymaster.cpp
+++ b/crypto/fscrypt/Keymaster.cpp
@@ -3,7 +3,7 @@
  *
  * 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
+ * You may obtain a copy of the License at  
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -17,11 +17,9 @@
 #include "Keymaster.h"
 
 #include <android-base/logging.h>
-#include <keymasterV4_0/authorization_set.h>
-#include <keymasterV4_0/keymaster_utils.h>
+#include <keymasterV4_1/authorization_set.h>
+#include <keymasterV4_1/keymaster_utils.h>
 
-namespace android {
-namespace vold {
 
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
@@ -138,30 +136,25 @@
     return true;
 }
 
-km::ErrorCode Keymaster::exportKey(km::KeyFormat format, KeyBuffer& kmKey, const std::string& clientId,
-                          const std::string& appData, std::string* key) {
+bool Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) {
     auto kmKeyBlob = km::support::blob2hidlVec(std::string(kmKey.data(), kmKey.size()));
-    auto emptyAssign = NULL;
-    auto kmClientId = (clientId == "!") ? emptyAssign: km::support::blob2hidlVec(clientId);
-    auto kmAppData = (appData == "!") ? emptyAssign: km::support::blob2hidlVec(appData);
     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());
+        if (key)
+            key->assign(reinterpret_cast<const char*>(&exportedKeyBlob[0]), exportedKeyBlob.size());
     };
-    auto error = mDevice->exportKey(format, kmKeyBlob, kmClientId, kmAppData, hidlCb);
+    auto error = mDevice->exportKey(km::KeyFormat::RAW, kmKeyBlob, {}, {}, hidlCb);
     if (!error.isOk()) {
         LOG(ERROR) << "export_key failed: " << error.description();
-        return km::ErrorCode::UNKNOWN_ERROR;
+        return false;
     }
     if (km_error != km::ErrorCode::OK) {
         LOG(ERROR) << "export_key failed, code " << int32_t(km_error);
-        return km_error;
+        return false;
     }
-    return km::ErrorCode::OK;
+    return true;
 }
 
 bool Keymaster::deleteKey(const std::string& key) {
@@ -233,10 +226,22 @@
     return mDevice->halVersion().securityLevel != km::SecurityLevel::SOFTWARE;
 }
 
-}  // namespace vold
-}  // namespace android
-
-using namespace ::android::vold;
+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;
diff --git a/crypto/fscrypt/Keymaster.h b/crypto/fscrypt/Keymaster.h
index 429a0a6..c3da4c8 100644
--- a/crypto/fscrypt/Keymaster.h
+++ b/crypto/fscrypt/Keymaster.h
@@ -25,12 +25,21 @@
 
 #include <android-base/macros.h>
 #include <keymasterV4_1/Keymaster.h>
-#include <keymasterV4_0/authorization_set.h>
+#include <keymasterV4_1/authorization_set.h>
 
-namespace android {
-namespace vold {
+namespace km {
 
-namespace km = ::android::hardware::keymaster::V4_1;
+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.
@@ -102,9 +111,8 @@
     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);
-	// Export a key from keymaster.
-    km::ErrorCode exportKey(km::KeyFormat format, KeyBuffer& kmKey, const std::string& clientId,
-                   const std::string& appData, std::string* key);
+    // Exports a keymaster key with STORAGE_KEY tag wrapped with a per-boot ephemeral key
+    bool 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.
@@ -117,15 +125,16 @@
                              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:
-    std::unique_ptr<KmDevice> mDevice;
+    android::sp<KmDevice> mDevice;
     DISALLOW_COPY_AND_ASSIGN(Keymaster);
     static bool hmacKeyGenerated;
 };
 
-}  // namespace vold
-}  // namespace android
-
 // FIXME no longer needed now cryptfs is in C++.
 
 /*
diff --git a/crypto/fscrypt/MetadataCrypt.cpp b/crypto/fscrypt/MetadataCrypt.cpp
index 45f3af3..d875ff0 100755
--- a/crypto/fscrypt/MetadataCrypt.cpp
+++ b/crypto/fscrypt/MetadataCrypt.cpp
@@ -23,21 +23,21 @@
 #include <vector>
 
 #include <fcntl.h>
-#include <sys/ioctl.h>
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include <linux/dm-ioctl.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 "KeyStorage.h"
 #include "KeyUtil.h"
@@ -45,30 +45,64 @@
 #include "Utils.h"
 #include "VoldUtil.h"
 
-#define DM_CRYPT_BUF_SIZE 4096
 #define TABLE_LOAD_RETRIES 10
-#define DEFAULT_KEY_TARGET_TYPE "default-key"
+
 
 using android::fs_mgr::FstabEntry;
 using android::fs_mgr::GetEntryForMountPoint;
-using android::fs_mgr::ReadDefaultFstab;
-using android::vold::KeyBuffer;
+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(android::vold::sFsckContext)) {
+    if (setexeccon(::sFsckContext)) {
         PLOG(ERROR) << "Failed to setexeccon";
         return false;
     }
+
+    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,
-                                    false);
+                                    ::cp_needsCheckpoint(), true);
     if (setexeccon(nullptr)) {
         PLOG(ERROR) << "Failed to clear setexeccon";
         return false;
@@ -77,15 +111,10 @@
         LOG(ERROR) << "fs_mgr_do_mount failed with rc " << mount_rc;
         return false;
     }
-    LOG(DEBUG) << "Mounted " << mount_point;
+    LOG(INFO) << "mount_via_fs_mgr::Mounted " << mount_point;
     return true;
 }
 
-android::fs_mgr::Fstab fstab_default;
-
-namespace android {
-namespace vold {
-
 // 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) {
@@ -111,20 +140,20 @@
     LOG(INFO) << "Old Key deleted: " << dir;
 }
 
-static bool read_key(const FstabEntry& data_rec, bool create_if_absent, KeyBuffer* key) {
-    if (data_rec.key_dir.empty()) {
-        LOG(ERROR) << "Failed to get key_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 key_dir = data_rec.key_dir;
     std::string sKey;
-    auto dir = key_dir + "/key";
-    LOG(DEBUG) << "key_dir/key: " << dir;
+    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 = key_dir + "/tmp";
+    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,
@@ -134,152 +163,170 @@
     Keymaster keymaster;
     if (pathExists(newKeyPath)) {
         if (!android::base::ReadFileToString(newKeyPath, &sKey))
-            LOG(ERROR) << "Failed to read old key: " << dir;
+            LOG(ERROR) << "Failed to read incomplete key: " << dir;
         else if (!keymaster.deleteKey(sKey))
-            LOG(ERROR) << "Old key deletion failed, continuing anyway: " << dir;
+            LOG(ERROR) << "Incomplete key deletion failed, continuing anyway: " << dir;
         else
             unlink(newKeyPath.c_str());
     }
-    // bool needs_cp = cp_needsCheckpoint();
-    bool needs_cp = false;
-    if (!android::vold::retrieveKey(create_if_absent, dir, temp, key, needs_cp)) return false;
+    bool needs_cp = cp_needsCheckpoint();
+    if (!retrieveOrGenerateKey(dir, temp, kEmptyAuthentication, gen, key, needs_cp)) return false;
     if (needs_cp && pathExists(newKeyPath)) std::thread(commit_key, dir).detach();
     return true;
 }
 
-}  // namespace vold
-}  // namespace android
-
-static KeyBuffer default_key_params(const std::string& real_blkdev, const KeyBuffer& key) {
-    KeyBuffer hex_key;
-    if (android::vold::StrToHex(key, hex_key) != android::OK) {
-        LOG(ERROR) << "Failed to turn key to hex";
-        return KeyBuffer();
-    }
-    auto res = KeyBuffer() + "AES-256-XTS " + hex_key + " " + real_blkdev.c_str() + " 0";
-    return res;
-}
-
 static bool get_number_of_sectors(const std::string& real_blkdev, uint64_t* nr_sec) {
-    if (android::vold::GetBlockDev512Sectors(real_blkdev, nr_sec) != android::OK) {
+    if (::GetBlockDev512Sectors(real_blkdev, nr_sec) != android::OK) {
         PLOG(ERROR) << "Unable to measure size of " << real_blkdev;
         return false;
     }
     return true;
 }
 
-static struct dm_ioctl* dm_ioctl_init(char* buffer, size_t buffer_size, const std::string& dm_name) {
-    if (buffer_size < sizeof(dm_ioctl)) {
-        LOG(ERROR) << "dm_ioctl buffer too small";
-        return nullptr;
+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;
     }
 
-    memset(buffer, 0, buffer_size);
-    struct dm_ioctl* io = (struct dm_ioctl*)buffer;
-    io->data_size = buffer_size;
-    io->data_start = sizeof(struct dm_ioctl);
-    io->version[0] = 4;
-    io->version[1] = 0;
-    io->version[2] = 0;
-    io->flags = 0;
-    dm_name.copy(io->name, sizeof(io->name));
-    return io;
-}
-
-static bool create_crypto_blk_dev(const std::string& dm_name, uint64_t nr_sec,
-                                  const std::string& target_type, const KeyBuffer& crypt_params,
-                                  std::string* crypto_blkdev) {
-    android::base::unique_fd dm_fd(
-        TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC, 0)));
-    if (dm_fd == -1) {
-        PLOG(ERROR) << "Cannot open device-mapper";
+    KeyBuffer hex_key_buffer;
+    if (::StrToHex(module_key, hex_key_buffer) != android::OK) {
+        LOG(ERROR) << "Failed to turn key to hex";
         return false;
     }
-    alignas(struct dm_ioctl) char buffer[DM_CRYPT_BUF_SIZE];
-    auto io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
-    if (!io || ioctl(dm_fd.get(), DM_DEV_CREATE, io) != 0) {
-        PLOG(ERROR) << "Cannot create dm-crypt device " << dm_name;
-        return false;
-    }
+    std::string hex_key(hex_key_buffer.data(), hex_key_buffer.size());
 
-    // Get the device status, in particular, the name of its device file
-    io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
-    if (ioctl(dm_fd.get(), DM_DEV_STATUS, io) != 0) {
-        PLOG(ERROR) << "Cannot retrieve dm-crypt device status " << dm_name;
-        return false;
-    }
-    *crypto_blkdev = std::string() + "/dev/block/dm-" +
-                     std::to_string((io->dev & 0xff) | ((io->dev >> 12) & 0xfff00));
+    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();
 
-    io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
-    size_t paramix = io->data_start + sizeof(struct dm_target_spec);
-    size_t nullix = paramix + crypt_params.size();
-    size_t endix = (nullix + 1 + 7) & 8;  // Add room for \0 and align to 8 byte boundary
+    DmTable table;
+    table.AddTarget(std::move(target));
 
-    if (endix > sizeof(buffer)) {
-        LOG(ERROR) << "crypt_params too big for DM_CRYPT_BUF_SIZE";
-        return false;
-    }
-
-    io->target_count = 1;
-    auto tgt = (struct dm_target_spec*)(buffer + io->data_start);
-    tgt->status = 0;
-    tgt->sector_start = 0;
-    tgt->length = nr_sec;
-    target_type.copy(tgt->target_type, sizeof(tgt->target_type));
-    memcpy(buffer + paramix, crypt_params.data(),
-           std::min(crypt_params.size(), sizeof(buffer) - paramix));
-    buffer[nullix] = '\0';
-    tgt->next = endix;
-
+    auto& dm = DeviceMapper::Instance();
     for (int i = 0;; i++) {
-        if (ioctl(dm_fd.get(), DM_TABLE_LOAD, io) == 0) {
+        if (dm.CreateDevice(dm_name, table)) {
             break;
         }
         if (i + 1 >= TABLE_LOAD_RETRIES) {
-            PLOG(ERROR) << "DM_TABLE_LOAD ioctl failed";
+            PLOG(ERROR) << "Could not create default-key device " << dm_name;
             return false;
         }
-        PLOG(INFO) << "DM_TABLE_LOAD ioctl failed, retrying";
+        PLOG(INFO) << "Could not create default-key device, retrying";
         usleep(500000);
     }
 
-    // Resume this device to activate it
-    io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
-    if (ioctl(dm_fd.get(), DM_DEV_SUSPEND, io)) {
-        PLOG(ERROR) << "Cannot resume dm-crypt device " << dm_name;
+    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(ERROR) << "fscrypt_mount_metadata_encrypted: " << blk_device << " " << mount_point << " " << needs_encrypt;
-    // auto encrypted_state = android::base::GetProperty("ro.crypto.state", "");
-    // if (encrypted_state != "") {
-        // LOG(ERROR) << "fscrypt_enable_crypto got unexpected starting state: " << encrypted_state;
-        // return false;
-    // }
-
+    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 (!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";
+        LOG(ERROR) << "Failed to get data_rec for " << mount_point;
         return false;
     }
-    KeyBuffer key;
-    if (!read_key(*data_rec, needs_encrypt, &key)) return false;
-    uint64_t nr_sec;
-    if (!get_number_of_sectors(data_rec->blk_device, &nr_sec)) return false;
-    std::string crypto_blkdev;
-    if (!create_crypto_blk_dev(kDmNameUserdata, nr_sec, DEFAULT_KEY_TARGET_TYPE,
-                               default_key_params(blk_device, key), &crypto_blkdev))
+
+    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;
+        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;
@@ -297,8 +344,35 @@
         LOG(INFO) << "Inplace encryption complete";
     }
 
-    LOG(ERROR) << "Mounting metadata-encrypted filesystem:" << mount_point;
-    mount_via_fs_mgr(data_rec->mount_point.c_str(), crypto_blkdev.c_str());
+    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
index cd0f5e5..0370664 100644
--- a/crypto/fscrypt/MetadataCrypt.h
+++ b/crypto/fscrypt/MetadataCrypt.h
@@ -19,7 +19,17 @@
 
 #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
index 3d8e3d7..277d6a3 100644
--- a/crypto/fscrypt/Process.cpp
+++ b/crypto/fscrypt/Process.cpp
@@ -29,6 +29,7 @@
 #include <unistd.h>
 
 #include <fstream>
+#include <mntent.h>
 #include <unordered_set>
 
 #include <android-base/file.h>
@@ -81,6 +82,51 @@
     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;
 
diff --git a/crypto/fscrypt/Process.h b/crypto/fscrypt/Process.h
index 1406782..1c59812 100644
--- a/crypto/fscrypt/Process.h
+++ b/crypto/fscrypt/Process.h
@@ -21,6 +21,7 @@
 namespace vold {
 
 int KillProcessesWithOpenFiles(const std::string& path, int signal);
+int KillProcessesWithMounts(const std::string& path, int signal);
 
 }  // namespace vold
 }  // namespace android
diff --git a/crypto/fscrypt/Utils.cpp b/crypto/fscrypt/Utils.cpp
index aa71d8f..3b0eda0 100755
--- a/crypto/fscrypt/Utils.cpp
+++ b/crypto/fscrypt/Utils.cpp
@@ -29,23 +29,29 @@
 #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 <unistd.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
@@ -53,33 +59,47 @@
 #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;
 
-namespace android {
-namespace vold {
+struct selabel_handle* sehandle;
 
 security_context_t sBlkidContext = nullptr;
 security_context_t sBlkidUntrustedContext = nullptr;
 security_context_t sFsckContext = nullptr;
 security_context_t sFsckUntrustedContext = nullptr;
-struct selabel_handle* sehandle;
 
 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;
 
-status_t CreateDeviceNode(const std::string& path, dev_t dev) {
+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();
-    status_t res = 0;
+    android::status_t res = 0;
 
     char* secontext = nullptr;
     if (sehandle) {
@@ -105,16 +125,297 @@
     return res;
 }
 
-status_t DestroyDeviceNode(const std::string& path) {
+android::status_t DestroyDeviceNode(const std::string& path) {
     const char* cpath = path.c_str();
     if (TEMP_FAILURE_RETRY(unlink(cpath))) {
         return -errno;
     } else {
-        return OK;
+        return android::OK;
     }
 }
 
-status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid) {
+// 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();
 
@@ -133,68 +434,93 @@
     }
 
     if (res == 0) {
-        return OK;
+        return android::OK;
     } else {
         return -errno;
     }
 }
 
-status_t ForceUnmount(const std::string& path) {
+android::status_t ForceUnmount(const std::string& path) {
     const char* cpath = path.c_str();
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
-        return OK;
+        return android::OK;
     }
     // Apps might still be handling eject request, so wait before
     // we start sending signals
     if (sSleepOnUnmount) sleep(5);
 
-    KillProcessesWithOpenFiles(path, SIGINT);
+    android::vold::KillProcessesWithOpenFiles(path, SIGINT);
     if (sSleepOnUnmount) sleep(5);
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
-        return OK;
+        return android::OK;
     }
 
-    KillProcessesWithOpenFiles(path, SIGTERM);
+    android::vold::KillProcessesWithOpenFiles(path, SIGTERM);
     if (sSleepOnUnmount) sleep(5);
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
-        return OK;
+        return android::OK;
     }
 
-    KillProcessesWithOpenFiles(path, SIGKILL);
+    android::vold::KillProcessesWithOpenFiles(path, SIGKILL);
     if (sSleepOnUnmount) sleep(5);
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
-        return OK;
+        return android::OK;
     }
-
+    PLOG(INFO) << "ForceUnmount failed";
     return -errno;
 }
 
-status_t KillProcessesUsingPath(const std::string& path) {
-    if (KillProcessesWithOpenFiles(path, SIGINT) == 0) {
-        return OK;
+android::status_t KillProcessesWithMountPrefix(const std::string& path) {
+    if (android::vold::KillProcessesWithMounts(path, SIGINT) == 0) {
+        return android::OK;
     }
     if (sSleepOnUnmount) sleep(5);
 
-    if (KillProcessesWithOpenFiles(path, SIGTERM) == 0) {
-        return OK;
+    if (android::vold::KillProcessesWithMounts(path, SIGTERM) == 0) {
+        return android::OK;
     }
     if (sSleepOnUnmount) sleep(5);
 
-    if (KillProcessesWithOpenFiles(path, SIGKILL) == 0) {
-        return OK;
+    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 with open files
-    if (KillProcessesWithOpenFiles(path, SIGKILL) == 0) {
-        return OK;
+    // actually killed everyone mount
+    if (android::vold::KillProcessesWithMounts(path, SIGKILL) == 0) {
+        return android::OK;
     }
     PLOG(ERROR) << "Failed to kill processes using " << path;
     return -EBUSY;
 }
 
-status_t BindMount(const std::string& source, const std::string& target) {
+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;
     }
@@ -202,10 +528,10 @@
         PLOG(ERROR) << "Failed to bind mount " << source << " to " << target;
         return -errno;
     }
-    return OK;
+    return android::OK;
 }
 
-status_t Symlink(const std::string& target, const std::string& linkpath) {
+android::status_t Symlink(const std::string& target, const std::string& linkpath) {
     if (Unlink(linkpath) < 0) {
         return -errno;
     }
@@ -213,22 +539,22 @@
         PLOG(ERROR) << "Failed to create symlink " << linkpath << " to " << target;
         return -errno;
     }
-    return OK;
+    return android::OK;
 }
 
-status_t Unlink(const std::string& linkpath) {
+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 OK;
+    return android::OK;
 }
 
-status_t CreateDir(const std::string& dir, mode_t mode) {
+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 OK;
+            return android::OK;
         } else if (TEMP_FAILURE_RETRY(unlink(dir.c_str())) == -1) {
             PLOG(ERROR) << "Failed to unlink " << dir;
             return -errno;
@@ -241,7 +567,7 @@
         PLOG(ERROR) << "Failed to mkdir " << dir;
         return -errno;
     }
-    return OK;
+    return android::OK;
 }
 
 bool FindValue(const std::string& raw, const std::string& key, std::string* value) {
@@ -264,7 +590,7 @@
     return true;
 }
 
-static status_t readMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
+static android::status_t readMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
                              std::string* fsLabel, bool untrusted) {
     fsType->clear();
     fsUuid->clear();
@@ -283,8 +609,8 @@
     cmd.push_back(path);
 
     std::vector<std::string> output;
-    status_t res = ForkExecvp(cmd, &output, untrusted ? sBlkidUntrustedContext : sBlkidContext);
-    if (res != OK) {
+    android::status_t res = ForkExecvp(cmd, &output, untrusted ? sBlkidUntrustedContext : sBlkidContext);
+    if (res != android::OK) {
         LOG(WARNING) << "blkid failed to identify " << path;
         return res;
     }
@@ -296,15 +622,15 @@
         FindValue(line, "LABEL", fsLabel);
     }
 
-    return OK;
+    return android::OK;
 }
 
-status_t ReadMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
+android::status_t ReadMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
                       std::string* fsLabel) {
     return readMetadata(path, fsType, fsUuid, fsLabel, false);
 }
 
-status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, std::string* fsUuid,
+android::status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, std::string* fsUuid,
                                std::string* fsLabel) {
     return readMetadata(path, fsType, fsUuid, fsLabel, true);
 }
@@ -324,7 +650,7 @@
     return argv;
 }
 
-static status_t ReadLinesFromFdAndLog(std::vector<std::string>* output,
+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) {
@@ -337,10 +663,10 @@
         LOG(DEBUG) << line;
         if (output) output->emplace_back(line);
     }
-    return OK;
+    return android::OK;
 }
 
-status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>* output,
+android::status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>* output,
                     security_context_t context) {
     auto argv = ConvertToArgv(args);
 
@@ -365,7 +691,7 @@
         }
         pipe_write.reset();
         execvp(argv[0], const_cast<char**>(argv.data()));
-        PLOG(ERROR) << "exec in ForkExecvp" << " cmd: " << argv[0];
+        PLOG(ERROR) << "exec in ForkExecvp";
         _exit(EXIT_FAILURE);
     }
     if (pid == -1) {
@@ -390,7 +716,7 @@
         LOG(ERROR) << "Process exited with code: " << WEXITSTATUS(status);
         return WEXITSTATUS(status);
     }
-    return OK;
+    return android::OK;
 }
 
 pid_t ForkExecvpAsync(const std::vector<std::string>& args) {
@@ -413,12 +739,12 @@
     return pid;
 }
 
-status_t ReadRandomBytes(size_t bytes, std::string& out) {
+android::status_t ReadRandomBytes(size_t bytes, std::string& out) {
     out.resize(bytes);
     return ReadRandomBytes(bytes, &out[0]);
 }
 
-status_t ReadRandomBytes(size_t bytes, char* buf) {
+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;
@@ -432,15 +758,15 @@
     close(fd);
 
     if (bytes == 0) {
-        return OK;
+        return android::OK;
     } else {
         return -EIO;
     }
 }
 
-status_t GenerateRandomUuid(std::string& out) {
-    status_t res = ReadRandomBytes(16, out);
-    if (res == OK) {
+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        */
@@ -449,7 +775,7 @@
     return res;
 }
 
-status_t HexToStr(const std::string& hex, std::string& str) {
+android::status_t HexToStr(const std::string& hex, std::string& str) {
     str.clear();
     bool even = true;
     char cur = 0;
@@ -487,30 +813,30 @@
         }
         even = !even;
     }
-    return even ? OK : -EINVAL;
+    return even ? android::OK : -EINVAL;
 }
 
 static const char* kLookup = "0123456789abcdef";
 
-status_t StrToHex(const std::string& str, std::string& hex) {
+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 OK;
+    return android::OK;
 }
 
-status_t StrToHex(const KeyBuffer& str, KeyBuffer& hex) {
+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 OK;
+    return android::OK;
 }
 
-status_t NormalizeHex(const std::string& in, std::string& out) {
+android::status_t NormalizeHex(const std::string& in, std::string& out) {
     std::string tmp;
     if (HexToStr(in, tmp)) {
         return -EINVAL;
@@ -518,17 +844,17 @@
     return StrToHex(tmp, out);
 }
 
-status_t GetBlockDevSize(int fd, uint64_t* size) {
+android::status_t GetBlockDevSize(int fd, uint64_t* size) {
     if (ioctl(fd, BLKGETSIZE64, size)) {
         return -errno;
     }
 
-    return OK;
+    return android::OK;
 }
 
-status_t GetBlockDevSize(const std::string& path, uint64_t* size) {
+android::status_t GetBlockDevSize(const std::string& path, uint64_t* size) {
     int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
-    status_t res = OK;
+    android::status_t res = android::OK;
 
     if (fd < 0) {
         return -errno;
@@ -541,17 +867,17 @@
     return res;
 }
 
-status_t GetBlockDev512Sectors(const std::string& path, uint64_t* nr_sec) {
+android::status_t GetBlockDev512Sectors(const std::string& path, uint64_t* nr_sec) {
     uint64_t size;
-    status_t res = GetBlockDevSize(path, &size);
+    android::status_t res = GetBlockDevSize(path, &size);
 
-    if (res != OK) {
+    if (res != android::OK) {
         return res;
     }
 
     *nr_sec = size / 512;
 
-    return OK;
+    return android::OK;
 }
 
 uint64_t GetFreeBytes(const std::string& path) {
@@ -626,6 +952,19 @@
     }
 }
 
+// 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)) {
@@ -635,8 +974,13 @@
     return supported.find(fsType + "\n") != std::string::npos;
 }
 
-status_t WipeBlockDevice(const std::string& path) {
-    status_t res = -1;
+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};
 
@@ -646,7 +990,7 @@
         goto done;
     }
 
-    if (GetBlockDevSize(fd, &range[1]) != OK) {
+    if (GetBlockDevSize(fd, &range[1]) != android::OK) {
         PLOG(ERROR) << "Failed to determine size of " << path;
         goto done;
     }
@@ -759,7 +1103,7 @@
     }
 }
 
-status_t RestoreconRecursive(const std::string& path) {
+android::status_t RestoreconRecursive(const std::string& path) {
     LOG(DEBUG) << "Starting restorecon of " << path;
 
     static constexpr const char* kRestoreconString = "selinux.restorecon_recursive";
@@ -770,7 +1114,7 @@
     android::base::WaitForProperty(kRestoreconString, path);
 
     LOG(DEBUG) << "Finished restorecon of " << path;
-    return OK;
+    return android::OK;
 }
 
 bool Readlinkat(int dirfd, const std::string& path, std::string* result) {
@@ -796,11 +1140,42 @@
     }
 }
 
-bool IsRunningInEmulator() {
-    return android::base::GetBoolProperty("ro.kernel.qemu", false);
+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;
 }
 
-static status_t findMountPointsWithPrefix(const std::string& prefix,
+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
@@ -824,13 +1199,13 @@
             mountPoints.push_front(mountPoint);
         }
     }
-    return OK;
+    return android::OK;
 }
 
 // Unmount all mountpoints that start with prefix. prefix itself doesn't need to be a mountpoint.
-status_t UnmountTreeWithPrefix(const std::string& prefix) {
+android::status_t UnmountTreeWithPrefix(const std::string& prefix) {
     std::list<std::string> toUnmount;
-    status_t result = findMountPointsWithPrefix(prefix, toUnmount);
+    android::status_t result = findMountPointsWithPrefix(prefix, toUnmount);
     if (result < 0) {
         return result;
     }
@@ -843,23 +1218,23 @@
     return result;
 }
 
-status_t UnmountTree(const std::string& mountPoint) {
+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 OK;
+    return android::OK;
 }
 
-static status_t delete_dir_contents(DIR* dir) {
+static android::status_t delete_dir_contents(DIR* dir) {
     // Shamelessly borrowed from android::installd
     int dfd = dirfd(dir);
     if (dfd < 0) {
         return -errno;
     }
 
-    status_t result = OK;
+    android::status_t result = android::OK;
     struct dirent* de;
     while ((de = readdir(dir))) {
         const char* name = de->d_name;
@@ -899,8 +1274,8 @@
     return result;
 }
 
-status_t DeleteDirContentsAndDir(const std::string& pathname) {
-    status_t res = DeleteDirContents(pathname);
+android::status_t DeleteDirContentsAndDir(const std::string& pathname) {
+    android::status_t res = DeleteDirContents(pathname);
     if (res < 0) {
         return res;
     }
@@ -909,15 +1284,15 @@
         return -errno;
     }
     LOG(VERBOSE) << "Success: rmdir on " << pathname;
-    return OK;
+    return android::OK;
 }
 
-status_t DeleteDirContents(const std::string& pathname) {
+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 OK;
+            return android::OK;
         }
         PLOG(ERROR) << "Failed to opendir " << pathname;
         return -errno;
@@ -926,7 +1301,7 @@
 }
 
 // TODO(118708649): fix duplication with init/util.h
-status_t WaitForFile(const char* filename, std::chrono::nanoseconds timeout) {
+android::status_t WaitForFile(const char* filename, std::chrono::nanoseconds timeout) {
     android::base::Timer t;
     while (t.duration() < timeout) {
         struct stat sb;
@@ -985,5 +1360,263 @@
     return true;
 }
 
-}  // namespace vold
-}  // namespace android
+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
index af4e401..e820711 100755
--- a/crypto/fscrypt/Utils.h
+++ b/crypto/fscrypt/Utils.h
@@ -20,6 +20,7 @@
 #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>
@@ -30,8 +31,9 @@
 
 struct DIR;
 
-namespace android {
-namespace vold {
+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;
@@ -42,72 +44,93 @@
 // TODO remove this with better solution, b/64143519
 extern bool sSleepOnUnmount;
 
-status_t CreateDeviceNode(const std::string& path, dev_t dev);
-status_t DestroyDeviceNode(const std::string& path);
+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 */
-status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid);
+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 */
-status_t ForceUnmount(const std::string& path);
+android::status_t ForceUnmount(const std::string& path);
 
 /* Kills any processes using given path */
-status_t KillProcessesUsingPath(const std::string& 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 */
-status_t BindMount(const std::string& source, const std::string& target);
+android::status_t BindMount(const std::string& source, const std::string& target);
 
 /** Creates a symbolic link to target */
-status_t Symlink(const std::string& target, const std::string& linkpath);
+android::status_t Symlink(const std::string& target, const std::string& linkpath);
 
 /** Calls unlink(2) at linkpath */
-status_t Unlink(const std::string& linkpath);
+android::status_t Unlink(const std::string& linkpath);
 
 /** Creates the given directory if it is not already available */
-status_t CreateDir(const std::string& dir, mode_t mode);
+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 */
-status_t ReadMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
+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 */
-status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, std::string* fsUuid,
+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 */
-status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>* output = nullptr,
+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 */
-status_t GetBlockDevSize(int fd, uint64_t* size);
-status_t GetBlockDevSize(const std::string& path, uint64_t* size);
+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 */
-status_t GetBlockDev512Sectors(const std::string& path, uint64_t* nr_sec);
+android::status_t GetBlockDev512Sectors(const std::string& path, uint64_t* nr_sec);
 
-status_t ReadRandomBytes(size_t bytes, std::string& out);
-status_t ReadRandomBytes(size_t bytes, char* buffer);
-status_t GenerateRandomUuid(std::string& out);
+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 [ :-] */
-status_t HexToStr(const std::string& hex, std::string& str);
+android::status_t HexToStr(const std::string& hex, std::string& str);
 /* Converts raw bytes to hex string */
-status_t StrToHex(const std::string& str, std::string& hex);
+android::status_t StrToHex(const std::string& str, std::string& hex);
 /* Converts raw key bytes to hex string */
-status_t StrToHex(const KeyBuffer& str, KeyBuffer& hex);
+android::status_t StrToHex(const KeyBuffer& str, KeyBuffer& hex);
 /* Normalize given hex string into consistent format */
-status_t NormalizeHex(const std::string& in, std::string& out);
+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 */
-status_t WipeBlockDevice(const std::string& path);
+android::status_t WipeBlockDevice(const std::string& path);
 
 std::string BuildKeyPath(const std::string& partGuid);
 
@@ -128,26 +151,38 @@
 
 dev_t GetDevice(const std::string& path);
 
-status_t RestoreconRecursive(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);
 
-/* Checks if Android is running in QEMU */
-bool IsRunningInEmulator();
+// Handles dynamic major assignment for virtio-block
+bool IsVirtioBlkDevice(unsigned int major);
 
-status_t UnmountTreeWithPrefix(const std::string& prefix);
-status_t UnmountTree(const std::string& mountPoint);
+android::status_t UnmountTreeWithPrefix(const std::string& prefix);
+android::status_t UnmountTree(const std::string& mountPoint);
 
-status_t DeleteDirContentsAndDir(const std::string& pathname);
-status_t DeleteDirContents(const std::string& pathname);
+android::status_t DeleteDirContentsAndDir(const std::string& pathname);
+android::status_t DeleteDirContents(const std::string& pathname);
 
-status_t WaitForFile(const char* filename, std::chrono::nanoseconds timeout);
+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);
-}  // namespace vold
-}  // namespace android
+
+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.h b/crypto/fscrypt/VoldUtil.h
index 173c598..ce6b411 100644
--- a/crypto/fscrypt/VoldUtil.h
+++ b/crypto/fscrypt/VoldUtil.h
@@ -17,8 +17,7 @@
 #pragma once
 
 #include <fstab/fstab.h>
-#include <sys/cdefs.h>
 
 extern android::fs_mgr::Fstab fstab_default;
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+#define DATA_MNT_POINT "/data"
diff --git a/crypto/fscrypt/cryptfs.cpp b/crypto/fscrypt/cryptfs.cpp
new file mode 100644
index 0000000..b58c343
--- /dev/null
+++ b/crypto/fscrypt/cryptfs.cpp
@@ -0,0 +1,2902 @@
+/*
+ * 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
index a4fe87b..728b775 100644
--- a/crypto/fscrypt/cryptfs.h
+++ b/crypto/fscrypt/cryptfs.h
@@ -17,17 +17,7 @@
 #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 <string>
 
 #include <linux/types.h>
 #include <stdbool.h>
@@ -35,172 +25,10 @@
 
 #include <cutils/properties.h>
 
-/* The current cryptfs version */
-#define CURRENT_MAJOR_VERSION 1
-#define CURRENT_MINOR_VERSION 3
+#include "KeyBuffer.h"
+#include "KeyUtil.h"
 
 #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. */
-
-/* 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
-
-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];
-};
-
-#define DATA_MNT_POINT "/data"
-#define METADATA_MNT_POINT "/metadata"
 
 /* Return values for cryptfs_crypto_complete */
 #define CRYPTO_COMPLETE_NOT_ENCRYPTED 1
@@ -210,11 +38,6 @@
 #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 */
-
 /* Return values for cryptfs_getfield */
 #define CRYPTO_GETFIELD_OK 0
 #define CRYPTO_GETFIELD_ERROR_NO_FIELD (-1)
@@ -232,11 +55,8 @@
 #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 wait_and_unmount(const char* mountpoint, bool kill);
-
-typedef int (*kdf_func)(const char* passwd, const unsigned char* salt, unsigned char* ikey,
-                        void* params);
 
 int cryptfs_crypto_complete(void);
 int cryptfs_check_passwd(const char* pw);
@@ -245,9 +65,8 @@
 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 unsigned char* key,
-                             char* out_crypto_blkdev);
-int cryptfs_revert_ext_volume(const char* label);
+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);
@@ -255,8 +74,6 @@
 const char* cryptfs_get_password(void);
 void cryptfs_clear_password(void);
 int cryptfs_isConvertibleToFBE(void);
-
-uint32_t cryptfs_get_keysize();
-const char* cryptfs_get_crypto_name();
+const KeyGeneration cryptfs_get_keygen();
 
 #endif /* ANDROID_VOLD_CRYPTFS_H */
diff --git a/crypto/fscrypt/fscrypt-common.h b/crypto/fscrypt/fscrypt-common.h
new file mode 100755
index 0000000..e5733c6
--- /dev/null
+++ b/crypto/fscrypt/fscrypt-common.h
@@ -0,0 +1,5 @@
+#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
index 43d9552..99833f8 100755
--- a/crypto/fscrypt/fscrypt_policy.cpp
+++ b/crypto/fscrypt/fscrypt_policy.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include "fscrypt/fscrypt.h"
-
 #include <array>
 
 #include <asm/ioctl.h>
@@ -34,44 +32,23 @@
 #include <cutils/properties.h>
 #include <logwrap/logwrap.h>
 #include <utils/misc.h>
+#include <fscrypt/fscrypt.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");
 }
 
-static void log_ls(const char* dirname) {
-    std::array<const char*, 3> argv = {"ls", "-laZ", dirname};
-    int status = 0;
-    auto res =
-        android_fork_execvp(argv.size(), const_cast<char**>(argv.data()), &status, false, true);
-    if (res != 0) {
-        PLOG(ERROR) << argv[0] << " " << argv[1] << " " << argv[2] << "failed";
-        return;
-    }
-    if (!WIFEXITED(status)) {
-        LOG(ERROR) << argv[0] << " " << argv[1] << " " << argv[2]
-                   << " did not exit normally, status: " << status;
-        return;
-    }
-    if (WEXITSTATUS(status) != 0) {
-        LOG(ERROR) << argv[0] << " " << argv[1] << " " << argv[2]
-                   << " returned failure: " << WEXITSTATUS(status);
-        return;
-    }
-}
-
-extern "C" void policy_to_hex(const uint8_t* policy, char* hex) {
-    for (size_t i = 0, j = 0; i < FS_KEY_DESCRIPTOR_SIZE; i++) {
-        hex[j++] = HEX_LOOKUP[(policy[i] & 0xF0) >> 4];
-        hex[j++] = HEX_LOOKUP[policy[i] & 0x0F];
-    }
-    hex[FS_KEY_DESCRIPTOR_SIZE_HEX - 1] = '\0';
+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)
@@ -121,153 +98,6 @@
     return FS_POLICY_FLAGS_PAD_16;
 }
 
-static bool fscrypt_policy_set(const char *directory, uint8_t *policy,
-                               size_t policy_length,
-                               int contents_encryption_mode,
-                               int filenames_encryption_mode) {
-    if (policy_length != FS_KEY_DESCRIPTOR_SIZE) {
-        LOG(ERROR) << "Policy wrong length: " << policy_length;
-        return false;
-    }
-    char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-    policy_to_hex(policy, policy_hex);
-
-    int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open directory " << directory;
-        return false;
-    }
-
-    fscrypt_policy fp;
-    fp.version = 0;
-    fp.contents_encryption_mode = contents_encryption_mode;
-    fp.filenames_encryption_mode = filenames_encryption_mode;
-    fp.flags = fscrypt_get_policy_flags(filenames_encryption_mode);
-    memcpy(fp.master_key_descriptor, policy, FS_KEY_DESCRIPTOR_SIZE);
-    if (ioctl(fd, FS_IOC_SET_ENCRYPTION_POLICY, &fp)) {
-        PLOG(ERROR) << "Failed to set encryption policy for " << directory  << " to " << policy_hex
-            << " modes " << contents_encryption_mode << "/" << filenames_encryption_mode;
-        close(fd);
-        return false;
-    }
-    close(fd);
-
-    LOG(INFO) << "Policy for " << directory << " set to " << policy_hex
-        << " modes " << contents_encryption_mode << "/" << filenames_encryption_mode;
-    return true;
-}
-
-static bool fscrypt_policy_get(const char *directory, uint8_t *policy,
-                               size_t policy_length,
-                               int contents_encryption_mode,
-                               int filenames_encryption_mode) {
-    if (policy_length != FS_KEY_DESCRIPTOR_SIZE) {
-        LOG(ERROR) << "Policy wrong length: " << policy_length;
-        return false;
-    }
-
-    int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open directory " << directory;
-        return false;
-    }
-
-    fscrypt_policy fp;
-    memset(&fp, 0, sizeof(fscrypt_policy));
-    if (ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, &fp) != 0) {
-        PLOG(ERROR) << "Failed to get encryption policy for " << directory;
-        close(fd);
-        log_ls(directory);
-        return false;
-    }
-    close(fd);
-
-    if ((fp.version != 0)
-            || (fp.contents_encryption_mode != contents_encryption_mode)
-            || (fp.filenames_encryption_mode != filenames_encryption_mode)
-            || (fp.flags !=
-                fscrypt_get_policy_flags(filenames_encryption_mode))) {
-        LOG(ERROR) << "Failed to find matching encryption policy for " << directory;
-        return false;
-    }
-    memcpy(policy, fp.master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE);
-
-    return true;
-}
-
-static bool fscrypt_policy_check(const char *directory, uint8_t *policy,
-                                 size_t policy_length,
-                                 int contents_encryption_mode,
-                                 int filenames_encryption_mode) {
-    if (policy_length != FS_KEY_DESCRIPTOR_SIZE) {
-        LOG(ERROR) << "Policy wrong length: " << policy_length;
-        return false;
-    }
-    uint8_t existing_policy[FS_KEY_DESCRIPTOR_SIZE];
-    if (!fscrypt_policy_get(directory, existing_policy, FS_KEY_DESCRIPTOR_SIZE,
-                            contents_encryption_mode,
-                            filenames_encryption_mode)) return false;
-    char existing_policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-
-    policy_to_hex(existing_policy, existing_policy_hex);
-
-    if (memcmp(policy, existing_policy, FS_KEY_DESCRIPTOR_SIZE) != 0) {
-        char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-        policy_to_hex(policy, policy_hex);
-        LOG(ERROR) << "Found policy " << existing_policy_hex << " at " << directory
-                   << " which doesn't match expected value " << policy_hex;
-        log_ls(directory);
-        return false;
-    }
-    LOG(INFO) << "Found policy " << existing_policy_hex << " at " << directory
-              << " which matches expected value";
-    return true;
-}
-
-int fscrypt_policy_ensure(const char *directory, uint8_t *policy,
-                          size_t policy_length,
-                          const char *contents_encryption_mode,
-                          const char *filenames_encryption_mode) {
-    int contents_mode = 0;
-    int filenames_mode = 0;
-
-    if (!strcmp(contents_encryption_mode, "software") ||
-        !strcmp(contents_encryption_mode, "aes-256-xts")) {
-        contents_mode = FS_ENCRYPTION_MODE_AES_256_XTS;
-    } else if (!strcmp(contents_encryption_mode, "adiantum")) {
-        contents_mode = FS_ENCRYPTION_MODE_ADIANTUM;
-    } else if (!strcmp(contents_encryption_mode, "ice")) {
-        contents_mode = FS_ENCRYPTION_MODE_PRIVATE;
-    } else {
-        LOG(ERROR) << "Invalid file contents encryption mode: "
-                   << contents_encryption_mode;
-        return -1;
-    }
-
-    if (!strcmp(filenames_encryption_mode, "aes-256-cts")) {
-        filenames_mode = FS_ENCRYPTION_MODE_AES_256_CTS;
-    } else if (!strcmp(filenames_encryption_mode, "aes-256-heh")) {
-        filenames_mode = FS_ENCRYPTION_MODE_AES_256_HEH;
-    } else if (!strcmp(filenames_encryption_mode, "adiantum")) {
-        filenames_mode = FS_ENCRYPTION_MODE_ADIANTUM;
-    } else {
-        LOG(ERROR) << "Invalid file names encryption mode: "
-                   << filenames_encryption_mode;
-        return -1;
-    }
-
-    bool is_empty;
-    if (!is_dir_empty(directory, &is_empty)) return -1;
-    if (is_empty) {
-        if (!fscrypt_policy_set(directory, policy, policy_length,
-                                contents_mode, filenames_mode)) return -1;
-    } else {
-        if (!fscrypt_policy_check(directory, policy, policy_length,
-                                  contents_mode, filenames_mode)) return -1;
-    }
-    return 0;
-}
-
 extern "C" bool fscrypt_set_mode() {
     const char* mode_file = "/data/unencrypted/mode";
     struct stat st;
@@ -292,12 +122,10 @@
 
     std::string contents_encryption_mode_string = std::string(contents_encryption_mode);
     int pos = contents_encryption_mode_string.find(":");
-    PLOG(ERROR) << "contents_encryption_mode_string: " << contents_encryption_mode_string.substr(0, pos);
+    LOG(INFO) << "contents_encryption_mode_string: " << contents_encryption_mode_string.substr(0, pos);
 
-    // if (!strcmp(contents_encryption_mode, "software")) {
     if (contents_encryption_mode_string.substr(0, pos) == "software") {
         encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS;
-    // } else if (!strcmp(contents_encryption_mode, "ice")) {
     } else if (contents_encryption_mode_string.substr(0, pos) == "ice") {
         encryption_mode = FS_ENCRYPTION_MODE_PRIVATE;
     } else {
@@ -309,15 +137,11 @@
     return true;
 }
 
-extern "C" void fscrypt_policy_fill_default_struct(fscrypt_encryption_policy *fep) {
-	fep->version = 0;
-    fep->contents_encryption_mode = encryption_mode;
-    fep->filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS;
-    fep->flags = 0;
-    memset((void*)&fep->master_key_descriptor[0], 0, FS_KEY_DESCRIPTOR_SIZE);
-}
-
-extern "C" bool fscrypt_policy_set_struct(const char *directory, const fscrypt_encryption_policy *fep) {
+#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);
@@ -325,7 +149,6 @@
         return false;
     }
     if (ioctl(fd, FS_IOC_SET_ENCRYPTION_POLICY, fep)) {
-		printf("failed to set policy for '%s'\n", directory);
         PLOG(ERROR) << "Failed to set encryption policy for " << directory;
         close(fd);
         return false;
@@ -334,56 +157,30 @@
     return true;
 }
 
-extern "C" bool fscrypt_policy_get_struct(const char *directory, fscrypt_encryption_policy *fep) {
-    int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
+#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) {
-        printf("Failed to open '%s'\n", directory);
         PLOG(ERROR) << "Failed to open directory " << directory;
         return false;
     }
-    memset(fep, 0, sizeof(fscrypt_encryption_policy));
-    if (ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, fep) != 0) {
+#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};
+    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;
     }
-    printf("fscrypt_policy_get_struct::fep->version::%d\n", fep->version);
+    memcpy(fep, &ex_policy.policy.v2, sizeof(ex_policy.policy.v2));
     close(fd);
     return true;
 }
-
-extern "C" bool fscrypt_policy_set(const char *directory, uint8_t *policy,
-                               size_t policy_length, int contents_encryption_mode) {
-    if (contents_encryption_mode == 0)
-        contents_encryption_mode = encryption_mode;
-    if (policy_length != FS_KEY_DESCRIPTOR_SIZE) {
-		printf("policy wrong length\n");
-        LOG(ERROR) << "Policy wrong length: " << policy_length;
-        return false;
-    }
-    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;
-    }
-
-    fscrypt_encryption_policy fep;
-    fep.version = 0;
-    fep.contents_encryption_mode = contents_encryption_mode;
-    fep.filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS;
-    fep.flags = 0;
-    memcpy(fep.master_key_descriptor, policy, FS_KEY_DESCRIPTOR_SIZE);
-    if (ioctl(fd, FS_IOC_SET_ENCRYPTION_POLICY, &fep)) {
-		printf("failed to set policy for '%s' '%s'\n", directory, policy);
-        PLOG(ERROR) << "Failed to set encryption policy for " << directory;
-        close(fd);
-        return false;
-    }
-    close(fd);
-
-    char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-    policy_to_hex(policy, policy_hex);
-    LOG(INFO) << "Policy for " << directory << " set to " << policy_hex;
-    return true;
-}
diff --git a/crypto/fscrypt/fscrypt_policy.h b/crypto/fscrypt/fscrypt_policy.h
index 01fc419..c99ce2e 100755
--- a/crypto/fscrypt/fscrypt_policy.h
+++ b/crypto/fscrypt/fscrypt_policy.h
@@ -25,6 +25,7 @@
 __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)
 
 /* modes not supported by upstream kernel, so not in <linux/fs.h> */
 #define FS_ENCRYPTION_MODE_AES_256_HEH      126
@@ -42,22 +43,29 @@
 
 #define HEX_LOOKUP "0123456789abcdef"
 
-struct fscrypt_encryption_policy {
-  uint8_t version;
-  uint8_t contents_encryption_mode;
-  uint8_t filenames_encryption_mode;
-  uint8_t flags;
-  uint8_t master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
-} __attribute__((packed));
-
-
 bool fscrypt_set_mode();
-bool lookup_ref_key(const uint8_t *policy, uint8_t* policy_type);
+
+#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);
-void policy_to_hex(const uint8_t* policy, char* hex);
-bool fscrypt_policy_get_struct(const char *directory, struct fscrypt_encryption_policy *fep);
-bool fscrypt_policy_set_struct(const char *directory, const struct fscrypt_encryption_policy *fep);
-void fscrypt_policy_fill_default_struct(struct fscrypt_encryption_policy *fep);
+
+#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
index fae06f8..05e9d6f 100755
--- a/crypto/fscrypt/fscryptpolicyget.cpp
+++ b/crypto/fscrypt/fscryptpolicyget.cpp
@@ -18,16 +18,21 @@
 #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  {
-		fscrypt_encryption_policy fep;
+#ifdef USE_FSCRYPT_POLICY_V1
+		fscrypt_policy_v1 fep;
+#else
+		fscrypt_policy_v2 fep;
+#endif
 		if (fscrypt_policy_get_struct(argv[1], &fep)) {
-			char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-			policy_to_hex(fep.master_key_descriptor, policy_hex);
+			char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
+			bytes_to_hex(fep.master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
 			printf("%s\n", policy_hex);
 		} else {
 			printf("No policy set\n");
