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)