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/libtar/extract.c b/libtar/extract.c
old mode 100644
new mode 100755
index ea86c23..fd5e3c9
--- a/libtar/extract.c
+++ b/libtar/extract.c
@@ -36,8 +36,13 @@
 #include <selinux/selinux.h>
 
 #ifdef HAVE_EXT4_CRYPT
-# include "ext4crypt_tar.h"
+#include "ext4crypt_tar.h"
 #endif
+
+#ifdef USE_FSCRYPT
+#include "fscrypt_policy.h"
+#endif
+
 #include "android_utils.h"
 
 const unsigned long long progress_size = (unsigned long long)(T_BLOCKSIZE);
@@ -572,6 +577,31 @@
 	}
 #endif
 
+#ifdef USE_FSCRYPT
+	if(t->th_buf.fep != NULL)
+	{
+#ifdef DEBUG
+		printf("tar_extract_file(): restoring fscrypt policy %s to dir %s\n", t->th_buf.fep->master_key_descriptor, realname);
+#endif
+		uint8_t binary_policy[FS_KEY_DESCRIPTOR_SIZE];
+		if (!lookup_ref_tar(t->th_buf.fep->master_key_descriptor, &binary_policy[0])) {
+			printf("error looking up proper fscrypt policy for '%s' - %s\n", realname, t->th_buf.fep->master_key_descriptor);
+			return -1;
+		}
+		char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+		policy_to_hex(binary_policy, policy_hex);
+		printf("restoring policy %s > '%s' to '%s'\n", t->th_buf.fep->master_key_descriptor, policy_hex, realname);
+		memcpy(&t->th_buf.fep->master_key_descriptor, binary_policy, FS_KEY_DESCRIPTOR_SIZE);
+		if (!fscrypt_policy_set_struct(realname, t->th_buf.fep))
+		{
+			printf("tar_extract_file(): failed to restore fscrypt policy to dir '%s' '%s'!!!\n", realname, policy_hex);
+			//return -1; // This may not be an error in some cases, so log and ignore
+		}
+	}
+	else
+		printf("NULL FSCRYPT\n");
+#endif
+
 	return 0;
 }