decrypt: AOSP 10 requires the use of fscrypt

fscrypt aosp doc: https://source.android.com/security/encryption/file-based
kernel fscrypt doc: https://www.kernel.org/doc/html/v4.18/filesystems/fscrypt.html

This commit implements the ability for TWRP to use fscrypt to decrypt
files on the fscrypt implementation. It has been implemented mostly
in a new successor library to e4crypt called libtwrpfscrypt. Most of the
code was ported from AOSP vold.

Notable updates include:
 - updated policy storage by libtar
 - lookup of fbe policies by libtwrpfscrypt
 - threaded keystore operations

Big thanks to Dees_Troy for the initial trailblazing
of encryption in TWRP.

Change-Id: I69cd2eba3693a9914e00213d4943229635d0cdae
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index fa4e35d..b20f6ff 100755
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -649,7 +649,8 @@
 int TWFunc::tw_reboot(RebootCommand command)
 {
 	DataManager::Flush();
-	Update_Log_File();
+	if (!Is_Mount_Wiped("/data"))
+		Update_Log_File();
 	// Always force a sync before we reboot
 	sync();
 
@@ -1356,4 +1357,50 @@
 	}
 }
 
+bool TWFunc::Get_Encryption_Policy(fscrypt_encryption_policy &policy, std::string path) {
+	if (!TWFunc::Path_Exists(path)) {
+		LOGERR("Unable to find %s to get policy\n", path.c_str());
+		return false;
+	}
+	if (!fscrypt_policy_get_struct(path.c_str(), &policy)) {
+		LOGERR("No policy set for path %s\n", path.c_str());
+		return false;
+	}
+	return true;
+}
+
+bool TWFunc::Set_Encryption_Policy(std::string path, const fscrypt_encryption_policy &policy) {
+	if (!TWFunc::Path_Exists(path)) {
+		LOGERR("unable to find %s to set policy\n", path.c_str());
+		return false;
+	}
+	uint8_t binary_policy[FS_KEY_DESCRIPTOR_SIZE];
+	char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+	policy_to_hex(binary_policy, policy_hex);
+	if (!fscrypt_policy_set_struct(path.c_str(), &policy)) {
+		LOGERR("unable to set policy for path: %s\n", path.c_str());
+		return false;
+	}
+	return true;
+}
+
+bool TWFunc::Is_Mount_Wiped(std::string path) {
+	DIR* d = opendir(path.c_str());
+	size_t file_count = 0;
+	if (d != NULL) {
+		struct dirent* de;
+		while ((de = readdir(d)) != NULL) {
+			if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
+				continue;
+			if (strncmp(de->d_name, "lost+found", 10) == 0 || strncmp(de->d_name, "media", 5) == 0 || strncmp(de->d_name, "misc", 4) == 0
+				|| strncmp(de->d_name, "system", 6) == 0 || strncmp(de->d_name, "unencrypted", 11) == 0 
+				|| strncmp(de->d_name, "per_boot", 8) == 0)
+				continue;
+			file_count++;
+
+		}
+		closedir(d);
+	}
+	return file_count == 0;
+}
 #endif // ndef BUILD_TWRPTAR_MAIN