diff --git a/crypto/ext4crypt/Android.mk b/crypto/ext4crypt/Android.mk
index 8b1dcd4..b32f384 100644
--- a/crypto/ext4crypt/Android.mk
+++ b/crypto/ext4crypt/Android.mk
@@ -5,7 +5,7 @@
 LOCAL_MODULE := libe4crypt
 LOCAL_MODULE_TAGS := eng optional
 LOCAL_CFLAGS :=
-LOCAL_SRC_FILES := Decrypt.cpp Ext4Crypt.cpp Keymaster.cpp KeyStorage.cpp ScryptParameters.cpp Utils.cpp HashPassword.cpp ext4_crypt.cpp
+LOCAL_SRC_FILES := Decrypt.cpp Ext4Crypt.cpp ScryptParameters.cpp Utils.cpp HashPassword.cpp ext4_crypt.cpp
 LOCAL_SHARED_LIBRARIES := libselinux libc libc++ libext4_utils libsoftkeymaster 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 hardware/libhardware/include/hardware system/security/softkeymaster/include/keymaster system/keymaster/include
@@ -14,6 +14,16 @@
     LOCAL_CFLAGS += -DTW_CRYPTO_HAVE_KEYMASTERX
     LOCAL_C_INCLUDES +=  external/boringssl/src/include
 endif
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26; echo $$?),0)
+    LOCAL_CFLAGS += -DUSE_KEYSTORAGE_3 -DHAVE_LIBKEYUTILS -DHAVE_SYNTH_PWD_SUPPORT -DHAVE_GATEKEEPER1
+    LOCAL_SRC_FILES += Keymaster3.cpp KeyStorage3.cpp
+    LOCAL_SHARED_LIBRARIES += android.hardware.keymaster@3.0 libkeystore_binder libhidlbase libutils libkeyutils libbinder
+    LOCAL_SHARED_LIBRARIES += android.hardware.gatekeeper@1.0
+    LOCAL_SRC_FILES += Weaver1.cpp
+    LOCAL_SHARED_LIBRARIES += android.hardware.weaver@1.0
+else
+    LOCAL_SRC_FILES += Keymaster.cpp KeyStorage.cpp
+endif
 
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/crypto/ext4crypt/Decrypt.cpp b/crypto/ext4crypt/Decrypt.cpp
index 3b69d46..2dab166 100644
--- a/crypto/ext4crypt/Decrypt.cpp
+++ b/crypto/ext4crypt/Decrypt.cpp
@@ -26,10 +26,50 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include "ext4_crypt.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_utils/ext4_crypt.h>
+
+#include <keystore/IKeystoreService.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <keystore/keystore.h>
+#include <keystore/authorization_set.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>
@@ -67,7 +107,7 @@
 
 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);
+        printf("Unexpected version %c\n", policy_type[0]);
         return false;
     }
     const char* ptr = policy_type + 1; // skip past the version number
@@ -94,6 +134,7 @@
     return true;
 }
 
+#ifndef HAVE_GATEKEEPER1
 int gatekeeper_device_initialize(gatekeeper_device_t **dev) {
 	int ret;
 	const hw_module_t *mod;
@@ -110,29 +151,7 @@
 		printf("failed to open gatekeeper\n");
 	return ret;
 }
-
-int Get_Password_Type(const userid_t user_id, std::string& filename) {
-	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";
-	struct stat st;
-	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;
-}
+#endif //ifndef HAVE_GATEKEEPER1
 
 bool Decrypt_DE() {
 	if (!e4crypt_initialize_global_de()) { // this deals with the overarching device encryption
@@ -146,6 +165,692 @@
 	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;
+}
+
+// The password data is stored in big endian and has to be swapped on little endian ARM
+template <class T>
+void endianswap(T *objp) {
+	unsigned char *memp = reinterpret_cast<unsigned char*>(objp);
+	std::reverse(memp, memp + sizeof(T));
+}
+
+/* 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);
+	} else {
+		printf("Get_Password_Data salt_len is 0\n");
+		return false;
+	}
+	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 1
+#define SYNTHETIC_PASSWORD_PASSWORD_BASED 0
+#define SYNTHETIC_PASSWORD_KEY_PREFIX "USRSKEY_synthetic_password_"
+
+/* 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) {
+	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;
+
+	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;
+
+	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))
+				continue;
+			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("keystoreid: '%s'\n", keystoreid.c_str());
+				found_subid = true;
+			}
+		}
+		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);
+	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) {
+	std::string disk_decryption_secret_key = "";
+
+	std::string keystore_alias_subid;
+	if (!Find_Keystore_Alias_SubID_And_Prep_Files(user_id, keystore_alias_subid)) {
+		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();
+	sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+	if (service == NULL) {
+		printf("error: could not connect to keystore service\n");
+		return disk_decryption_secret_key;
+	}
+
+	// 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;
+	}
+	const unsigned char* byteptr = (const unsigned char*)spblob_data.data();
+	if (*byteptr != SYNTHETIC_PASSWORD_VERSION) {
+		printf("SYNTHETIC_PASSWORD_VERSION does not match\n");
+		return disk_decryption_secret_key;
+	}
+	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
+	/* 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");
+
+	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 = SYNTHETIC_PASSWORD_KEY_PREFIX;
+	keystore_alias += keystore_alias_subid;
+	String16 keystore_alias16(keystore_alias.c_str());
+	::keystore::KeyPurpose purpose = ::keystore::KeyPurpose::DECRYPT;
+	OperationResult begin_result;
+	// 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);
+	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");
+	}
+	::keystore::hidl_vec<::keystore::KeyParameter> empty_params;
+	empty_params.resize(0);
+	OperationResult update_result;
+	// 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;
+	OperationResult finish_result;
+	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;
+}
+
+}}
+
+#define PASSWORD_TOKEN_SIZE 32
+
+bool Free_Return(bool retval, void* weaver_key, void* pwd_salt) {
+	if (weaver_key)
+		free(weaver_key);
+	if (pwd_salt)
+		free(pwd_salt);
+	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;
+
+	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.salt);
+	}
+	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.salt);
+	}
+	//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.salt);
+	}
+	//output_hex(&password_token[0], PASSWORD_TOKEN_SIZE);printf("\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");
+		// Fail over to gatekeeper path for Pixel 1???
+		return Free_Return(retval, weaver_key, pwd.salt);
+	}
+	// 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.salt);
+	}
+	// 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.salt);
+	}
+	// 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.salt);
+	} 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.salt);
+	}
+	//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
+	char application_id[PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH];
+	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
+	// 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);
+	if (!secret.size()) {
+		printf("failed to unwrapSyntheticPasswordBlob\n");
+		return Free_Return(retval, weaver_key, pwd.salt);
+	}
+	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.salt);
+	}
+	if (!e4crypt_prepare_user_storage(nullptr, user_id, 0, flags)) {
+		printf("failed to e4crypt_prepare_user_storage\n");
+		return Free_Return(retval, weaver_key, pwd.salt);
+	}
+	printf("Decrypted Successfully!\n");
+	retval = true;
+	return Free_Return(retval, weaver_key, pwd.salt);
+}
+#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
+		else if (pwd.password_type == 2) // In Android this means PIN or password
+			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;
@@ -167,8 +872,6 @@
 		flags = FLAG_STORAGE_DE;
 	else
 		flags = FLAG_STORAGE_CE;
-	gatekeeper_device_t *device;
-	ret = gatekeeper_device_initialize(&device);
 	if (Default_Password) {
 		if (!e4crypt_unlock_user_key(user_id, 0, "!", "!")) {
 			printf("e4crypt_unlock_user_key returned fail\n");
@@ -181,8 +884,15 @@
 		printf("Decrypted Successfully!\n");
 		return true;
 	}
-    if (ret!=0)
+	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));
@@ -194,13 +904,51 @@
 		return false;
 	}
     bool should_reenroll;
-    ret = device->verify(device, user_id, 0, (const uint8_t *)handle.c_str(), st.st_size,
+#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;
diff --git a/crypto/ext4crypt/Ext4Crypt.cpp b/crypto/ext4crypt/Ext4Crypt.cpp
index 8bc4199..ea5b1cf 100644
--- a/crypto/ext4crypt/Ext4Crypt.cpp
+++ b/crypto/ext4crypt/Ext4Crypt.cpp
@@ -41,8 +41,16 @@
 
 #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"
diff --git a/crypto/ext4crypt/HashPassword.cpp b/crypto/ext4crypt/HashPassword.cpp
index 86e067e..817c984 100644
--- a/crypto/ext4crypt/HashPassword.cpp
+++ b/crypto/ext4crypt/HashPassword.cpp
@@ -28,16 +28,37 @@
 #include <stdlib.h>
 #include <openssl/sha.h>
 
+#include "HashPassword.h"
+
 #define PASS_PADDING_SIZE 128
 #define SHA512_HEX_SIZE SHA512_DIGEST_LENGTH * 2
 
-std::string HashPassword(const std::string& Password) {
-	size_t size = PASS_PADDING_SIZE + Password.size();
+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);
-	const char* prefix = "Android FBE credential hash";
+	if (!buffer) return NULL; // failed to malloc
 	memcpy((void*)buffer, (void*)prefix, strlen(prefix));
 	unsigned char* ptr = buffer + PASS_PADDING_SIZE;
-	memcpy((void*)ptr, Password.c_str(), Password.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);
@@ -49,5 +70,15 @@
 		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 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
index d9b5ce5..8abd0de 100644
--- a/crypto/ext4crypt/HashPassword.h
+++ b/crypto/ext4crypt/HashPassword.h
@@ -19,6 +19,16 @@
 
 #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"
+
+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 HashPassword(const std::string& Password);
 
 #endif
diff --git a/crypto/ext4crypt/KeyStorage3.cpp b/crypto/ext4crypt/KeyStorage3.cpp
new file mode 100644
index 0000000..a07212d
--- /dev/null
+++ b/crypto/ext4crypt/KeyStorage3.cpp
@@ -0,0 +1,526 @@
+/*
+ * 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
new file mode 100644
index 0000000..bce6a99
--- /dev/null
+++ b/crypto/ext4crypt/KeyStorage3.h
@@ -0,0 +1,58 @@
+/*
+ * 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/Keymaster3.cpp b/crypto/ext4crypt/Keymaster3.cpp
new file mode 100644
index 0000000..c72ddd0
--- /dev/null
+++ b/crypto/ext4crypt/Keymaster3.cpp
@@ -0,0 +1,324 @@
+/*
+ * 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)
+{
+    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 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
new file mode 100644
index 0000000..4db8551
--- /dev/null
+++ b/crypto/ext4crypt/Keymaster3.h
@@ -0,0 +1,148 @@
+/*
+ * 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);*/
+
+__END_DECLS
+
+#endif
diff --git a/crypto/ext4crypt/Utils.h b/crypto/ext4crypt/Utils.h
index 8d0445d..aede203 100644
--- a/crypto/ext4crypt/Utils.h
+++ b/crypto/ext4crypt/Utils.h
@@ -24,6 +24,14 @@
 #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 {
 
diff --git a/crypto/ext4crypt/Weaver1.cpp b/crypto/ext4crypt/Weaver1.cpp
new file mode 100644
index 0000000..6d09ec9
--- /dev/null
+++ b/crypto/ext4crypt/Weaver1.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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
new file mode 100644
index 0000000..22f401e
--- /dev/null
+++ b/crypto/ext4crypt/Weaver1.h
@@ -0,0 +1,64 @@
+/*
+ * 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
index d217f18..05de86f 100644
--- a/crypto/ext4crypt/e4policyget.cpp
+++ b/crypto/ext4crypt/e4policyget.cpp
@@ -28,13 +28,10 @@
 		printf("Must specify a path\n");
 		return -1;
 	} else  {
-		char e4crypt_policy[EXT4_KEY_DESCRIPTOR_SIZE];
-		if (e4crypt_policy_get(argv[1], e4crypt_policy, EXT4_KEY_DESCRIPTOR_SIZE, 0))
-		{
-			char* ptr = tar_policy;
-			memset(tar_policy, 0, sizeof(tar_policy));
+		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(e4crypt_policy, policy_hex);
+			policy_to_hex(eep.master_key_descriptor, policy_hex);
 			printf("%s\n", policy_hex);
 		} else {
 			printf("No policy set\n");
diff --git a/crypto/ext4crypt/ext4_crypt.cpp b/crypto/ext4crypt/ext4_crypt.cpp
index 029db75..5a3b4b2 100644
--- a/crypto/ext4crypt/ext4_crypt.cpp
+++ b/crypto/ext4crypt/ext4_crypt.cpp
@@ -22,6 +22,7 @@
  */
 
 #include "ext4_crypt.h"
+#include "ext4crypt_tar.h"
 
 #include <dirent.h>
 #include <errno.h>
@@ -41,29 +42,13 @@
 #define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy"
 #define EXT4_KEYREF_DELIMITER ((char)'.')
 
-// 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
-
-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__));
-
 #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;
 
-// 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)
-
 #define HEX_LOOKUP "0123456789abcdef"
 
 extern "C" void policy_to_hex(const char* policy, char* hex) {
@@ -146,6 +131,48 @@
     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;
diff --git a/crypto/ext4crypt/ext4crypt_tar.h b/crypto/ext4crypt/ext4crypt_tar.h
index 1c9cef0..c35d115 100644
--- a/crypto/ext4crypt/ext4crypt_tar.h
+++ b/crypto/ext4crypt/ext4crypt_tar.h
@@ -21,8 +21,25 @@
 #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);
 
@@ -31,6 +48,9 @@
                                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
