diff --git a/crypto/fscrypt/Android.mk b/crypto/fscrypt/Android.mk index a10a7e69..d9fb6ef5 100755 --- a/crypto/fscrypt/Android.mk +++ b/crypto/fscrypt/Android.mk @@ -36,6 +36,12 @@ LOCAL_C_INCLUDES := system/extras/ext4_utils \ 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 5878d15d..00554715 100755 --- a/crypto/fscrypt/Decrypt.cpp +++ b/crypto/fscrypt/Decrypt.cpp @@ -98,12 +98,22 @@ inline std::string hidlVec2String(const ::keystore::hidl_vec& value) { } static bool lookup_ref_key_internal(std::map 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::iterator it=key_map.begin(); it!=key_map.end(); ++it) { +#ifdef USE_FSCRYPT_POLICY_V1 + bytes_to_hex(reinterpret_cast(&it->second.key_raw_ref[0]), FS_KEY_DESCRIPTOR_SIZE, key_map_hex); +#else bytes_to_hex(reinterpret_cast(&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 @@ static bool lookup_ref_key_internal(std::mapmaster_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_key(fscrypt_policy_v2* v2, uint8_t* policy_type) { 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 @@ extern "C" bool lookup_ref_tar(const uint8_t* policy_type, uint8_t* policy) { 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 99833f8e..9ca3ed4f 100755 --- a/crypto/fscrypt/fscrypt_policy.cpp +++ b/crypto/fscrypt/fscrypt_policy.cpp @@ -180,7 +180,11 @@ extern "C" bool fscrypt_policy_get_struct(const char *directory, struct fscrypt_ 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 c99ce2ec..57147901 100755 --- a/crypto/fscrypt/fscrypt_policy.h +++ b/crypto/fscrypt/fscrypt_policy.h @@ -27,6 +27,22 @@ __BEGIN_DECLS #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 */ #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 05e9d6f0..189a4281 100755 --- a/crypto/fscrypt/fscryptpolicyget.cpp +++ b/crypto/fscrypt/fscryptpolicyget.cpp @@ -31,8 +31,13 @@ int main(int argc, char *argv[]) { 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 2fd44515..bc23757d 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 9209da90..6ff8fc92 100755 --- a/libtar/Android.mk +++ b/libtar/Android.mk @@ -16,6 +16,11 @@ LOCAL_SHARED_LIBRARIES += libselinux 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 860ab463..6f0b2527 100755 --- a/libtar/append.c +++ b/libtar/append.c @@ -153,15 +153,29 @@ tar_append_file(TAR *t, const char *realname, const char *savename) } 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 db972220..b46d55a9 100755 --- a/libtar/block.c +++ b/libtar/block.c @@ -384,7 +384,11 @@ th_read(TAR *t) (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 { @@ -594,8 +598,13 @@ th_write(TAR *t) 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 diff --git a/libtar/extract.c b/libtar/extract.c index 064ba9ba..65ea1d16 100755 --- a/libtar/extract.c +++ b/libtar/extract.c @@ -557,20 +557,42 @@ tar_extract_dir(TAR *t, const char *realname) #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 5e724e5a..015179de 100755 --- a/libtar/output.c +++ b/libtar/output.c @@ -62,9 +62,14 @@ th_print(TAR *t) (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 }