/*
 * Copyright (C) 2016 - 2020 The TeamWin Recovery Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Decrypt.h"
#include "FsCrypt.h"

#include <map>
#include <string>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef HAVE_LIBKEYUTILS
#include "key_control.h"
#else
#include <keyutils.h>
#endif
#include "keystore_client.pb.h"
#include "Weaver1.h"
#include "cutils/properties.h"

#include <openssl/sha.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/rand.h>

#include <dirent.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <fstream>
#include <future>
#include <algorithm>

#include <android-base/file.h>
#include <base/threading/platform_thread.h>
#include <android/hardware/confirmationui/1.0/types.h>
#include <android/security/BnConfirmationPromptCallback.h>
#include <android/security/keystore/IKeystoreService.h>
#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>

#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <hardware/hw_auth_token.h>

#include <keystore/keystore.h>
#include <keystore/keystore_client.h>
#include <keystore/keystore_client_impl.h>
#include <keystore/KeystoreResponse.h>
#include <keystore/keystore_hidl_support.h>
#include <keystore/keystore_promises.h>
#include <keystore/keystore_return_types.h>
#include <keystore/keymaster_types.h>
#include <keymasterV4_0/Keymaster.h>
#include <keystore/OperationResult.h>
#include "keystore_client.pb.h"

#include <keymasterV4_0/authorization_set.h>
#include <keymasterV4_0/keymaster_utils.h>

extern "C" {
#include "crypto_scrypt.h"
}

#include "fscrypt_policy.h"
#include "HashPassword.h"
#include "KeyStorage.h"

using android::security::keystore::IKeystoreService;
using keystore::KeystoreResponsePromise;
using keystore::OperationResultPromise;
using android::security::keymaster::OperationResult;

// Store main DE raw ref / policy
extern std::string de_raw_ref;
extern std::map<userid_t, std::string> s_de_key_raw_refs;
extern std::map<userid_t, std::string> s_ce_key_raw_refs;

inline std::string hidlVec2String(const ::keystore::hidl_vec<uint8_t>& value) {
    return std::string(reinterpret_cast<const std::string::value_type*>(&value[0]), value.size());
}

static bool lookup_ref_key_internal(std::map<userid_t, std::string>& key_map, const uint8_t* policy, userid_t* user_id) {
	char policy_string_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
	char key_map_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
	policy_to_hex(policy, policy_string_hex);

    for (std::map<userid_t, std::string>::iterator it=key_map.begin(); it!=key_map.end(); ++it) {
		policy_to_hex(reinterpret_cast<const uint8_t*>(&it->second[0]), key_map_hex);
		std::string key_map_hex_string = std::string(key_map_hex);
		if (key_map_hex_string == policy_string_hex) {
            *user_id = it->first;
            return true;
        }
    }
    return false;
}

extern "C" bool lookup_ref_key(const uint8_t* policy, uint8_t* policy_type) {
    userid_t user_id = 0;
	char policy_string_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
	char de_raw_ref_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
	policy_to_hex(policy, policy_string_hex);
	policy_to_hex(reinterpret_cast<const uint8_t*>(&de_raw_ref[0]), de_raw_ref_hex);
	std::string de_raw_ref_hex_string = std::string(de_raw_ref_hex);

	std::string policy_type_string;
	if (policy_string_hex == de_raw_ref_hex_string) {
		policy_type_string = "0DK";
		memcpy(policy_type, policy_type_string.data(), policy_type_string.size());
		return true;
	}

    if (!lookup_ref_key_internal(s_de_key_raw_refs, policy, &user_id)) {
        if (!lookup_ref_key_internal(s_ce_key_raw_refs, policy, &user_id)) {
            return false;
		} else
			policy_type_string = "0CE" + std::to_string(user_id);
    } else
			policy_type_string = "0DE" + std::to_string(user_id);
	memcpy(policy_type, policy_type_string.data(), policy_type_string.size());
    return true;
}

extern "C" bool lookup_ref_tar(const uint8_t* policy_type, uint8_t* policy) {
	std::string policy_type_string = std::string((char *) policy_type);
	char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
	policy_to_hex(policy_type, policy_hex);

	// Current encryption fscrypt policy is v1 (which is stored as version 0e)
	if (policy_type_string.substr(0,1) != "0") {
        printf("Unexpected version %c\n", policy_type[0]);
        return false;
    }

	if (policy_type_string.substr(1, 2) == "DK") {
        memcpy(policy, de_raw_ref.data(), de_raw_ref.size());
        return true;
    }

	userid_t user_id = atoi(policy_type_string.substr(3, 4).c_str());
    std::string raw_ref;

	if (policy_type_string.substr(1, 1) == "D") {
        if (lookup_key_ref(s_de_key_raw_refs, user_id, &raw_ref)) {
            memcpy(policy, raw_ref.data(), raw_ref.size());
        } else
            return false;
    } else if (policy_type_string.substr(1, 1) == "C") {
        if (lookup_key_ref(s_ce_key_raw_refs, user_id, &raw_ref)) {
            memcpy(policy, raw_ref.data(), raw_ref.size());
        } else
            return false;
    } else {
        printf("unknown policy type '%s'\n", policy_type);
        return false;
    }
    return true;
}

bool Decrypt_DE() {
	if (!fscrypt_initialize_systemwide_keys()) { // this deals with the overarching device encryption
		printf("fscrypt_initialize_systemwide_keys returned fail\n");
		return false;
	}
	if (!fscrypt_init_user0()) {
		printf("fscrypt_init_user0 returned fail\n");
		return false;
	}
	return true;
}

// Crappy functions for debugging, please ignore unless you need to debug
// void output_hex(const std::string& in) {
// 	const char *buf = in.data();
// 	char hex[in.size() * 2 + 1];
// 	unsigned int index;
// 	for (index = 0; index < in.size(); index++)
// 		sprintf(&hex[2 * index], "%02X", buf[index]);
// 	printf("%s", hex);
// }

// void output_hex(const char* buf, const int size) {
// 	char hex[size * 2 + 1];
// 	int index;
// 	for (index = 0; index < size; index++)
// 		sprintf(&hex[2 * index], "%02X", buf[index]);
// 	printf("%s", hex);
// }

// void output_hex(const unsigned char* buf, const int size) {
// 	char hex[size * 2 + 1];
// 	int index;
// 	for (index = 0; index < size; index++)
// 		sprintf(&hex[2 * index], "%02X", buf[index]);
// 	printf("%s", hex);
// }

// void output_hex(std::vector<uint8_t>* vec) {
// 	char hex[3];
// 	unsigned int index;
// 	for (index = 0; index < vec->size(); index++) {
// 		sprintf(&hex[0], "%02X", vec->at(index));
// 		printf("%s", hex);
// 	}
// }

/* An alternative is to use:
 * sqlite3 /data/system/locksettings.db "SELECT value FROM locksettings WHERE name='sp-handle' AND user=0;"
 * but we really don't want to include the 1.1MB libsqlite in TWRP. We scan the spblob folder for the
 * password data file (*.pwd) and get the handle from the filename instead. This is a replacement for
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/LockSettingsService.java#2017
 * We never use this data as an actual long. We always use it as a string. */
bool Find_Handle(const std::string& spblob_path, std::string& handle_str) {
	DIR* dir = opendir(spblob_path.c_str());
	if (!dir) {
		printf("Error opening '%s'\n", spblob_path.c_str());
		return false;
	}

	struct dirent* de = 0;

	while ((de = readdir(dir)) != 0) {
		if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
			continue;
		size_t len = strlen(de->d_name);
		if (len <= 4)
			continue;
		char* p = de->d_name;
		p += len - 4;
		if (strncmp(p, ".pwd", 4) == 0) {
			handle_str = de->d_name;
			handle_str = handle_str.substr(0, len - 4);
			//*handle = strtoull(handle_str.c_str(), 0 , 16);
			closedir(dir);
			return true;
		}
	}
	closedir(dir);
	return false;
}

/* This is the structure of the data in the password data (*.pwd) file which the structure can be found
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#187 */
struct password_data_struct {
	int password_type;
	unsigned char scryptN;
	unsigned char scryptR;
	unsigned char scryptP;
	int salt_len;
	void* salt;
	int handle_len;
	void* password_handle;
};

/* C++ replacement for
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#764 */
bool Get_Password_Data(const std::string& spblob_path, const std::string& handle_str, password_data_struct *pwd) {
	std::string pwd_file = spblob_path + handle_str + ".pwd";
	std::string pwd_data;
	if (!android::base::ReadFileToString(pwd_file, &pwd_data)) {
		printf("Failed to read '%s'\n", pwd_file.c_str());
		return false;
	}
	// output_hex(pwd_data.data(), pwd_data.size());printf("\n");
	const int* intptr = (const int*)pwd_data.data();
	pwd->password_type = *intptr;
	endianswap(&pwd->password_type);
	//printf("password type %i\n", pwd->password_type); // 2 was PIN, 1 for pattern, 2 also for password, -1 for default password
	const unsigned char* byteptr = (const unsigned char*)pwd_data.data() + sizeof(int);
	pwd->scryptN = *byteptr;
	byteptr++;
	pwd->scryptR = *byteptr;
	byteptr++;
	pwd->scryptP = *byteptr;
	byteptr++;
	intptr = (const int*)byteptr;
	pwd->salt_len = *intptr;
	endianswap(&pwd->salt_len);
	if (pwd->salt_len != 0) {
		pwd->salt = malloc(pwd->salt_len);
		if (!pwd->salt) {
			printf("Get_Password_Data malloc salt\n");
			return false;
		}
		memcpy(pwd->salt, intptr + 1, pwd->salt_len);
		intptr++;
		byteptr = (const unsigned char*)intptr;
		byteptr += pwd->salt_len;
	} else {
		printf("Get_Password_Data salt_len is 0\n");
		return false;
	}
	intptr = (const int*)byteptr;
	pwd->handle_len = *intptr;
	endianswap(&pwd->handle_len);
	if (pwd->handle_len != 0) {
		pwd->password_handle = malloc(pwd->handle_len);
		if (!pwd->password_handle) {
			printf("Get_Password_Data malloc password_handle\n");
			return false;
		}
		memcpy(pwd->password_handle, intptr + 1, pwd->handle_len);
	} else {
		printf("Get_Password_Data handle_len is 0\n");
		// Not an error if using weaver
	}
	return true;
}

/* C++ replacement for
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#765
 * called here
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#1050 */
bool Get_Password_Token(const password_data_struct *pwd, const std::string& Password, unsigned char* password_token) {
	if (!password_token) {
		printf("password_token is null\n");
		return false;
	}
	unsigned int N = 1 << pwd->scryptN;
	unsigned int r = 1 << pwd->scryptR;
	unsigned int p = 1 << pwd->scryptP;
	//printf("N %i r %i p %i\n", N, r, p);
	int ret = crypto_scrypt(reinterpret_cast<const uint8_t*>(Password.data()), Password.size(),
                          reinterpret_cast<const uint8_t*>(pwd->salt), pwd->salt_len,
                          N, r, p,
                          password_token, 32);
	if (ret != 0) {
		printf("scrypt error\n");
		return false;
	}
	return true;
}

// Data structure for the *.weaver file, see Get_Weaver_Data below
struct weaver_data_struct {
	unsigned char version;
	int slot;
};

/* C++ replacement for
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#501
 * called here
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#768 */
bool Get_Weaver_Data(const std::string& spblob_path, const std::string& handle_str, weaver_data_struct *wd) {
	std::string weaver_file = spblob_path + handle_str + ".weaver";
	std::string weaver_data;
	if (!android::base::ReadFileToString(weaver_file, &weaver_data)) {
		printf("Failed to read '%s'\n", weaver_file.c_str());
		return false;
	}
	// output_hex(weaver_data.data(), weaver_data.size());printf("\n");
	const unsigned char* byteptr = (const unsigned char*)weaver_data.data();
	wd->version = *byteptr;
	// printf("weaver version %i\n", wd->version);
	const int* intptr = (const int*)weaver_data.data() + sizeof(unsigned char);
	wd->slot = *intptr;
	//endianswap(&wd->slot); not needed
	// printf("weaver slot %i\n", wd->slot);
	return true;
}

namespace android {

// On Android 8.0 for some reason init can't seem to completely stop keystore
// so we have to kill it too if it doesn't die on its own.
static void kill_keystore() {
    DIR* dir = opendir("/proc");
    if (dir) {
        struct dirent* de = 0;

        while ((de = readdir(dir)) != 0) {
            if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
                continue;

            int pid = -1;
            int ret = sscanf(de->d_name, "%d", &pid);

            if (ret == 1) {
                char cmdpath[PATH_MAX];
                sprintf(cmdpath, "/proc/%d/cmdline", pid);

                FILE* file = fopen(cmdpath, "r");
                size_t task_size = PATH_MAX;
                char task[PATH_MAX];
                char* p = task;
                if (getline(&p, &task_size, file) > 0) {
                    if (strstr(task, "keystore") != 0) {
                        printf("keystore pid %d found, sending kill.\n", pid);
                        kill(pid, SIGINT);
                        usleep(5000);
                        kill(pid, SIGKILL);
                    }
                }
                fclose(file);
            }
        }
        closedir(dir);
    }
}

// The keystore holds a file open on /data so we have to stop / kill it
// if we want to be able to unmount /data for things like formatting.
static void stop_keystore() {
    printf("Stopping keystore...\n");
    property_set("ctl.stop", "keystore");
    usleep(5000);
    kill_keystore();
}

/* These next 2 functions try to get the keystore service 50 times because
 * the keystore is not always ready when TWRP boots */
android::sp<IBinder> getKeystoreBinder() {
	android::sp<IServiceManager> sm = android::defaultServiceManager();
    return sm->getService(String16("android.security.keystore"));
}

android::sp<IBinder> getKeystoreBinderRetry() {
	printf("Starting keystore...\n");
    property_set("ctl.start", "keystore");
	int retry_count = 50;
	android::sp<IBinder> binder = getKeystoreBinder();
	while (binder == NULL && retry_count) {
		printf("Waiting for keystore service... %i\n", retry_count--);
		sleep(1);
		binder = getKeystoreBinder();
	}
	return binder;
}

namespace keystore {

#define SYNTHETIC_PASSWORD_VERSION_V1 1
#define SYNTHETIC_PASSWORD_VERSION_V2 2
#define SYNTHETIC_PASSWORD_VERSION_V3 3
#define SYNTHETIC_PASSWORD_PASSWORD_BASED 0
#define SYNTHETIC_PASSWORD_KEY_PREFIX "USRSKEY_synthetic_password_"
#define USR_PRIVATE_KEY_PREFIX "USRPKEY_synthetic_password_"

static std::string mKey_Prefix;

/* The keystore alias subid is sometimes the same as the handle, but not always.
 * In the case of handle 0c5303fd2010fe29, the alias subid used c5303fd2010fe29
 * without the leading 0. We could try to parse the data from a previous
 * keystore request, but I think this is an easier solution because there
 * is little to no documentation on the format of data we get back from
 * the keystore in this instance. We also want to copy everything to a temp
 * folder so that any key upgrades that might take place do not actually
 * upgrade the keys on the data partition. We rename all 1000 uid files to 0
 * to pass the keystore permission checks. */
bool Find_Keystore_Alias_SubID_And_Prep_Files(const userid_t user_id, std::string& keystoreid, const std::string& handle_str) {
	char path_c[PATH_MAX];
	sprintf(path_c, "/data/misc/keystore/user_%d", user_id);
	char user_dir[PATH_MAX];
	sprintf(user_dir, "user_%d", user_id);
	std::string source_path = "/data/misc/keystore/";
	source_path += user_dir;
	std::string handle_sub = handle_str;
	while (handle_sub.substr(0,1) == "0") {
		std::string temp = handle_sub.substr(1);
		handle_sub = temp;
	}
	mKey_Prefix = "";

	mkdir("/tmp/misc", 0755);
	mkdir("/tmp/misc/keystore", 0755);
	std::string destination_path = "/tmp/misc/keystore/";
	destination_path += user_dir;
	if (mkdir(destination_path.c_str(), 0755) && errno != EEXIST) {
		printf("failed to mkdir '%s' %s\n", destination_path.c_str(), strerror(errno));
		return false;
	}
	destination_path += "/";

	DIR* dir = opendir(source_path.c_str());
	if (!dir) {
		printf("Error opening '%s'\n", source_path.c_str());
		return false;
	}
	source_path += "/";

	struct dirent* de = 0;
	size_t prefix_len = strlen(SYNTHETIC_PASSWORD_KEY_PREFIX);
	bool found_subid = false;
	bool has_pkey = false; // PKEY has priority over SKEY

	while ((de = readdir(dir)) != 0) {
		if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
			continue;
		if (!found_subid) {
			size_t len = strlen(de->d_name);
			if (len <= prefix_len)
				continue;
			if (strstr(de->d_name, SYNTHETIC_PASSWORD_KEY_PREFIX) && !has_pkey)
				mKey_Prefix = SYNTHETIC_PASSWORD_KEY_PREFIX;
			else if (strstr(de->d_name, USR_PRIVATE_KEY_PREFIX)) {
				mKey_Prefix = USR_PRIVATE_KEY_PREFIX;
				has_pkey = true;
			} else
				continue;
			if (strstr(de->d_name, handle_sub.c_str())) {
				keystoreid = handle_sub;
				printf("keystoreid matched handle_sub: '%s'\n", keystoreid.c_str());
				found_subid = true;
			} else {
				std::string file = de->d_name;
				std::size_t found = file.find_last_of("_");
				if (found != std::string::npos) {
					keystoreid = file.substr(found + 1);
					// printf("possible keystoreid: '%s'\n", keystoreid.c_str());
					//found_subid = true; // we'll keep going in hopes that we find a pkey or a match to the handle_sub
				}
			}
		}
		std::string src = source_path;
		src += de->d_name;
		std::ifstream srcif(src.c_str(), std::ios::binary);
		std::string dst = destination_path;
		dst += de->d_name;
		std::size_t source_uid = dst.find("1000");
		if (source_uid != std::string::npos)
			dst.replace(source_uid, 4, "0");
		std::ofstream dstof(dst.c_str(), std::ios::binary);
		printf("copying '%s' to '%s'\n", src.c_str(), dst.c_str());
		dstof << srcif.rdbuf();
		srcif.close();
		dstof.close();
	}
	closedir(dir);
	if (!found_subid && !mKey_Prefix.empty() && !keystoreid.empty())
		found_subid = true;
	return found_subid;
}

/* C++ replacement for function of the same name
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#867
 * returning an empty string indicates an error */
std::string unwrapSyntheticPasswordBlob(const std::string& spblob_path, const std::string& handle_str, const userid_t user_id,
	const void* application_id, const size_t application_id_size, uint32_t auth_token_len) {
	std::string disk_decryption_secret_key = "";

	android::ProcessState::self()->startThreadPool();

	std::string keystore_alias_subid;
	if (!Find_Keystore_Alias_SubID_And_Prep_Files(user_id, keystore_alias_subid, handle_str)) {
		printf("failed to scan keystore alias subid and prep keystore files\n");
		return disk_decryption_secret_key;
	}

	// First get the keystore service
    android::sp<IBinder> binder = getKeystoreBinderRetry();
	android::sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);

	if (service == NULL) {
		printf("error: could not connect to keystore service\n");
		return disk_decryption_secret_key;
	}

	if (auth_token_len > 0) {
		printf("Starting keystore_auth service...\n");
		property_set("ctl.start", "keystore_auth");
	}

	// Read the data from the .spblob file per: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#869
	std::string spblob_file = spblob_path + handle_str + ".spblob";
	std::string spblob_data;
	if (!android::base::ReadFileToString(spblob_file, &spblob_data)) {
		printf("Failed to read '%s'\n", spblob_file.c_str());
		return disk_decryption_secret_key;
	}
	unsigned char* byteptr = (unsigned char*)spblob_data.data();
	if (*byteptr != SYNTHETIC_PASSWORD_VERSION_V2 && *byteptr != SYNTHETIC_PASSWORD_VERSION_V1
			&& *byteptr != SYNTHETIC_PASSWORD_VERSION_V3) {
		printf("Unsupported synthetic password version %i\n", *byteptr);
		return disk_decryption_secret_key;
	}
	const unsigned char* synthetic_password_version = byteptr;
	byteptr++;
	if (*byteptr != SYNTHETIC_PASSWORD_PASSWORD_BASED) {
		printf("spblob data is not SYNTHETIC_PASSWORD_PASSWORD_BASED\n");
		return disk_decryption_secret_key;
	}
	byteptr++; // Now we're pointing to the blob data itself
	if (*synthetic_password_version == SYNTHETIC_PASSWORD_VERSION_V2
			|| *synthetic_password_version == SYNTHETIC_PASSWORD_VERSION_V3) {
		printf("spblob v2 / v3\n");
		/* Version 2 / 3 of the spblob is basically the same as version 1, but the order of getting the intermediate key and disk decryption key have been flip-flopped
		 * as seen in https://android.googlesource.com/platform/frameworks/base/+/5025791ac6d1538224e19189397de8d71dcb1a12
		 */
		/* First decrypt call found in
		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.1.0_r18/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#135
		 * We will use https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
		 * and https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
		 * First we set some algorithm parameters as seen in two places:
		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java#297
		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java#216 */
		// When using secdis (aka not weaver) you must supply an auth token to the keystore prior to the begin operation
		if (auth_token_len > 0) {
			/*::keystore::KeyStoreServiceReturnCode auth_result = service->addAuthToken(auth_token, auth_token_len);
			if (!auth_result.isOk()) {
				// The keystore checks the uid of the calling process and will return a permission denied on this operation for user 0
				printf("keystore error adding auth token\n");
				return disk_decryption_secret_key;
			}*/
			// The keystore refuses to allow the root user to supply auth tokens, so we write the auth token to a file earlier and
			// run a separate service that runs user the system user to add the auth token. We wait for the auth token file to be
			// deleted by the keymaster_auth service and check for a /auth_error file in case of errors. We quit after after a while if
			// the /auth_token file never gets deleted.
			int auth_wait_count = 20;
			while (access("/auth_token", F_OK) == 0 && auth_wait_count-- > 0)
				usleep(5000);
			if (auth_wait_count == 0 || access("/auth_error", F_OK) == 0) {
				printf("error during keymaster_auth service\n");
				/* If you are getting this error, make sure that you have the keymaster_auth service defined in your init scripts, preferrably in init.recovery.{ro.hardware}.rc
				 * service keystore_auth /system/bin/keystore_auth
				 *     disabled
				 *     oneshot
				 *     user system
				 *     group root
				 *     seclabel u:r:recovery:s0
				 *
				 * And check dmesg for error codes regarding this service if needed. */
				return disk_decryption_secret_key;
			}
		}
		int32_t ret;
		size_t maclen = 128;
		unsigned char* iv = (unsigned char*)byteptr; // The IV is the first 12 bytes of the spblob
		::keystore::hidl_vec<uint8_t> iv_hidlvec;
		iv_hidlvec.setToExternal((unsigned char*)byteptr, 12);
		// printf("iv: "); output_hex((const unsigned char*)iv, 12); printf("\n");
		std::string keystore_alias = mKey_Prefix;
		keystore_alias += keystore_alias_subid;
		String16 keystore_alias16(keystore_alias.data(), keystore_alias.size());
		int32_t error_code;
		unsigned char* cipher_text = (unsigned char*)byteptr + 12; // The cipher text comes immediately after the IV
		std::string cipher_text_str(byteptr, byteptr + spblob_data.size() - 14);

		::keystore::hidl_vec<uint8_t> cipher_text_hidlvec;
		::keystore::AuthorizationSetBuilder begin_params;

        cipher_text_hidlvec.setToExternal(cipher_text, spblob_data.size() - 14 /* 1 each for version and SYNTHETIC_PASSWORD_PASSWORD_BASED and 12 for the iv */);
		begin_params.Authorization(::keystore::TAG_ALGORITHM, ::keystore::Algorithm::AES);
		begin_params.Authorization(::keystore::TAG_BLOCK_MODE, ::keystore::BlockMode::GCM);
		begin_params.Padding(::keystore::PaddingMode::NONE);
		begin_params.Authorization(::keystore::TAG_NONCE, iv_hidlvec);
		begin_params.Authorization(::keystore::TAG_MAC_LENGTH, maclen);

		::keystore::hidl_vec<uint8_t> entropy; // No entropy is needed for decrypt
		entropy.resize(0);
		android::security::keymaster::KeymasterArguments empty_params;
		android::hardware::keymaster::V4_0::KeyPurpose decryptPurpose  = android::hardware::keymaster::V4_0::KeyPurpose::DECRYPT;
		android::sp<android::IBinder> decryptAuthToken(new android::BBinder);

		android::sp<OperationResultPromise> promise = new OperationResultPromise;
		auto future = promise->get_future();
		auto binder_result = service->begin(promise, decryptAuthToken, keystore_alias16, (int32_t)decryptPurpose, true,
			android::security::keymaster::KeymasterArguments(begin_params.hidl_data()), 
			entropy, -1, &error_code);
	    if (!binder_result.isOk()) {
        	printf("communication error while calling keystore\n");
			return disk_decryption_secret_key;
   		}
		::keystore::KeyStoreNativeReturnCode rc(error_code);
		if (!rc.isOk()) {
			printf("Keystore begin returned: %u\n", error_code);
        	return disk_decryption_secret_key;
    	}
		OperationResult result = future.get();
		auto handle = std::move(result.token);

		// The cipher.doFinal call triggers an update to the keystore followed by a finish https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#64
		// See also https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java#208
		future = {};
		promise = new OperationResultPromise();
	    future = promise->get_future();
		binder_result = service->update(promise, handle, empty_params, cipher_text_hidlvec, &error_code);
		rc = ::keystore::KeyStoreNativeReturnCode(error_code);
        if (!rc.isOk()) {
            printf("Keystore update returned: %d\n", error_code);
            return disk_decryption_secret_key;
        }
		result = future.get();
        if (!result.resultCode.isOk()) {
            printf("update failed: %d\n", error_code);
            return disk_decryption_secret_key;
        }

		size_t keystore_result_size = result.data.size();
		unsigned char* keystore_result = (unsigned char*)malloc(keystore_result_size);
		if (!keystore_result) {
			printf("malloc on keystore_result\n");
			return disk_decryption_secret_key;
		}
		memcpy(keystore_result, &result.data[0], result.data.size());
		future = {};
		promise = new OperationResultPromise();
		future = promise->get_future();
		::keystore::hidl_vec<uint8_t> signature;
		binder_result = service->finish(promise, handle, empty_params, signature, entropy, &error_code);
		if (!binder_result.isOk()) {
			printf("communication error while calling keystore\n");
			free(keystore_result);
			return disk_decryption_secret_key;
		}
		rc = ::keystore::KeyStoreNativeReturnCode(error_code);
		if (!rc.isOk()) {
			printf("Keystore finish returned: %d\n", error_code);
			return disk_decryption_secret_key;
		}
		result = future.get();
		if (!result.resultCode.isOk()) {
			printf("finish failed: %d\n", error_code);
			return disk_decryption_secret_key;
		}
		stop_keystore();
		/* Now we do the second decrypt call as seen in:
		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.1.0_r18/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#136
		 */
		const unsigned char* intermediate_iv = keystore_result;
		// printf("intermediate_iv: "); output_hex((const unsigned char*)intermediate_iv, 12); printf("\n");
		const unsigned char* intermediate_cipher_text = (const unsigned char*)keystore_result + 12; // The cipher text comes immediately after the IV
		int cipher_size = keystore_result_size - 12;
		// First we personalize as seen https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#102
		void* personalized_application_id = PersonalizedHashBinary(PERSONALISATION_APPLICATION_ID, (const char*)application_id, application_id_size);
		if (!personalized_application_id) {
			return disk_decryption_secret_key;
		}
		// printf("personalized application id: "); output_hex((unsigned char*)personalized_application_id, SHA512_DIGEST_LENGTH); printf("\n");
		// Now we'll decrypt using openssl AES/GCM/NoPadding
		OpenSSL_add_all_ciphers();
		int actual_size=0, final_size=0;
		EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new();
		const unsigned char* key = (const unsigned char*)personalized_application_id; // The key is the now personalized copy of the application ID
		// printf("key: "); output_hex((const unsigned char*)key, 32); printf("\n");
		EVP_DecryptInit(d_ctx, EVP_aes_256_gcm(), key, intermediate_iv);
		unsigned char* secret_key = (unsigned char*)malloc(cipher_size);
		if (!secret_key) {
			printf("malloc failure on secret key\n");
			return disk_decryption_secret_key;
		}
		EVP_DecryptUpdate(d_ctx, secret_key, &actual_size, intermediate_cipher_text, cipher_size);
		unsigned char tag[AES_BLOCK_SIZE];
		EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, tag);
		EVP_DecryptFinal_ex(d_ctx, secret_key + actual_size, &final_size);
		EVP_CIPHER_CTX_free(d_ctx);
		free(personalized_application_id);
		free(keystore_result);
		int secret_key_real_size = actual_size - 16;
		// printf("secret key:  "); output_hex((const unsigned char*)secret_key, secret_key_real_size); printf("\n");
		// The payload data from the keystore update is further personalized at https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#153
		// We now have the disk decryption key!
		if (*synthetic_password_version == SYNTHETIC_PASSWORD_VERSION_V3) {
			// V3 uses SP800 instead of SHA512
			disk_decryption_secret_key = PersonalizedHashSP800(PERSONALIZATION_FBE_KEY, PERSONALISATION_CONTEXT, (const char*)secret_key, secret_key_real_size);
		} else {
			disk_decryption_secret_key = PersonalizedHash(PERSONALIZATION_FBE_KEY, (const char*)secret_key, secret_key_real_size);
		}
		// printf("disk_decryption_secret_key: '%s'\n", disk_decryption_secret_key.c_str());
		free(secret_key);
		return disk_decryption_secret_key;
	}
	return disk_decryption_secret_key;
}

}}

#define PASSWORD_TOKEN_SIZE 32

/* C++ replacement for
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#992
 * called here
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#813 */
bool Get_Secdis(const std::string& spblob_path, const std::string& handle_str, std::string& secdis_data) {
	std::string secdis_file = spblob_path + handle_str + ".secdis";
	if (!android::base::ReadFileToString(secdis_file, &secdis_data)) {
		printf("Failed to read '%s'\n", secdis_file.c_str());
		return false;
	}
	// output_hex(secdis_data.data(), secdis_data.size());printf("\n");
	return true;
}

// C++ replacement for https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#1033
userid_t fakeUid(const userid_t uid) {
    return 100000 + uid;
}

bool Is_Weaver(const std::string& spblob_path, const std::string& handle_str) {
	std::string weaver_file = spblob_path + handle_str + ".weaver";
	struct stat st;
	if (stat(weaver_file.c_str(), &st) == 0)
		return true;
	return false;
}

bool Free_Return(bool retval, void* weaver_key, password_data_struct* pwd) {
	if (weaver_key)
		free(weaver_key);
	if (pwd->salt)
		free(pwd->salt);
	if (pwd->password_handle)
		free(pwd->password_handle);
	return retval;
}

/* Decrypt_User_Synth_Pass is the TWRP C++ equivalent to spBasedDoVerifyCredential
 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/LockSettingsService.java#1998 */
bool Decrypt_User_Synth_Pass(const userid_t user_id, const std::string& Password) {
	bool retval = false;
	void* weaver_key = NULL;
	password_data_struct pwd;
	pwd.salt = NULL;
	pwd.salt_len = 0;
	pwd.password_handle = NULL;
	pwd.handle_len = 0;
	char application_id[PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH];

    uint32_t auth_token_len = 0;

	std::string secret; // this will be the disk decryption key that is sent to vold
	std::string token = "!"; // there is no token used for this kind of decrypt, key escrow is handled by weaver
	int flags = FLAG_STORAGE_DE;
    if (user_id == 0)
		flags = FLAG_STORAGE_DE;
	else
		flags = FLAG_STORAGE_CE;
	char spblob_path_char[PATH_MAX];
	sprintf(spblob_path_char, "/data/system_de/%d/spblob/", user_id);
	std::string spblob_path = spblob_path_char;
	long handle = 0;
	std::string handle_str;
	// Get the handle: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/LockSettingsService.java#2017
	if (!Find_Handle(spblob_path, handle_str)) {
		printf("Error getting handle\n");
		return Free_Return(retval, weaver_key, &pwd);
	}
	// printf("Handle is '%s'\n", handle_str.c_str());
	// Now we begin driving unwrapPasswordBasedSyntheticPassword from: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#758
	// First we read the password data which contains scrypt parameters
	if (!Get_Password_Data(spblob_path, handle_str, &pwd)) {
		printf("Failed to Get_Password_Data\n");
		return Free_Return(retval, weaver_key, &pwd);
	}
	// printf("pwd N %i R %i P %i salt ", pwd.scryptN, pwd.scryptR, pwd.scryptP); output_hex((char*)pwd.salt, pwd.salt_len); printf("\n");
	unsigned char password_token[PASSWORD_TOKEN_SIZE];
	// printf("Password: '%s'\n", Password.c_str());
	// The password token is the password scrypted with the parameters from the password data file
	if (!Get_Password_Token(&pwd, Password, &password_token[0])) {
		printf("Failed to Get_Password_Token\n");
		return Free_Return(retval, weaver_key, &pwd);
	}
	// output_hex(&password_token[0], PASSWORD_TOKEN_SIZE);printf("\n");
	if (Is_Weaver(spblob_path, handle_str)) {
		printf("using weaver\n");
		// BEGIN PIXEL 2 WEAVER
		// Get the weaver data from the .weaver file which tells us which slot to use when we ask weaver for the escrowed key
		// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#768
		weaver_data_struct wd;
		if (!Get_Weaver_Data(spblob_path, handle_str, &wd)) {
			printf("Failed to get weaver data\n");
			return Free_Return(retval, weaver_key, &pwd);
		}
		// The weaver key is the the password token prefixed with "weaver-key" padded to 128 with nulls with the password token appended then SHA512
		// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#1059
		weaver_key = PersonalizedHashBinary(PERSONALISATION_WEAVER_KEY, (char*)&password_token[0], PASSWORD_TOKEN_SIZE);
		if (!weaver_key) {
			printf("malloc error getting weaver_key\n");
			return Free_Return(retval, weaver_key, &pwd);
		}
		// Now we start driving weaverVerify: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#343
		// Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#776
		android::vold::Weaver weaver;
		if (!weaver) {
			printf("Failed to get weaver service\n");
			return Free_Return(retval, weaver_key, &pwd);
		}
		// Get the key size from weaver service
		uint32_t weaver_key_size = 0;
		if (!weaver.GetKeySize(&weaver_key_size)) {
			printf("Failed to get weaver key size\n");
			return Free_Return(retval, weaver_key, &pwd);
		} else {
			printf("weaver key size is %u\n", weaver_key_size);
		}
		// printf("weaver key: "); output_hex((unsigned char*)weaver_key, weaver_key_size); printf("\n");
		// Send the slot from the .weaver file, the computed weaver key, and get the escrowed key data
		std::vector<uint8_t> weaver_payload;
		// TODO: we should return more information about the status including time delays before the next retry
		if (!weaver.WeaverVerify(wd.slot, weaver_key, &weaver_payload)) {
			printf("failed to weaver verify\n");
			return Free_Return(retval, weaver_key, &pwd);
		}
		// printf("weaver payload: "); output_hex(&weaver_payload); printf("\n");
		// Done with weaverVerify
		// Now we will compute the application ID
		// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#964
		// Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#780
		// The escrowed weaver key data is prefixed with "weaver-pwd" padded to 128 with nulls with the weaver payload appended then SHA512
		void* weaver_secret = PersonalizedHashBinary(PERSONALISATION_WEAVER_PASSWORD, (const char*)weaver_payload.data(), weaver_payload.size());
		// printf("weaver secret: "); output_hex((unsigned char*)weaver_secret, SHA512_DIGEST_LENGTH); printf("\n");
		// The application ID is the password token and weaver secret appended to each other
		memcpy((void*)&application_id[0], (void*)&password_token[0], PASSWORD_TOKEN_SIZE);
		memcpy((void*)&application_id[PASSWORD_TOKEN_SIZE], weaver_secret, SHA512_DIGEST_LENGTH);
		// printf("application ID: "); output_hex((unsigned char*)application_id, PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH); printf("\n");
		// END PIXEL 2 WEAVER
	} else {
		printf("using secdis\n");
		std::string secdis_data;
		if (!Get_Secdis(spblob_path, handle_str, secdis_data)) {
			printf("Failed to get secdis data\n");
			return Free_Return(retval, weaver_key, &pwd);
		}
		void* secdiscardable = PersonalizedHashBinary(PERSONALISATION_SECDISCARDABLE, (char*)secdis_data.data(), secdis_data.size());
		if (!secdiscardable) {
			printf("malloc error getting secdiscardable\n");
			return Free_Return(retval, weaver_key, &pwd);
		}
		memcpy((void*)&application_id[0], (void*)&password_token[0], PASSWORD_TOKEN_SIZE);
		memcpy((void*)&application_id[PASSWORD_TOKEN_SIZE], secdiscardable, SHA512_DIGEST_LENGTH);

		int ret = -1;
		bool request_reenroll = false;
		android::sp<android::hardware::gatekeeper::V1_0::IGatekeeper> gk_device;
		gk_device = ::android::hardware::gatekeeper::V1_0::IGatekeeper::getService();
		if (gk_device == nullptr) {
			printf("failed to get gatekeeper service\n");
			return Free_Return(retval, weaver_key, &pwd);
		}
		if (pwd.handle_len <= 0) {
			printf("no password handle supplied\n");
			return Free_Return(retval, weaver_key, &pwd);
		}
		android::hardware::hidl_vec<uint8_t> pwd_handle_hidl;
		pwd_handle_hidl.setToExternal(const_cast<uint8_t *>((const uint8_t *)pwd.password_handle), pwd.handle_len);
		void* gk_pwd_token = PersonalizedHashBinary(PERSONALIZATION_USER_GK_AUTH, (char*)&password_token[0], PASSWORD_TOKEN_SIZE);
		if (!gk_pwd_token) {
			printf("malloc error getting gatekeeper_key\n");
			return Free_Return(retval, weaver_key, &pwd);
		}
		android::hardware::hidl_vec<uint8_t> gk_pwd_token_hidl;
		gk_pwd_token_hidl.setToExternal(const_cast<uint8_t *>((const uint8_t *)gk_pwd_token), SHA512_DIGEST_LENGTH);
		android::hardware::Return<void> hwRet =
			gk_device->verify(fakeUid(user_id), 0 /* challange */,
							  pwd_handle_hidl,
							  gk_pwd_token_hidl,
							  [&ret, &request_reenroll, &auth_token_len]
								(const android::hardware::gatekeeper::V1_0::GatekeeperResponse &rsp) {
									ret = static_cast<int>(rsp.code); // propagate errors
									if (rsp.code >= android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::STATUS_OK) {
										auth_token_len = rsp.data.size();
										request_reenroll = (rsp.code == android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::STATUS_REENROLL);
										ret = 0; // all success states are reported as 0
										// The keystore refuses to allow the root user to supply auth tokens, so we write the auth token to a file here and later
										// run a separate service that runs as the system user to add the auth token. We wait for the auth token file to be
										// deleted by the keymaster_auth service and check for a /auth_error file in case of errors. We quit after a while seconds if
										// the /auth_token file never gets deleted.
										unlink("/auth_token");
										FILE* auth_file = fopen("/auth_token","wb");
										if (auth_file != NULL) {
											fwrite(rsp.data.data(), sizeof(uint8_t), rsp.data.size(), auth_file);
											fclose(auth_file);
										} else {
											printf("failed to open /auth_token for writing\n");
											ret = -2;
										}
									} else if (rsp.code == android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::ERROR_RETRY_TIMEOUT && rsp.timeout > 0) {
										ret = rsp.timeout;
									}
								}
							 );
		free(gk_pwd_token);
		if (!hwRet.isOk() || ret != 0) {
			printf("gatekeeper verification failed\n");
			return Free_Return(retval, weaver_key, &pwd);
		}
	}
	// Now we will handle https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#816
	// Plus we will include the last bit that computes the disk decrypt key found in:
	// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#153
	secret = android::keystore::unwrapSyntheticPasswordBlob(spblob_path, handle_str, user_id, (const void*)&application_id[0], 
		PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH, auth_token_len);
	if (!secret.size()) {
		printf("failed to unwrapSyntheticPasswordBlob\n");
		return Free_Return(retval, weaver_key, &pwd);
	}

	if (!fscrypt_unlock_user_key(user_id, 0, token.c_str(), secret.c_str())) {
		printf("fscrypt_unlock_user_key returned fail\n");
		return Free_Return(retval, weaver_key, &pwd);
	}

	if (!fscrypt_prepare_user_storage("", user_id, 0, flags)) {
		printf("failed to fscrypt_prepare_user_storage\n");
		return Free_Return(retval, weaver_key, &pwd);
	}
	printf("Decrypted Successfully!\n");
	retval = true;
	return Free_Return(retval, weaver_key, &pwd);
}

int Get_Password_Type(const userid_t user_id, std::string& filename) {
	struct stat st;
	char spblob_path_char[PATH_MAX];
	sprintf(spblob_path_char, "/data/system_de/%d/spblob/", user_id);
	if (stat(spblob_path_char, &st) == 0) {
		printf("Using synthetic password method\n");
		std::string spblob_path = spblob_path_char;
		std::string handle_str;
		if (!Find_Handle(spblob_path, handle_str)) {
			printf("Error getting handle\n");
			return 0;
		}
		printf("Handle is '%s'\n", handle_str.c_str());
		password_data_struct pwd;
		if (!Get_Password_Data(spblob_path, handle_str, &pwd)) {
			printf("Failed to Get_Password_Data\n");
			return 0;
		}
		if (pwd.password_type == 1) { // In Android this means pattern
			printf("password type: pattern\n");
			return 2; // In TWRP this means pattern
		}
		else if (pwd.password_type == 2) { // In Android this means PIN or password
			printf("password type: pin\n");
			return 1; // In TWRP this means PIN or password
		}
		printf("using default password\n");
		return 0; // We'll try the default password
	}
	std::string path;
    if (user_id == 0) {
		path = "/data/system/";
	} else {
		char user_id_str[5];
		sprintf(user_id_str, "%i", user_id);
		path = "/data/system/users/";
		path += user_id_str;
		path += "/";
	}
	filename = path + "gatekeeper.password.key";
	if (stat(filename.c_str(), &st) == 0 && st.st_size > 0)
		return 1;
	filename = path + "gatekeeper.pattern.key";
	if (stat(filename.c_str(), &st) == 0 && st.st_size > 0)
		return 2;
	printf("Unable to locate gatekeeper password file '%s'\n", filename.c_str());
	filename = "";
	return 0;
}

bool Decrypt_User(const userid_t user_id, const std::string& Password) {
    uint8_t *auth_token;
    uint32_t auth_token_len;
    int ret;

    struct stat st;
    if (user_id > 9999) {
		printf("user_id is too big\n");
		return false;
	}
    std::string filename;
    bool Default_Password = (Password == "!");
    if (Get_Password_Type(user_id, filename) == 0 && !Default_Password) {
		printf("Unknown password type\n");
		return false;
	}
    int flags = FLAG_STORAGE_DE;
    if (user_id == 0)
		flags = FLAG_STORAGE_DE;
	else
		flags = FLAG_STORAGE_CE;

	if (Default_Password) {
		if (!fscrypt_unlock_user_key(user_id, 0, "!", "!")) {
			printf("unlock_user_key returned fail\n");
			return false;
		}
		if (!fscrypt_prepare_user_storage("", user_id, 0, flags)) {
			printf("failed to fscrypt_prepare_user_storage\n");
			return false;
		}
		printf("Decrypted Successfully!\n");
		return true;
	}
	if (stat("/data/system_de/0/spblob", &st) == 0) {
		printf("Using synthetic password method\n");
		return Decrypt_User_Synth_Pass(user_id, Password);
	}
	// printf("password filename is '%s'\n", filename.c_str());
	if (stat(filename.c_str(), &st) != 0) {
		printf("error stat'ing key file: %s\n", strerror(errno));
		return false;
	}
	std::string handle;
    if (!android::base::ReadFileToString(filename, &handle)) {
		printf("Failed to read '%s'\n", filename.c_str());
		return false;
	}
    bool should_reenroll;
	bool request_reenroll = false;
	android::sp<android::hardware::gatekeeper::V1_0::IGatekeeper> gk_device;
	gk_device = ::android::hardware::gatekeeper::V1_0::IGatekeeper::getService();
	if (gk_device == nullptr)
		return false;
	android::hardware::hidl_vec<uint8_t> curPwdHandle;
	curPwdHandle.setToExternal(const_cast<uint8_t *>((const uint8_t *)handle.c_str()), st.st_size);
	android::hardware::hidl_vec<uint8_t> enteredPwd;
	enteredPwd.setToExternal(const_cast<uint8_t *>((const uint8_t *)Password.c_str()), Password.size());

	android::hardware::Return<void> hwRet =
		gk_device->verify(user_id, 0 /* challange */,
						  curPwdHandle,
						  enteredPwd,
						  [&ret, &request_reenroll, &auth_token, &auth_token_len]
							(const android::hardware::gatekeeper::V1_0::GatekeeperResponse &rsp) {
								ret = static_cast<int>(rsp.code); // propagate errors
								if (rsp.code >= android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::STATUS_OK) {
									auth_token = new uint8_t[rsp.data.size()];
									auth_token_len = rsp.data.size();
									memcpy(auth_token, rsp.data.data(), auth_token_len);
									request_reenroll = (rsp.code == android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::STATUS_REENROLL);
									ret = 0; // all success states are reported as 0
								} else if (rsp.code == android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::ERROR_RETRY_TIMEOUT && rsp.timeout > 0) {
									ret = rsp.timeout;
								}
							}
						 );
	if (!hwRet.isOk()) {
		return false;
	}

	char token_hex[(auth_token_len*2)+1];
	token_hex[(auth_token_len*2)] = 0;
	uint32_t i;
	for (i=0;i<auth_token_len;i++) {
		sprintf(&token_hex[2*i], "%02X", auth_token[i]);
	}
	// The secret is "Android FBE credential hash" plus appended 0x00 to reach 128 bytes then append the user's password then feed that to sha512sum
	std::string secret = HashPassword(Password);
	if (!fscrypt_unlock_user_key(user_id, 0, token_hex, secret.c_str())) {
		printf("fscrypt_unlock_user_key returned fail\n");
		return false;
	}

	if (!fscrypt_prepare_user_storage("", user_id, 0, flags)) {
		printf("failed to fscrypt_prepare_user_storage\n");
		return false;
	}
	printf("Decrypted Successfully!\n");
	return true;
}
