fscrypt: integrate v1 processing into TWRP

Change-Id: I3bf9c14b818f9c3e0570c44c82bf0769fcec907f
diff --git a/crypto/fscrypt/Android.mk b/crypto/fscrypt/Android.mk
index a10a7e6..d9fb6ef 100755
--- a/crypto/fscrypt/Android.mk
+++ b/crypto/fscrypt/Android.mk
@@ -36,6 +36,12 @@
     system/extras/f2fs_utils/ \
     bootable/recovery/bootloader_message/include
 
+ifeq  ($(TW_USE_FSCRYPT_POLICY), 1)
+    LOCAL_CFLAGS += -DUSE_FSCRYPT_POLICY_V1
+else
+    LOCAL_CFLAGS += -DUSE_FSCRYPT_POLICY_V2
+endif
+
 ifneq ($(wildcard hardware/libhardware/include/hardware/keymaster0.h),)
     LOCAL_CFLAGS += -DTW_CRYPTO_HAVE_KEYMASTERX
     LOCAL_C_INCLUDES +=  external/boringssl/src/include
diff --git a/crypto/fscrypt/Decrypt.cpp b/crypto/fscrypt/Decrypt.cpp
index 5878d15..0055471 100755
--- a/crypto/fscrypt/Decrypt.cpp
+++ b/crypto/fscrypt/Decrypt.cpp
@@ -98,12 +98,22 @@
 }
 
 static bool lookup_ref_key_internal(std::map<userid_t, android::fscrypt::EncryptionPolicy> key_map, const uint8_t* policy, userid_t* user_id) {
+#ifdef USE_FSCRYPT_POLICY_V1
+	char policy_string_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+	char key_map_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+	bytes_to_hex(policy, FS_KEY_DESCRIPTOR_SIZE, policy_string_hex);
+#else
 	char policy_string_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
 	char key_map_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
 	bytes_to_hex(policy, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_string_hex);
+#endif
 
     for (std::map<userid_t, android::fscrypt::EncryptionPolicy>::iterator it=key_map.begin(); it!=key_map.end(); ++it) {
+#ifdef USE_FSCRYPT_POLICY_V1
+		bytes_to_hex(reinterpret_cast<const uint8_t*>(&it->second.key_raw_ref[0]), FS_KEY_DESCRIPTOR_SIZE, key_map_hex);
+#else
 		bytes_to_hex(reinterpret_cast<const uint8_t*>(&it->second.key_raw_ref[0]), FSCRYPT_KEY_IDENTIFIER_SIZE, key_map_hex);
+#endif
 		std::string key_map_hex_string = std::string(key_map_hex);
 		if (key_map_hex_string == policy_string_hex) {
             *user_id = it->first;
@@ -114,29 +124,49 @@
 }
 
 #ifdef USE_FSCRYPT_POLICY_V1
-extern "C" bool lookup_ref_key(fscrypt_policy_v1* v1, uint8_t* policy_type) {
+extern "C" bool lookup_ref_key(fscrypt_policy_v1* fep, uint8_t* policy_type) {
 #else
-extern "C" bool lookup_ref_key(fscrypt_policy_v2* v2, uint8_t* policy_type) {
+extern "C" bool lookup_ref_key(fscrypt_policy_v2* fep, uint8_t* policy_type) {
 #endif
 	userid_t user_id = 0;
 	std::string policy_type_string;
 
-	char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
-	bytes_to_hex(v2->master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
-	if (std::strncmp((const char*) v2->master_key_identifier, de_key_raw_ref.c_str(), FSCRYPT_KEY_IDENTIFIER_SIZE) == 0) {
-		policy_type_string = "0DK";
+#ifdef USE_FSCRYPT_POLICY_V1
+	char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+	bytes_to_hex(fep->master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE, policy_hex);
+	if (std::strncmp((const char*)fep->master_key_descriptor, de_key_raw_ref.c_str(), FS_KEY_DESCRIPTOR_SIZE) == 0) {
+		policy_type_string = SYSTEM_DE_FSCRYPT_POLICY;
 		memcpy(policy_type, policy_type_string.data(), policy_type_string.size());
 		return true;
 	}
-    if (!lookup_ref_key_internal(s_de_policies, v2->master_key_identifier, &user_id)) {
-        if (!lookup_ref_key_internal(s_ce_policies, v2->master_key_identifier, &user_id)) {
+    if (!lookup_ref_key_internal(s_de_policies, fep->master_key_descriptor, &user_id)) {
+        if (!lookup_ref_key_internal(s_ce_policies, fep->master_key_descriptor, &user_id)) {
             return false;
 		} else {
-			policy_type_string = "0CE" + std::to_string(user_id);
+			policy_type_string = USER_CE_FSCRYPT_POLICY + std::to_string(user_id);
 		}
     } else {
-			policy_type_string = "0DE" + std::to_string(user_id);
+			policy_type_string = USER_DE_FSCRYPT_POLICY + std::to_string(user_id);
 	}
+#else
+	char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
+	bytes_to_hex(fep->master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
+	if (std::strncmp((const char*)fep->master_key_identifier, de_key_raw_ref.c_str(), FSCRYPT_KEY_IDENTIFIER_SIZE) == 0) {
+		policy_type_string = SYSTEM_DE_FSCRYPT_POLICY;
+		memcpy(policy_type, policy_type_string.data(), policy_type_string.size());
+		return true;
+	}
+    if (!lookup_ref_key_internal(s_de_policies, fep->master_key_identifier, &user_id)) {
+        if (!lookup_ref_key_internal(s_ce_policies, fep->master_key_identifier, &user_id)) {
+            return false;
+		} else {
+			policy_type_string = USER_CE_FSCRYPT_POLICY + std::to_string(user_id);
+		}
+    } else {
+			policy_type_string = USER_DE_FSCRYPT_POLICY + std::to_string(user_id);
+	}
+#endif
+
 	memcpy(policy_type, policy_type_string.data(), policy_type_string.size());
 	LOG(INFO) << "storing policy type: " << policy_type;
     return true;
@@ -144,30 +174,39 @@
 
 extern "C" bool lookup_ref_tar(const uint8_t* policy_type, uint8_t* policy) {
 	std::string policy_type_string = std::string((char *) policy_type);
+#ifdef USE_FSCRYPT_POLICY_V1
+	char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+	bytes_to_hex(policy_type, FS_KEY_DESCRIPTOR_SIZE, policy_hex);
+#else
 	char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
 	bytes_to_hex(policy_type, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
+#endif
 
 	userid_t user_id = atoi(policy_type_string.substr(3, 4).c_str());
 
 	// TODO Update version # and make magic strings
-	if (policy_type_string.substr(0,1) != "0") {
+#ifdef USE_FSCRYPT_POLICY_V1
+	if (policy_type_string.substr(0,1) != FSCRYPT_V1) {
+#else
+	if (policy_type_string.substr(0,1) != FSCRYPT_V2) {
+#endif
         LOG(ERROR) << "Unexpected version:" << policy_type[0];
         return false;
     }
 
-	if (policy_type_string.substr(1, 2) == "DK") {
+	if (policy_type_string.substr(1, 2) == SYSTEM_DE_KEY) {
         memcpy(policy, de_key_raw_ref.data(), de_key_raw_ref.size());
         return true;
     }
 
     std::string raw_ref;
 
-	if (policy_type_string.substr(1, 1) == "D") {
+	if (policy_type_string.substr(1, 1) == USER_DE_KEY) {
         if (lookup_key_ref(s_de_policies, user_id, &raw_ref)) {
             memcpy(policy, raw_ref.data(), raw_ref.size());
         } else
             return false;
-    } else if (policy_type_string.substr(1, 1) == "C") {
+    } else if (policy_type_string.substr(1, 1) == USER_CE_KEY) {
         if (lookup_key_ref(s_ce_policies, user_id, &raw_ref)) {
             memcpy(policy, raw_ref.data(), raw_ref.size());
         } else
@@ -176,9 +215,6 @@
         LOG(ERROR) << "unknown policy type: " << policy_type;
         return false;
     }
-
-	char found_policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
-	bytes_to_hex(policy, FSCRYPT_KEY_IDENTIFIER_SIZE, found_policy_hex);
     return true;
 }
 
diff --git a/crypto/fscrypt/fscrypt_policy.cpp b/crypto/fscrypt/fscrypt_policy.cpp
index 99833f8..9ca3ed4 100755
--- a/crypto/fscrypt/fscrypt_policy.cpp
+++ b/crypto/fscrypt/fscrypt_policy.cpp
@@ -180,7 +180,11 @@
         close(fd);
         return false;
     }
+#ifdef USE_FSCRYPT_POLICY_V1
+    memcpy(fep, &ex_policy.policy.v1, sizeof(ex_policy.policy.v1));
+#else
     memcpy(fep, &ex_policy.policy.v2, sizeof(ex_policy.policy.v2));
+#endif
     close(fd);
     return true;
 }
diff --git a/crypto/fscrypt/fscrypt_policy.h b/crypto/fscrypt/fscrypt_policy.h
index c99ce2e..5714790 100755
--- a/crypto/fscrypt/fscrypt_policy.h
+++ b/crypto/fscrypt/fscrypt_policy.h
@@ -27,6 +27,22 @@
 #define FS_KEY_DESCRIPTOR_SIZE_HEX (2 * FS_KEY_DESCRIPTOR_SIZE + 1)
 #define FSCRYPT_KEY_IDENTIFIER_HEX_SIZE ((2 * FSCRYPT_KEY_IDENTIFIER_SIZE) + 1)
 
+#ifdef USE_FSCRYPT_POLICY_V1
+#define USER_CE_FSCRYPT_POLICY           "0CE"
+#define USER_DE_FSCRYPT_POLICY           "0DE"
+#define SYSTEM_DE_FSCRYPT_POLICY         "0DK"
+#else
+#define USER_CE_FSCRYPT_POLICY           "2CE"
+#define USER_DE_FSCRYPT_POLICY           "2DE"
+#define SYSTEM_DE_FSCRYPT_POLICY         "2DK"
+#endif
+
+#define FSCRYPT_V1                        "0"
+#define FSCRYPT_V2                        "2"
+#define SYSTEM_DE_KEY                     "DK"
+#define USER_CE_KEY                       "C"
+#define USER_DE_KEY                       "D"
+
 /* modes not supported by upstream kernel, so not in <linux/fs.h> */
 #define FS_ENCRYPTION_MODE_AES_256_HEH      126
 #define FS_ENCRYPTION_MODE_PRIVATE          127
diff --git a/crypto/fscrypt/fscryptpolicyget.cpp b/crypto/fscrypt/fscryptpolicyget.cpp
index 05e9d6f..189a428 100755
--- a/crypto/fscrypt/fscryptpolicyget.cpp
+++ b/crypto/fscrypt/fscryptpolicyget.cpp
@@ -31,8 +31,13 @@
 		fscrypt_policy_v2 fep;
 #endif
 		if (fscrypt_policy_get_struct(argv[1], &fep)) {
+#ifdef USE_FSCRYPT_POLICY_V1
+			char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+			bytes_to_hex(fep.master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE, policy_hex);
+#else
 			char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
 			bytes_to_hex(fep.master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
+#endif
 			printf("%s\n", policy_hex);
 		} else {
 			printf("No policy set\n");
diff --git a/etc/init/android.hardware.boot@1.0-service.rc b/etc/init/android.hardware.boot@1.0-service.rc
index 2fd4451..bc23757 100644
--- a/etc/init/android.hardware.boot@1.0-service.rc
+++ b/etc/init/android.hardware.boot@1.0-service.rc
@@ -1,5 +1,5 @@
 on post-fs
-    start boot-hal-1-0
+    #start boot-hal-1-0
 
 service boot-hal-1-0 /system/bin/android.hardware.boot@1.0-service
     user root
diff --git a/libtar/Android.mk b/libtar/Android.mk
index 9209da9..6ff8fc9 100755
--- a/libtar/Android.mk
+++ b/libtar/Android.mk
@@ -16,6 +16,11 @@
 ifeq ($(TW_INCLUDE_CRYPTO_FBE), true)
     LOCAL_SHARED_LIBRARIES += libtwrpfscrypt
     LOCAL_CFLAGS += -DUSE_FSCRYPT
+    ifeq ($(TW_USE_FSCRYPT_POLICY), 1)
+        LOCAL_CFLAGS += -DUSE_FSCRYPT_POLICY_V1
+    else
+        LOCAL_CFLAGS += -DUSE_FSCRYPT_POLICY_V2
+    endif
     LOCAL_C_INCLUDES += $(LOCAL_PATH)/../crypto/fscrypt
 endif
 
diff --git a/libtar/append.c b/libtar/append.c
index 860ab46..6f0b252 100755
--- a/libtar/append.c
+++ b/libtar/append.c
@@ -153,15 +153,29 @@
 		}
 
 		if (fscrypt_policy_get_struct(realname, t->th_buf.fep)) {
+#ifdef USE_FSCRYPT_POLICY_V1
+			uint8_t tar_policy[FS_KEY_DESCRIPTOR_SIZE];
+			char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+#else
 			uint8_t tar_policy[FSCRYPT_KEY_IDENTIFIER_SIZE];
-			memset(tar_policy, 0, sizeof(tar_policy));
 			char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
+#endif
+			memset(tar_policy, 0, sizeof(tar_policy));
+#ifdef USE_FSCRYPT_POLICY_V1
+			bytes_to_hex(t->th_buf.fep->master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE, policy_hex);
+#else
 			bytes_to_hex(t->th_buf.fep->master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
+#endif
 			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) {
+				if (strncmp((char *) tar_policy, USER_CE_FSCRYPT_POLICY, sizeof(USER_CE_FSCRYPT_POLICY) - 1) == 0 
+				|| strncmp((char *) tar_policy, USER_DE_FSCRYPT_POLICY, sizeof(USER_DE_FSCRYPT_POLICY) - 1) == 0 
+				|| strncmp((char *) tar_policy, SYSTEM_DE_FSCRYPT_POLICY, sizeof(SYSTEM_DE_FSCRYPT_POLICY)) == 0) {
+#ifdef USE_FSCRYPT_POLICY_V1
+					memcpy(t->th_buf.fep->master_key_descriptor, tar_policy, FS_KEY_DESCRIPTOR_SIZE);
+#else
 					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);
+#endif
 				} else {
 					printf("failed to match fscrypt tar policy for '%s' - '%s'\n", realname, policy_hex);
 					free(t->th_buf.fep);
diff --git a/libtar/block.c b/libtar/block.c
index db97222..b46d55a 100755
--- a/libtar/block.c
+++ b/libtar/block.c
@@ -384,8 +384,12 @@
 						(int)t->th_buf.fep->contents_encryption_mode,
 						(int)t->th_buf.fep->filenames_encryption_mode,
 						(int)t->th_buf.fep->flags,
+#ifdef USE_FSCRYPT_POLICY_V1
+						t->th_buf.fep->master_key_descriptor);
+#else
 						t->th_buf.fep->master_key_identifier);
 #endif
+#endif
 				}
 				else {
 					printf("     invalid fscrypt header found\n");
@@ -594,9 +598,14 @@
 	if((t->options & TAR_STORE_FSCRYPT_POL) && t->th_buf.fep != NULL)
 	{
 #ifdef DEBUG
+#ifdef USE_FSCRYPT_POLICY_V1
+		printf("th_write(): using fscrypt_policy %s\n",
+		       t->th_buf.fep->master_key_descriptor);
+#else
 		printf("th_write(): using fscrypt_policy %s\n",
 		       t->th_buf.fep->master_key_identifier);
 #endif
+#endif
 		/* setup size - EXT header has format "*size of this whole tag as ascii numbers* *space* *version code* *content* *newline* */
 		//                                                       size   newline
 #ifdef USE_FSCRYPT_POLICY_V1
diff --git a/libtar/extract.c b/libtar/extract.c
index 064ba9b..65ea1d1 100755
--- a/libtar/extract.c
+++ b/libtar/extract.c
@@ -557,20 +557,42 @@
 #ifdef USE_FSCRYPT
 	if(t->th_buf.fep != NULL)
 	{
-                char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
+#ifdef USE_FSCRYPT_POLICY_V1
+		char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+#else
+		char policy_hex[FSCRYPT_KEY_IDENTIFIER_HEX_SIZE];
+#endif
 #ifdef DEBUG
+#ifdef USE_FSCRYPT_POLICY_V1
+		bytes_to_hex(t->th_buf.fep->master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE, policy_hex);
+#else
 		bytes_to_hex(t->th_buf.fep->master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
+#endif
 		printf("tar_extract_dir(): restoring fscrypt policy %s to dir %s\n", (char *)policy_hex, realname);
 #endif
+#ifdef USE_FSCRYPT_POLICY_V1
+		uint8_t binary_policy[FS_KEY_DESCRIPTOR_SIZE];
+		memset(&binary_policy, 0, FS_KEY_DESCRIPTOR_SIZE);
+#else
 		uint8_t binary_policy[FSCRYPT_KEY_IDENTIFIER_SIZE];
 		memset(&binary_policy, 0, FSCRYPT_KEY_IDENTIFIER_SIZE);
+#endif
 
+#ifdef USE_FSCRYPT_POLICY_V1
+		if (!lookup_ref_tar(t->th_buf.fep->master_key_descriptor, &binary_policy[0])) {
+			printf("error looking up fscrypt policy for '%s' - %s\n", realname, t->th_buf.fep->master_key_descriptor);
+			return -1;
+		}
+		memcpy(&t->th_buf.fep->master_key_descriptor, binary_policy, FS_KEY_DESCRIPTOR_SIZE);
+		bytes_to_hex(t->th_buf.fep->master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE, policy_hex);
+#else
 		if (!lookup_ref_tar(t->th_buf.fep->master_key_identifier, &binary_policy[0])) {
 			printf("error looking up fscrypt policy for '%s' - %s\n", realname, t->th_buf.fep->master_key_identifier);
 			return -1;
 		}
 		memcpy(&t->th_buf.fep->master_key_identifier, binary_policy, FSCRYPT_KEY_IDENTIFIER_SIZE);
 		bytes_to_hex(t->th_buf.fep->master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, policy_hex);
+#endif
 		printf("attempting to restore policy: %s\n", policy_hex);
 		if (!fscrypt_policy_set_struct(realname, t->th_buf.fep))
 		{
diff --git a/libtar/output.c b/libtar/output.c
index 5e724e5..015179d 100755
--- a/libtar/output.c
+++ b/libtar/output.c
@@ -62,9 +62,14 @@
 	       (t->th_buf.gnu_longlink ? t->th_buf.gnu_longlink : "[NULL]"));
 		   
 #ifdef USE_FSCRYPT
+#ifdef USE_FSCRYPT_POLICY_V1
+	printf("  fep = \"%s\"\n",
+	       (t->th_buf.fep ? t->th_buf.fep->master_key_descriptor : (uint8_t*) "[NULL]"));
+#else
 	printf("  fep = \"%s\"\n",
 	       (t->th_buf.fep ? t->th_buf.fep->master_key_identifier : (uint8_t*) "[NULL]"));
 #endif
+#endif
 }