From 933828251d862bc24b888d247a1cb13573e7232b Mon Sep 17 00:00:00 2001 From: Ethan Yonker Date: Thu, 1 Nov 2018 15:25:31 -0500 Subject: Add metadata decrypt support for FBE Change-Id: Ie0292f4ffea5993a4ae74fa04fc5c8252ca2cfcf --- partition.cpp | 202 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 119 insertions(+), 83 deletions(-) (limited to 'partition.cpp') diff --git a/partition.cpp b/partition.cpp index 1bdb91a35..ee346863d 100644 --- a/partition.cpp +++ b/partition.cpp @@ -114,6 +114,8 @@ const struct flag_list mount_flags[] = { const char *ignored_mount_items[] = { "defaults=", "errors=", + "latemount", + "sysfs_path=", NULL }; @@ -154,6 +156,7 @@ enum TW_FSTAB_FLAGS { TWFLAG_VOLDMANAGED, TWFLAG_FORMATTABLE, TWFLAG_RESIZE, + TWFLAG_KEYDIRECTORY, }; /* Flags without a trailing '=' are considered dual format flags and can be @@ -197,6 +200,7 @@ const struct flag_list tw_flags[] = { { "voldmanaged=", TWFLAG_VOLDMANAGED }, { "formattable", TWFLAG_FORMATTABLE }, { "resize", TWFLAG_RESIZE }, + { "keydirectory=", TWFLAG_KEYDIRECTORY }, { 0, 0 }, }; @@ -260,6 +264,7 @@ TWPartition::TWPartition() { Is_Adopted_Storage = false; Adopted_GUID = ""; SlotSelect = false; + Key_Directory = ""; } TWPartition::~TWPartition(void) { @@ -624,80 +629,39 @@ void TWPartition::Setup_Data_Partition(bool Display_Error) { DataManager::SetValue(TW_IS_DECRYPTED, 1); Is_Encrypted = true; Is_Decrypted = true; - Is_FBE = false; + if (Key_Directory.empty()) + Is_FBE = false; + else + Is_FBE = true; DataManager::SetValue(TW_IS_FBE, 0); Decrypted_Block_Device = crypto_blkdev; LOGINFO("Data already decrypted, new block device: '%s'\n", crypto_blkdev); } else if (!Mount(false)) { if (Is_Present) { - set_partition_data(Actual_Block_Device.c_str(), Crypto_Key_Location.c_str(), Fstab_File_System.c_str()); - if (cryptfs_check_footer() == 0) { + if (Key_Directory.empty()) { + set_partition_data(Actual_Block_Device.c_str(), Crypto_Key_Location.c_str(), Fstab_File_System.c_str()); + if (cryptfs_check_footer() == 0) { + Is_Encrypted = true; + Is_Decrypted = false; + Can_Be_Mounted = false; + Current_File_System = "emmc"; + Setup_Image(); + DataManager::SetValue(TW_IS_ENCRYPTED, 1); + DataManager::SetValue(TW_CRYPTO_PWTYPE, cryptfs_get_password_type()); + DataManager::SetValue(TW_CRYPTO_PASSWORD, ""); + DataManager::SetValue("tw_crypto_display", ""); + } else { + gui_err("mount_data_footer=Could not mount /data and unable to find crypto footer."); + } + } else { Is_Encrypted = true; Is_Decrypted = false; - Can_Be_Mounted = false; - Current_File_System = "emmc"; - Setup_Image(); - DataManager::SetValue(TW_IS_ENCRYPTED, 1); - DataManager::SetValue(TW_CRYPTO_PWTYPE, cryptfs_get_password_type()); - DataManager::SetValue(TW_CRYPTO_PASSWORD, ""); - DataManager::SetValue("tw_crypto_display", ""); - } else { - gui_err("mount_data_footer=Could not mount /data and unable to find crypto footer."); } - } else { + } else if (Key_Directory.empty()) { LOGERR("Primary block device '%s' for mount point '%s' is not present!\n", Primary_Block_Device.c_str(), Mount_Point.c_str()); } } else { - if (TWFunc::Path_Exists("/data/unencrypted/key/version")) { - LOGINFO("File Based Encryption is present\n"); -#ifdef TW_INCLUDE_FBE - ExcludeAll(Mount_Point + "/convert_fbe"); - ExcludeAll(Mount_Point + "/unencrypted"); - //ExcludeAll(Mount_Point + "/system/users/0"); // we WILL need to retain some of this if multiple users are present or we just need to delete more folders for the extra users somewhere else - ExcludeAll(Mount_Point + "/misc/vold/user_keys"); - //ExcludeAll(Mount_Point + "/system_ce"); - //ExcludeAll(Mount_Point + "/system_de"); - //ExcludeAll(Mount_Point + "/misc_ce"); - //ExcludeAll(Mount_Point + "/misc_de"); - ExcludeAll(Mount_Point + "/system/gatekeeper.password.key"); - ExcludeAll(Mount_Point + "/system/gatekeeper.pattern.key"); - ExcludeAll(Mount_Point + "/system/locksettings.db"); - //ExcludeAll(Mount_Point + "/system/locksettings.db-shm"); // don't seem to need this one, but the other 2 are needed - ExcludeAll(Mount_Point + "/system/locksettings.db-wal"); - //ExcludeAll(Mount_Point + "/user_de"); - //ExcludeAll(Mount_Point + "/misc/profiles/cur/0"); // might be important later - ExcludeAll(Mount_Point + "/misc/gatekeeper"); - ExcludeAll(Mount_Point + "/misc/keystore"); - ExcludeAll(Mount_Point + "/drm/kek.dat"); - ExcludeAll(Mount_Point + "/system_de/0/spblob"); // contains data needed to decrypt pixel 2 - int retry_count = 3; - while (!Decrypt_DE() && --retry_count) - usleep(2000); - if (retry_count > 0) { - property_set("ro.crypto.state", "encrypted"); - Is_Encrypted = true; - Is_Decrypted = false; - Is_FBE = true; - DataManager::SetValue(TW_IS_FBE, 1); - DataManager::SetValue(TW_IS_ENCRYPTED, 1); - string filename; - int pwd_type = Get_Password_Type(0, filename); - if (pwd_type < 0) { - LOGERR("This TWRP does not have synthetic password decrypt support\n"); - pwd_type = 0; // default password - } - DataManager::SetValue(TW_CRYPTO_PWTYPE, pwd_type); - DataManager::SetValue(TW_CRYPTO_PASSWORD, ""); - DataManager::SetValue("tw_crypto_display", ""); - } -#else - LOGERR("FBE found but FBE support not present in TWRP\n"); -#endif - } else { - // Filesystem is not encrypted and the mount succeeded, so return to - // the original unmounted state - UnMount(false); - } + Decrypt_FBE_DE(); } if (datamedia && (!Is_Encrypted || (Is_Encrypted && Is_Decrypted))) { Setup_Data_Media(); @@ -711,6 +675,57 @@ void TWPartition::Setup_Data_Partition(bool Display_Error) { #endif } +bool TWPartition::Decrypt_FBE_DE() { +if (TWFunc::Path_Exists("/data/unencrypted/key/version")) { + LOGINFO("File Based Encryption is present\n"); +#ifdef TW_INCLUDE_FBE + ExcludeAll(Mount_Point + "/convert_fbe"); + ExcludeAll(Mount_Point + "/unencrypted"); + //ExcludeAll(Mount_Point + "/system/users/0"); // we WILL need to retain some of this if multiple users are present or we just need to delete more folders for the extra users somewhere else + ExcludeAll(Mount_Point + "/misc/vold/user_keys"); + //ExcludeAll(Mount_Point + "/system_ce"); + //ExcludeAll(Mount_Point + "/system_de"); + //ExcludeAll(Mount_Point + "/misc_ce"); + //ExcludeAll(Mount_Point + "/misc_de"); + ExcludeAll(Mount_Point + "/system/gatekeeper.password.key"); + ExcludeAll(Mount_Point + "/system/gatekeeper.pattern.key"); + ExcludeAll(Mount_Point + "/system/locksettings.db"); + //ExcludeAll(Mount_Point + "/system/locksettings.db-shm"); // don't seem to need this one, but the other 2 are needed + ExcludeAll(Mount_Point + "/system/locksettings.db-wal"); + //ExcludeAll(Mount_Point + "/user_de"); + //ExcludeAll(Mount_Point + "/misc/profiles/cur/0"); // might be important later + ExcludeAll(Mount_Point + "/misc/gatekeeper"); + ExcludeAll(Mount_Point + "/misc/keystore"); + ExcludeAll(Mount_Point + "/drm/kek.dat"); + ExcludeAll(Mount_Point + "/system_de/0/spblob"); // contains data needed to decrypt pixel 2 + int retry_count = 3; + while (!Decrypt_DE() && --retry_count) + usleep(2000); + if (retry_count > 0) { + property_set("ro.crypto.state", "encrypted"); + Is_Encrypted = true; + Is_Decrypted = false; + Is_FBE = true; + DataManager::SetValue(TW_IS_FBE, 1); + DataManager::SetValue(TW_IS_ENCRYPTED, 1); + string filename; + int pwd_type = Get_Password_Type(0, filename); + if (pwd_type < 0) { + LOGERR("This TWRP does not have synthetic password decrypt support\n"); + pwd_type = 0; // default password + } + DataManager::SetValue(TW_CRYPTO_PWTYPE, pwd_type); + DataManager::SetValue(TW_CRYPTO_PASSWORD, ""); + DataManager::SetValue("tw_crypto_display", ""); + return true; + } +#else + LOGERR("FBE found but FBE support not present in TWRP\n"); +#endif + } + return false; +} + void TWPartition::Setup_Cache_Partition(bool Display_Error __unused) { if (Mount_Point != "/cache") return; @@ -826,12 +841,14 @@ void TWPartition::Apply_TW_Flag(const unsigned flag, const char* str, const bool // fileencryption=ice:aes-256-heh { std::string FBE = str; - std::string FBE_contents, FBE_filenames; size_t colon_loc = FBE.find(":"); if (colon_loc == std::string::npos) { - LOGINFO("Invalid fileencryption fstab flag: '%s'\n", str); + property_set("fbe.contents", FBE.c_str()); + property_set("fbe.filenames", ""); + LOGINFO("FBE contents '%s', filenames ''\n", FBE.c_str()); break; } + std::string FBE_contents, FBE_filenames; FBE_contents = FBE.substr(0, colon_loc); FBE_filenames = FBE.substr(colon_loc + 1); property_set("fbe.contents", FBE_contents.c_str()); @@ -905,6 +922,8 @@ void TWPartition::Apply_TW_Flag(const unsigned flag, const char* str, const bool case TWFLAG_ALTDEVICE: Alternate_Block_Device = str; break; + case TWFLAG_KEYDIRECTORY: + Key_Directory = str; default: // Should not get here LOGINFO("Flag identified for processing, but later unmatched: %i\n", flag); @@ -1904,21 +1923,26 @@ bool TWPartition::Decrypt(string Password) { bool TWPartition::Wipe_Encryption() { bool Save_Data_Media = Has_Data_Media; + bool ret = false; + BasePartition* base_partition = make_partition(); + + if (!base_partition->PreWipeEncryption()) + goto exit; if (!UnMount(true)) - return false; + goto exit; Has_Data_Media = false; - Decrypted_Block_Device = ""; #ifdef TW_INCLUDE_CRYPTO if (Is_Decrypted && !Decrypted_Block_Device.empty()) { if (!UnMount(true)) - return false; + goto exit; if (delete_crypto_blk_dev((char*)("userdata")) != 0) { LOGERR("Error deleting crypto block device, continuing anyway.\n"); } } #endif + Decrypted_Block_Device = ""; Is_Decrypted = false; Is_Encrypted = false; Find_Actual_Block_Device(); @@ -1978,15 +2002,22 @@ bool TWPartition::Wipe_Encryption() { #ifndef TW_OEM_BUILD gui_msg("format_data_msg=You may need to reboot recovery to be able to use /data again."); #endif - return true; + ret = true; + if (!Key_Directory.empty()) + ret = PartitionManager.Wipe_By_Path(Key_Directory); + if (ret) + ret = base_partition->PostWipeEncryption(); + goto exit; } else { Has_Data_Media = Save_Data_Media; gui_err("format_data_err=Unable to format to remove encryption."); if (Has_Data_Media && Mount(false)) PartitionManager.Add_MTP_Storage(MTP_Storage_ID); - return false; + goto exit; } - return false; +exit: + delete base_partition; + return ret; } void TWPartition::Check_FS_Type() { @@ -2233,18 +2264,23 @@ bool TWPartition::Wipe_F2FS() { gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("mkfs.f2fs")); Find_Actual_Block_Device(); - command = "mkfs.f2fs -t 0"; - if (!Is_Decrypted && Length != 0) { - // Only use length if we're not decrypted - char len[32]; - int mod_length = Length; - if (Length < 0) - mod_length *= -1; - sprintf(len, "%i", mod_length); - command += " -r "; - command += len; - } - command += " " + Actual_Block_Device; + if (!TWFunc::Path_Exists("/sbin/sload.f2fs")) { + command = "mkfs.f2fs -t 0"; + if (!Is_Decrypted && Length != 0) { + // Only use length if we're not decrypted + char len[32]; + int mod_length = Length; + if (Length < 0) + mod_length *= -1; + sprintf(len, "%i", mod_length); + command += " -r "; + command += len; + } + command += " " + Actual_Block_Device; + } else { + unsigned long long size = IOCTL_Get_Block_Size() + Length; + command = "mkfs.f2fs -d1 -f -O encrypt -O quota -O verity -w 4096 " + Actual_Block_Device + " " + std::to_string(size / 4096) + " && sload.f2fs -t /data " + Actual_Block_Device; + } if (TWFunc::Exec_Cmd(command) == 0) { Recreate_AndSec_Folder(); gui_msg("done=Done."); -- cgit v1.2.3