Add metadata decrypt support for FBE
Change-Id: Ie0292f4ffea5993a4ae74fa04fc5c8252ca2cfcf
This commit is contained in:
+118
-82
@@ -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;
|
||||
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;
|
||||
}
|
||||
command += " " + Actual_Block_Device;
|
||||
if (TWFunc::Exec_Cmd(command) == 0) {
|
||||
Recreate_AndSec_Folder();
|
||||
gui_msg("done=Done.");
|
||||
|
||||
Reference in New Issue
Block a user