Permalink
Browse files

Merge pull request #11215 from unknownbrackets/savedata

Respect secureVersion based on tests
  • Loading branch information...
hrydgard committed Jun 25, 2018
2 parents 098a7ff + ecdc4bb commit f0923af53147881d3baf7ba4f4434da65da43e06
Showing with 84 additions and 63 deletions.
  1. +1 −1 Core/Config.cpp
  2. +29 −35 Core/Dialog/PSPSaveDialog.cpp
  3. +50 −23 Core/Dialog/SavedataParam.cpp
  4. +4 −4 Core/Dialog/SavedataParam.h
@@ -797,7 +797,7 @@ static ConfigSetting systemParamSettings[] = {
#endif
ConfigSetting("WlanPowerSave", &g_Config.bWlanPowerSave, (bool) PSP_SYSTEMPARAM_WLAN_POWERSAVE_OFF, true, true),
ReportedConfigSetting("EncryptSave", &g_Config.bEncryptSave, true, true, true),
ConfigSetting("SavedataUpgrade", &g_Config.bSavedataUpgrade, false, true, false),
ConfigSetting("SavedataUpgradeVersion", &g_Config.bSavedataUpgrade, true, true, false),
ConfigSetting(false),
};
@@ -1019,14 +1019,14 @@ void PSPSaveDialog::ExecuteIOAction() {
std::lock_guard<std::mutex> guard(paramLock);
switch (display) {
case DS_LOAD_LOADING:
if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave)) {
if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave) == 0) {
display = DS_LOAD_DONE;
} else {
display = DS_LOAD_FAILED;
}
break;
case DS_SAVE_SAVING:
if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) {
if (param.Save(param.GetPspParam(), GetSelectedSaveDirName()) == 0) {
display = DS_SAVE_DONE;
} else {
display = DS_SAVE_FAILED;
@@ -1052,87 +1052,81 @@ void PSPSaveDialog::ExecuteIOAction() {
}
void PSPSaveDialog::ExecuteNotVisibleIOAction() {
auto &result = param.GetPspParam()->common.result;
switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode) {
case SCE_UTILITY_SAVEDATA_TYPE_LOAD: // Only load and exit
case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD:
if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave)) {
param.GetPspParam()->common.result = 0;
} else {
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
}
result = param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave);
break;
case SCE_UTILITY_SAVEDATA_TYPE_SAVE: // Only save and exit
case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE:
if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) {
param.GetPspParam()->common.result = 0;
} else {
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE;
}
result = param.Save(param.GetPspParam(), GetSelectedSaveDirName());
break;
case SCE_UTILITY_SAVEDATA_TYPE_SIZES:
param.GetPspParam()->common.result = param.GetSizes(param.GetPspParam());
result = param.GetSizes(param.GetPspParam());
break;
case SCE_UTILITY_SAVEDATA_TYPE_LIST:
param.GetList(param.GetPspParam());
param.GetPspParam()->common.result = 0;
result = 0;
break;
case SCE_UTILITY_SAVEDATA_TYPE_FILES:
param.GetPspParam()->common.result = param.GetFilesList(param.GetPspParam());
result = param.GetFilesList(param.GetPspParam());
break;
case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE:
{
bool result = param.GetSize(param.GetPspParam());
bool sizeResult = param.GetSize(param.GetPspParam());
// TODO: According to JPCSP, should test/verify this part but seems edge casey.
if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_INSERTED) {
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK;
} else if (result) {
param.GetPspParam()->common.result = 0;
result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK;
} else if (sizeResult) {
result = 0;
} else {
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
}
}
break;
case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA:
DEBUG_LOG(SCEUTILITY, "sceUtilitySavedata DELETEDATA: %s", param.GetPspParam()->saveName);
param.GetPspParam()->common.result = param.DeleteData(param.GetPspParam());
result = param.DeleteData(param.GetPspParam());
break;
//case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE:
case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE:
if (param.Delete(param.GetPspParam(), param.GetSelectedSave())) {
param.GetPspParam()->common.result = 0;
result = 0;
} else {
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;
result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;
}
break;
// TODO: Should reset the directory's other files.
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA:
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE)) {
param.GetPspParam()->common.result = 0;
if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE) == 0) {
result = 0;
} else if (MemoryStick_FreeSpace() == 0) {
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_MEMSTICK_FULL;
result = SCE_UTILITY_SAVEDATA_ERROR_RW_MEMSTICK_FULL;
} else {
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
}
break;
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA:
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE)) {
param.GetPspParam()->common.result = 0;
if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE) == 0) {
result = 0;
} else {
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
}
break;
case SCE_UTILITY_SAVEDATA_TYPE_READDATA:
case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
if (!param.IsSaveDirectoryExist(param.GetPspParam())){
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
} else if (!param.IsSfoFileExist(param.GetPspParam())) {
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_DATA_BROKEN;
} else if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave, param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE)) {
param.GetPspParam()->common.result = 0;
result = SCE_UTILITY_SAVEDATA_ERROR_RW_DATA_BROKEN;
} else if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave, param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE) == 0) {
result = 0;
} else {
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND;
result = SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND;
}
break;
default:
@@ -358,9 +358,19 @@ int SavedataParam::DeleteData(SceUtilitySavedataParam* param) {
return 0;
}
bool SavedataParam::Save(SceUtilitySavedataParam* param, const std::string &saveDirName, bool secureMode) {
int SavedataParam::Save(SceUtilitySavedataParam* param, const std::string &saveDirName, bool secureMode) {
if (!param) {
return false;
return SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE;
}
if (param->secureVersion > 3) {
ERROR_LOG_REPORT(SCEUTILITY, "Savedata version requested on save: %d", param->secureVersion);
return SCE_UTILITY_SAVEDATA_ERROR_SAVE_PARAM;
} else if (param->secureVersion != 0) {
if (param->secureVersion != 1 && !HasKey(param)) {
ERROR_LOG_REPORT(SCEUTILITY, "Savedata version with missing key on save: %d", param->secureVersion);
return SCE_UTILITY_SAVEDATA_ERROR_SAVE_PARAM;
}
WARN_LOG_REPORT(SCEUTILITY, "Savedata version requested on save: %d", param->secureVersion);
}
std::string dirPath = GetSaveFilePath(param, GetSaveDir(param, saveDirName));
@@ -390,8 +400,13 @@ bool SavedataParam::Save(SceUtilitySavedataParam* param, const std::string &save
memcpy(cryptedData, data_, cryptedSize);
int decryptMode = DetermineCryptMode(param);
if (EncryptData(decryptMode, cryptedData, &cryptedSize, &aligned_len, cryptedHash, (HasKey(param) ? param->key : 0)) != 0)
{
bool hasKey = decryptMode > 1;
if (hasKey && !HasKey(param)) {
delete[] cryptedData;
return SCE_UTILITY_SAVEDATA_ERROR_SAVE_PARAM;
}
if (EncryptData(decryptMode, cryptedData, &cryptedSize, &aligned_len, cryptedHash, (hasKey ? param->key : 0)) != 0) {
I18NCategory *err = GetI18NCategory("Error");
host->NotifyUserMessage(err->T("Save encryption failed. This save won't work on real PSP"), 6.0f);
ERROR_LOG(SCEUTILITY,"Save encryption failed. This save won't work on real PSP");
@@ -502,11 +517,8 @@ bool SavedataParam::Save(SceUtilitySavedataParam* param, const std::string &save
if (!WritePSPFile(filePath, data_, saveSize))
{
ERROR_LOG(SCEUTILITY,"Error writing file %s",filePath.c_str());
if(cryptedData != 0)
{
delete[] cryptedData;
}
return false;
delete[] cryptedData;
return SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE;
}
delete[] cryptedData;
}
@@ -538,23 +550,23 @@ bool SavedataParam::Save(SceUtilitySavedataParam* param, const std::string &save
WritePSPFile(snd0path, param->snd0FileData.buf, param->snd0FileData.bufSize);
}
return true;
return 0;
}
bool SavedataParam::Load(SceUtilitySavedataParam *param, const std::string &saveDirName, int saveId, bool secureMode)
{
int SavedataParam::Load(SceUtilitySavedataParam *param, const std::string &saveDirName, int saveId, bool secureMode) {
if (!param) {
return false;
return SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
}
std::string dirPath = GetSaveFilePath(param, GetSaveDir(param, saveDirName));
std::string filePath = dirPath + "/" + GetFileName(param);
if (!pspFileSystem.GetFileInfo(filePath).exists) {
return false;
return SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
}
if(!LoadSaveData(param, saveDirName, dirPath, secureMode)) // Load main savedata
return false;
int result = LoadSaveData(param, saveDirName, dirPath, secureMode);
if (result != 0)
return result;
LoadSFO(param, dirPath); // Load sfo
@@ -572,11 +584,18 @@ bool SavedataParam::Load(SceUtilitySavedataParam *param, const std::string &save
// Load SND0.AT3
LoadFile(dirPath, SND0_FILENAME, &param->snd0FileData);
return true;
return 0;
}
bool SavedataParam::LoadSaveData(SceUtilitySavedataParam *param, const std::string &saveDirName, const std::string& dirPath, bool secureMode) {
if (param->secureVersion != 0) {
int SavedataParam::LoadSaveData(SceUtilitySavedataParam *param, const std::string &saveDirName, const std::string &dirPath, bool secureMode) {
if (param->secureVersion > 3) {
ERROR_LOG_REPORT(SCEUTILITY, "Savedata version requested: %d", param->secureVersion);
return SCE_UTILITY_SAVEDATA_ERROR_LOAD_PARAM;
} else if (param->secureVersion != 0) {
if (param->secureVersion != 1 && !HasKey(param)) {
ERROR_LOG_REPORT(SCEUTILITY, "Savedata version with missing key: %d", param->secureVersion);
return SCE_UTILITY_SAVEDATA_ERROR_LOAD_PARAM;
}
WARN_LOG_REPORT(SCEUTILITY, "Savedata version requested: %d", param->secureVersion);
}
u8 *data_ = param->dataBuf;
@@ -587,7 +606,7 @@ bool SavedataParam::LoadSaveData(SceUtilitySavedataParam *param, const std::stri
int saveSize = -1;
if (!ReadPSPFile(filePath, &saveData, saveSize, &readSize)) {
ERROR_LOG(SCEUTILITY,"Error reading file %s",filePath.c_str());
return false;
return SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
}
saveSize = (int)readSize;
@@ -598,22 +617,30 @@ bool SavedataParam::LoadSaveData(SceUtilitySavedataParam *param, const std::stri
bool isCrypted = prevCryptMode != 0 && secureMode;
bool saveDone = false;
if (isCrypted) {
if (DetermineCryptMode(param) > 1 && !HasKey(param))
return SCE_UTILITY_SAVEDATA_ERROR_LOAD_PARAM;
LoadCryptedSave(param, data_, saveData, saveSize, prevCryptMode, saveDone);
// TODO: Should return SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN here if !saveDone.
}
if (!saveDone) {
LoadNotCryptedSave(param, data_, saveData, saveSize);
}
param->dataSize = (SceSize)saveSize;
delete[] saveData;
return true;
return 0;
}
int SavedataParam::DetermineCryptMode(const SceUtilitySavedataParam *param) const {
int decryptMode = 1;
if (param->secureVersion != 0) {
decryptMode = param->secureVersion;
if (param->secureVersion == 1) {
decryptMode = 1;
} else if (param->secureVersion == 2) {
decryptMode = 3;
} else if (param->secureVersion == 3) {
decryptMode = GetSDKMainVersion(sceKernelGetCompiledSdkVersion()) >= 4 ? 5 : 1;
} else if (HasKey(param)) {
// TODO: This should ignore HasKey(), which would trigger errors. Not doing that yet to play it safe.
decryptMode = GetSDKMainVersion(sceKernelGetCompiledSdkVersion()) >= 4 ? 5 : 3;
}
return decryptMode;
@@ -253,7 +253,7 @@ struct SceUtilitySavedataParam
u8 key[16];
s32_le secureVersion;
u32_le secureVersion;
s32_le multiStatus;
// Function 11 LIST
@@ -306,8 +306,8 @@ class SavedataParam
std::string GetSaveDir(const SceUtilitySavedataParam *param, const std::string &saveDirName) const;
bool Delete(SceUtilitySavedataParam* param, int saveId = -1);
int DeleteData(SceUtilitySavedataParam* param);
bool Save(SceUtilitySavedataParam* param, const std::string &saveDirName, bool secureMode = true);
bool Load(SceUtilitySavedataParam* param, const std::string &saveDirName, int saveId = -1, bool secureMode = true);
int Save(SceUtilitySavedataParam* param, const std::string &saveDirName, bool secureMode = true);
int Load(SceUtilitySavedataParam* param, const std::string &saveDirName, int saveId = -1, bool secureMode = true);
int GetSizes(SceUtilitySavedataParam* param);
bool GetList(SceUtilitySavedataParam* param);
int GetFilesList(SceUtilitySavedataParam* param);
@@ -354,7 +354,7 @@ class SavedataParam
void SetFileInfo(SaveFileInfo &saveInfo, PSPFileInfo &info, std::string saveName);
void ClearFileInfo(SaveFileInfo &saveInfo, const std::string &saveName);
bool LoadSaveData(SceUtilitySavedataParam *param, const std::string &saveDirName, const std::string& dirPath, bool secureMode);
int LoadSaveData(SceUtilitySavedataParam *param, const std::string &saveDirName, const std::string& dirPath, bool secureMode);
void LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize, int prevCryptMode, bool &saveDone);
void LoadNotCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize);
void LoadSFO(SceUtilitySavedataParam *param, const std::string& dirPath);

0 comments on commit f0923af

Please sign in to comment.