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/append.c b/libtar/append.c
old mode 100644
new mode 100755
index 8f09de2..3075a61
--- a/libtar/append.c
+++ b/libtar/append.c
@@ -24,22 +24,28 @@
 
 #include <sys/capability.h>
 #include <sys/xattr.h>
+#include <linux/fs.h>
 #include <linux/xattr.h>
 
 #ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <string.h>
+#include <stdlib.h>
+#include <string.h>
 #endif
 
 #ifdef HAVE_UNISTD_H
-# include <unistd.h>
+#include <unistd.h>
 #endif
 
 #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"
 
 struct tar_dev
@@ -142,6 +148,7 @@
 			printf("malloc ext4_encryption_policy\n");
 			return -1;
 		}
+
 		if (e4crypt_policy_get_struct(realname, t->th_buf.eep))
 		{
 			char tar_policy[EXT4_KEY_DESCRIPTOR_SIZE];
@@ -166,6 +173,43 @@
 		}
 	}
 #endif
+#ifdef USE_FSCRYPT
+	if (TH_ISDIR(t) && t->options & TAR_STORE_FSCRYPT_POL)
+	{
+		if (t->th_buf.fep != NULL)
+		{
+			free(t->th_buf.fep);
+			t->th_buf.fep = NULL;
+		}
+
+		t->th_buf.fep = (struct fscrypt_encryption_policy*)malloc(sizeof(struct fscrypt_encryption_policy));
+		if (!t->th_buf.fep) {
+			printf("malloc fs_encryption_policy\n");
+			return -1;
+		}
+
+		if (fscrypt_policy_get_struct(realname, t->th_buf.fep)) {
+			uint8_t tar_policy[FS_KEY_DESCRIPTOR_SIZE];
+			memset(tar_policy, 0, sizeof(tar_policy));
+			char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+			policy_to_hex(t->th_buf.fep->master_key_descriptor, policy_hex);
+			if (lookup_ref_key(t->th_buf.fep->master_key_descriptor, &tar_policy[0])) {
+				printf("found fscrypt policy '%s' - '%s' - '%s'\n", realname, tar_policy, policy_hex);
+				memcpy(t->th_buf.fep->master_key_descriptor, tar_policy, FS_KEY_DESCRIPTOR_SIZE);
+			} else {
+				printf("failed to lookup fscrypt tar policy for '%s' - '%s'\n", realname, policy_hex);
+				free(t->th_buf.fep);
+				t->th_buf.fep = NULL;
+				return -1;
+			}
+		}
+		else {
+			// no policy found, but this is not an error as not all dirs will have a policy
+			free(t->th_buf.fep);
+			t->th_buf.fep = NULL;
+		}
+	}
+#endif
 
 	/* get posix file capabilities */
 	if (TH_ISREG(t) && t->options & TAR_STORE_POSIX_CAP)