Add support for multi-user decryption
* Add CLI support using the command "twrp decrypt <PASSWORD> [USER ID]"
* Add GUI support using the menu Advanced --> Decrypt User
multiuser: Parse users only when Decrypt_DE runs successfully
multiuser: Warn when not all users are decrypted
Change-Id: Ia5e943b13c2d5ec5c34ae97661133c19ff471e6d
diff --git a/partition.cpp b/partition.cpp
index 2c5f352..5de102f 100755
--- a/partition.cpp
+++ b/partition.cpp
@@ -667,7 +667,8 @@
} else if (!Mount(false)) {
if (Is_Present) {
if (Key_Directory.empty()) {
- set_partition_data(Actual_Block_Device.c_str(), Crypto_Key_Location.c_str(), Fstab_File_System.c_str());
+ 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;
@@ -675,6 +676,7 @@
Current_File_System = "emmc";
Setup_Image();
DataManager::SetValue(TW_CRYPTO_PWTYPE, cryptfs_get_password_type());
+ DataManager::SetValue("tw_crypto_pwtype_0", cryptfs_get_password_type());
DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
DataManager::SetValue("tw_crypto_display", "");
} else {
@@ -685,7 +687,8 @@
Is_Decrypted = false;
}
} 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());
+ LOGERR("Primary block device '%s' for mount point '%s' is not present!\n",
+ Primary_Block_Device.c_str(), Mount_Point.c_str());
}
} else {
Set_FBE_Status();
@@ -737,48 +740,55 @@
DataManager::SetValue(TW_CRYPTO_PWTYPE, "0"); // Set initial value so that recovery will not be confused when using unencrypted data or failed to decrypt data
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 + "/misc/vold/volume_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
- ExcludeAll(Mount_Point + "/per_boot"); // removed each boot by init
-
- 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);
- 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;
+ Is_FBE = true;
+ ExcludeAll(Mount_Point + "/convert_fbe");
+ ExcludeAll(Mount_Point + "/unencrypted");
+ ExcludeAll(Mount_Point + "/misc/vold/user_keys");
+ ExcludeAll(Mount_Point + "/misc/vold/volume_keys");
+ 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-wal");
+ 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
+ ExcludeAll(Mount_Point + "/system/users/0/gatekeeper.password.key");
+ ExcludeAll(Mount_Point + "/system/users/0/gatekeeper.pattern.key");
+ ExcludeAll(Mount_Point + "/cache");
+ ExcludeAll(Mount_Point + "/per_boot"); // removed each boot by init
+ 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;
+ 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
}
+ PartitionManager.Parse_Users(); // after load_all_de_keys() to parse_users
+ std::vector<users_struct>::iterator iter;
+ std::vector<users_struct>* userList = PartitionManager.Get_Users_List();
+ for (iter = userList->begin(); iter != userList->end(); iter++) {
+ if (atoi((*iter).userId.c_str()) != 0) {
+ ExcludeAll(Mount_Point + "/system_de/" + (*iter).userId + "/spblob");
+ ExcludeAll(Mount_Point + "/system/users/" + (*iter).userId + "/gatekeeper.password.key");
+ ExcludeAll(Mount_Point + "/system/users/" + (*iter).userId + "/gatekeeper.pattern.key");
+ ExcludeAll(Mount_Point + "/system/users/" + (*iter).userId + "/locksettings.db");
+ ExcludeAll(Mount_Point + "/system/users/" + (*iter).userId + "/locksettings.db-wal");
+ }
+ }
+ DataManager::SetValue(TW_CRYPTO_PWTYPE, pwd_type);
+ DataManager::SetValue("tw_crypto_pwtype_0", 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
@@ -2546,6 +2556,22 @@
Full_FileName = part_settings->Backup_Folder + "/" + Backup_FileName;
if (Has_Data_Media)
gui_msg(Msg(msg::kWarning, "backup_storage_warning=Backups of {1} do not include any files in internal storage such as pictures or downloads.")(Display_Name));
+ if (Mount_Point == "/data" && DataManager::GetIntValue(TW_IS_FBE)) {
+ std::vector<users_struct>::iterator iter;
+ std::vector<users_struct>* userList = PartitionManager.Get_Users_List();
+ for (iter = userList->begin(); iter != userList->end(); iter++) {
+ if (!(*iter).isDecrypted && (*iter).userId != "0") {
+ gui_msg(Msg(msg::kWarning,
+ "backup_storage_undecrypt_warning=Backup will not include some files from user {1} "
+ "because the user is not decrypted.")((*iter).userId));
+ backup_exclusions.add_absolute_dir("/data/system_ce/" + (*iter).userId);
+ backup_exclusions.add_absolute_dir("/data/misc_ce/" + (*iter).userId);
+ backup_exclusions.add_absolute_dir("/data/vendor_ce/" + (*iter).userId);
+ backup_exclusions.add_absolute_dir("/data/media/" + (*iter).userId);
+ backup_exclusions.add_absolute_dir("/data/user/" + (*iter).userId);
+ }
+ }
+ }
tar.part_settings = part_settings;
tar.backup_exclusions = &backup_exclusions;
tar.setdir(Backup_Path);