FsCrypt update: support fscrypt policies v1 and v2
This patchset introduces support decryption for Android 11.
In this update we deprecate ext4crypt. To specify the
policy version to use, use TW_USE_FSCRYPT_POLICY := 1 or
TW_USE_FSCRYPT_POLICY := 2. By default policy version will
be set to 2 if this variable is omitted.
Change-Id: I62a29c1bef36c259ec4b11259f71be613d20a112
diff --git a/libtar/append.c b/libtar/append.c
index 3075a61..860ab46 100755
--- a/libtar/append.c
+++ b/libtar/append.c
@@ -38,16 +38,16 @@
#include <selinux/selinux.h>
-#ifdef HAVE_EXT4_CRYPT
-#include "ext4crypt_tar.h"
-#endif
-
#ifdef USE_FSCRYPT
#include "fscrypt_policy.h"
#endif
#include "android_utils.h"
+#ifdef TW_LIBTAR_DEBUG
+#define DEBUG 1
+#endif
+
struct tar_dev
{
dev_t td_dev;
@@ -84,8 +84,8 @@
char path[MAXPATHLEN];
#ifdef DEBUG
- printf("==> tar_append_file(TAR=0x%lx (\"%s\"), realname=\"%s\", "
- "savename=\"%s\")\n", t, t->pathname, realname,
+ printf("==> tar_append_file(TAR=0x%p (\"%s\"), realname=\"%s\", "
+ "savename=\"%s\")\n", (void*) t, t->pathname, realname,
(savename ? savename : "[NULL]"));
#endif
@@ -134,45 +134,6 @@
}
}
-#ifdef HAVE_EXT4_CRYPT
- if (TH_ISDIR(t) && t->options & TAR_STORE_EXT4_POL)
- {
- if (t->th_buf.eep != NULL)
- {
- free(t->th_buf.eep);
- t->th_buf.eep = NULL;
- }
-
- t->th_buf.eep = (struct ext4_encryption_policy*)malloc(sizeof(struct ext4_encryption_policy));
- if (!t->th_buf.eep) {
- 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];
- memset(tar_policy, 0, sizeof(tar_policy));
- char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX];
- policy_to_hex(t->th_buf.eep->master_key_descriptor, policy_hex);
- if (lookup_ref_key(t->th_buf.eep->master_key_descriptor, &tar_policy[0])) {
- printf("found policy '%s' - '%s' - '%s'\n", realname, tar_policy, policy_hex);
- memcpy(t->th_buf.eep->master_key_descriptor, tar_policy, EXT4_KEY_DESCRIPTOR_SIZE);
- } else {
- printf("failed to lookup tar policy for '%s' - '%s'\n", realname, policy_hex);
- free(t->th_buf.eep);
- t->th_buf.eep = 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.eep);
- t->th_buf.eep = NULL;
- }
- }
-#endif
#ifdef USE_FSCRYPT
if (TH_ISDIR(t) && t->options & TAR_STORE_FSCRYPT_POL)
{
@@ -181,21 +142,31 @@
free(t->th_buf.fep);
t->th_buf.fep = NULL;
}
-
- t->th_buf.fep = (struct fscrypt_encryption_policy*)malloc(sizeof(struct fscrypt_encryption_policy));
+#ifdef USE_FSCRYPT_POLICY_V1
+ t->th_buf.fep = (struct fscrypt_policy_v1 *)malloc(sizeof(struct fscrypt_policy_v1));
+#else
+ t->th_buf.fep = (struct fscrypt_policy_v2 *)malloc(sizeof(struct fscrypt_policy_v2));
+#endif
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];
+ uint8_t tar_policy[FSCRYPT_KEY_IDENTIFIER_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);
+ char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
+ bytes_to_hex(t->th_buf.fep->master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
+ if (lookup_ref_key(t->th_buf.fep, &tar_policy[0])) {
+ if (strncmp((char *) tar_policy, "0CE0", 4) == 0 || strncmp((char *) tar_policy, "0DE0", 4) == 0
+ || strncmp((char *) tar_policy, "0DK", 3) == 0) {
+ memcpy(t->th_buf.fep->master_key_identifier, tar_policy, FSCRYPT_KEY_IDENTIFIER_SIZE);
+ printf("found fscrypt policy '%s' - '%s' - '%s'\n", realname, t->th_buf.fep->master_key_identifier, policy_hex);
+ } else {
+ printf("failed to match fscrypt tar policy for '%s' - '%s'\n", realname, policy_hex);
+ free(t->th_buf.fep);
+ t->th_buf.fep = NULL;
+ }
} else {
printf("failed to lookup fscrypt tar policy for '%s' - '%s'\n", realname, policy_hex);
free(t->th_buf.fep);
@@ -266,7 +237,7 @@
else
{
#ifdef DEBUG
- printf("+++ adding hash for device (0x%lx, 0x%lx)...\n",
+ printf("+++ adding hash for device (0x%x, 0x%x)...\n",
major(s.st_dev), minor(s.st_dev));
#endif
td = (tar_dev_t *)calloc(1, sizeof(tar_dev_t));
@@ -292,9 +263,9 @@
else
{
#ifdef DEBUG
- printf("+++ adding entry: device (0x%lx,0x%lx), inode %ld "
+ printf("+++ adding entry: device (0x%d,0x%x), inode %lu"
"(\"%s\")...\n", major(s.st_dev), minor(s.st_dev),
- s.st_ino, realname);
+ (unsigned long) s.st_ino, realname);
#endif
ti = (tar_ino_t *)calloc(1, sizeof(tar_ino_t));
if (ti == NULL)
@@ -332,7 +303,7 @@
if (th_write(t) != 0)
{
#ifdef DEBUG
- printf("t->fd = %d\n", t->fd);
+ printf("t->fd = %ld\n", t->fd);
#endif
return -1;
}
@@ -448,7 +419,7 @@
if (th_write(t) != 0)
{
#ifdef DEBUG
- fprintf(stderr, "tar_append_file_contents(): could not write header, t->fd = %d\n", t->fd);
+ fprintf(stderr, "tar_append_file_contents(): could not write header, t->fd = %ld\n", t->fd);
#endif
return -1;
}