summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLPFaint99 <lpfaint99@gmail.com>2011-06-27 06:19:23 +0000
committerLPFaint99 <lpfaint99@gmail.com>2011-06-27 06:19:23 +0000
commitf95bcfc1c24d60327178abddfc93d62bebea08c0 (patch)
tree54d084099fb25ae2c4aecfc1f7f2f7538caf27d2 /Source/Core
parent46b95db6c71441535b7055701ea235a2f75511d0 (diff)
Wii Save Export can now successfully create data.bin files that the wii will accept as long as the user has their wii's private keys.
requires NG-id, NG-key-id, NG-priv, NG-sig sorry for not fixing this sooner, I forgot that I cleared my wiis private keys before the initial commit git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7642 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/DolphinWX/Src/MemoryCards/WiiSaveCrypted.cpp148
-rw-r--r--Source/Core/DolphinWX/Src/MemoryCards/WiiSaveCrypted.h21
2 files changed, 95 insertions, 74 deletions
diff --git a/Source/Core/DolphinWX/Src/MemoryCards/WiiSaveCrypted.cpp b/Source/Core/DolphinWX/Src/MemoryCards/WiiSaveCrypted.cpp
index 73b94e9419..43f4c63367 100644
--- a/Source/Core/DolphinWX/Src/MemoryCards/WiiSaveCrypted.cpp
+++ b/Source/Core/DolphinWX/Src/MemoryCards/WiiSaveCrypted.cpp
@@ -33,18 +33,16 @@ const u8 SDKey[16] = {0xAB, 0x01, 0xB9, 0xD8, 0xE1, 0x62, 0x2B, 0x08,
const u8 MD5_BLANKER[0x10] = {0x0E, 0x65, 0x37, 0x81, 0x99, 0xBE, 0x45, 0x17,
0xAB, 0x06, 0xEC, 0x22, 0x45, 0x1A, 0x57, 0x93};
-CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 title)
- : _saveGameTitle(title)
+CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 TitleID)
+ : m_TitleID(TitleID)
{
Common::ReadReplacements(replacements);
strcpy(pathData_bin, FileName);
memcpy(SD_IV, "\x21\x67\x12\xE6\xAA\x1F\x68\x9F\x95\xC5\xA2\x23\x24\xDC\x6A\x98", 0x10);
- if (!title)
+ if (!TitleID) // Import
{
- AES_set_decrypt_key(SDKey, 128, &m_AES_KEY);
-
-
+ AES_set_decrypt_key(SDKey, 128, &m_AES_KEY);
do
{
b_valid = true;
@@ -66,12 +64,39 @@ CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 title)
if (getPaths(true))
{
+ memset(&keys, 0, sizeof(_keys));
+ std::string keysdir = File::GetSysDirectory() + "/Wii/";
+ std::string NG_id = keysdir + "NG-id";
+ std::string NG_key_id = keysdir + "NG-key-id";
+ std::string NG_priv = keysdir + "NG-priv";
+ std::string NG_sig = keysdir + "NG-sig";
+ if (!File::Exists(NG_id) || !File::Exists(NG_key_id) ||
+ !File::Exists(NG_priv) ||!File::Exists(NG_sig))
+ {
+ if (!AskYesNoT("Wii Private Keys not found, the exported save will only work with dolphin\n Continue?"))
+ {
+ PanicAlertT("Key files not found, save will not copy to wii\nPlace NG-id, NG-key-id, NG-priv, and NG-sig in the folder\n%s", keysdir.c_str());
+ return;
+ }
+ }
+ else
+ {
+ File::IOFile fp_key(NG_id, "rb");
+ fp_key.ReadBytes(keys.NG_id, 4);
+ fp_key.Open(NG_key_id, "rb");
+ fp_key.ReadBytes(keys.NG_key_id, 4);
+ fp_key.Open(NG_priv, "rb");
+ fp_key.ReadBytes(keys.NG_priv, 30);
+ fp_key.Open(NG_sig, "rb");
+ fp_key.ReadBytes(keys.NG_sig, 60);
+ }
+
do
{
b_valid = true;
WriteHDR();
WriteBKHDR();
- ExportWiiSaveFiles();
+ ExportWiiSaveFiles();
do_sig();
if (b_valid)
{
@@ -110,7 +135,7 @@ void CWiiSaveCrypted::ReadHDR()
b_valid = false;
return;
}
- _saveGameTitle = Common::swap64(_header.hdr.SaveGameTitle);
+ m_TitleID = Common::swap64(_header.hdr.SaveGameTitle);
memcpy(md5_file, _header.hdr.Md5, 0x10);
memcpy(_header.hdr.Md5, MD5_BLANKER, 0x10);
@@ -126,10 +151,10 @@ void CWiiSaveCrypted::ReadHDR()
b_valid = false;
return;
}
- if (!File::Exists(pathBanner_bin) || AskYesNoT("%s already exists, overwrite?", pathBanner_bin))
+ if (!File::Exists(BannerFilePath) || AskYesNoT("%s already exists, overwrite?", BannerFilePath.c_str()))
{
- INFO_LOG(CONSOLE, "creating file %s", pathBanner_bin);
- File::IOFile fpBanner_bin(pathBanner_bin, "wb");
+ INFO_LOG(CONSOLE, "creating file %s", BannerFilePath.c_str());
+ File::IOFile fpBanner_bin(BannerFilePath, "wb");
fpBanner_bin.WriteBytes(_header.BNR, _bannerSize);
}
}
@@ -139,14 +164,15 @@ void CWiiSaveCrypted::WriteHDR()
if (!b_valid) return;
memset(&_header, 0, HEADER_SZ);
- _header.hdr.BannerSize = Common::swap32(File::GetSize(pathBanner_bin));
+ u32 bannerSize = File::GetSize(BannerFilePath);
+ _header.hdr.BannerSize = Common::swap32(bannerSize);
- _header.hdr.SaveGameTitle = Common::swap64(_saveGameTitle);
+ _header.hdr.SaveGameTitle = Common::swap64(m_TitleID);
memcpy(_header.hdr.Md5, MD5_BLANKER, 0x10);
- _header.hdr.Permissions = 0x3C;//0x35;
+ _header.hdr.Permissions = 0x35;
- File::IOFile fpBanner_bin(pathBanner_bin, "rb");
- if (!fpBanner_bin.ReadBytes(_header.BNR, Common::swap32(_header.hdr.BannerSize)))
+ File::IOFile fpBanner_bin(BannerFilePath, "rb");
+ if (!fpBanner_bin.ReadBytes(_header.BNR, bannerSize))
{
PanicAlertT("Failed to read banner.bin");
b_valid = false;
@@ -202,8 +228,8 @@ void CWiiSaveCrypted::ReadBKHDR()
if (_sizeOfFiles + FULL_CERT_SZ != _totalSize)
WARN_LOG(CONSOLE, "Size(%x) + cert(%x) does not equal totalsize(%x)", _sizeOfFiles, FULL_CERT_SZ, _totalSize);
- if (_saveGameTitle != Common::swap64(bkhdr.SaveGameTitle))
- WARN_LOG(CONSOLE, "encrypted title (%llx) does not match unencrypted title (%llx)", _saveGameTitle, Common::swap64(bkhdr.SaveGameTitle));
+ if (m_TitleID != Common::swap64(bkhdr.SaveGameTitle))
+ WARN_LOG(CONSOLE, "encrypted title (%llx) does not match unencrypted title (%llx)", m_TitleID, Common::swap64(bkhdr.SaveGameTitle));
}
void CWiiSaveCrypted::WriteBKHDR()
@@ -212,21 +238,15 @@ void CWiiSaveCrypted::WriteBKHDR()
_numberOfFiles = 0;
_sizeOfFiles = 0;
- ScanForFiles(pathSavedir, FilesList, &_numberOfFiles, &_sizeOfFiles);
+ ScanForFiles(WiiTitlePath, FilesList, &_numberOfFiles, &_sizeOfFiles);
memset(&bkhdr, 0, BK_SZ);
bkhdr.size = Common::swap32(BK_LISTED_SZ);
bkhdr.magic = Common::swap32(BK_HDR_MAGIC);
-//customize this
- bkhdr.NGid = Common::swap32(1);
-//
+ bkhdr.NGid = *(u32*)(keys.NG_id);
bkhdr.numberOfFiles = Common::swap32(_numberOfFiles);
bkhdr.sizeOfFiles = Common::swap32(_sizeOfFiles);
bkhdr.totalSize = Common::swap32(_sizeOfFiles + FULL_CERT_SZ);
- bkhdr.SaveGameTitle = Common::swap64(_saveGameTitle);
-// customize this
- const u8 MAC[6] = {0};
-//
- memcpy(bkhdr.MACaddress, MAC, 6);
+ bkhdr.SaveGameTitle = Common::swap64(m_TitleID);
File::IOFile fpData_bin(pathData_bin, "ab");
if (!fpData_bin.WriteBytes(&bkhdr, BK_SZ))
@@ -279,8 +299,8 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
fileName.replace(j, 1, iter->second);
}
- sprintf(pathRawSave, "%s%s", pathSavedir, fileName.c_str());
- File::CreateFullPath(pathRawSave);
+ std::string fullFilePath = WiiTitlePath + fileName;
+ File::CreateFullPath(fullFilePath);
if (_tmpFileHDR.type == 1)
{
_fileSize = Common::swap32(_tmpFileHDR.size);
@@ -299,11 +319,11 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
AES_cbc_encrypt((const unsigned char *)_encryptedData, _data, RoundedFileSize, &m_AES_KEY, IV, AES_DECRYPT);
delete []_encryptedData;
- if (!File::Exists(pathRawSave) || AskYesNoT("%s already exists, overwrite?", pathRawSave))
+ if (!File::Exists(fullFilePath) || AskYesNoT("%s already exists, overwrite?", fullFilePath.c_str()))
{
- INFO_LOG(CONSOLE, "creating file %s", pathRawSave);
+ INFO_LOG(CONSOLE, "creating file %s", fullFilePath.c_str());
- File::IOFile fpRawSaveFile(pathRawSave, "wb");
+ File::IOFile fpRawSaveFile(fullFilePath, "wb");
fpRawSaveFile.WriteBytes(_data, _fileSize);
}
delete []_data;
@@ -330,7 +350,7 @@ void CWiiSaveCrypted::ExportWiiSaveFiles()
tmpFileHDR.magic = Common::swap32(FILE_HDR_MAGIC);
tmpFileHDR.size = Common::swap32(_fileSize);
- tmpFileHDR.Permissions = 0x3C;
+ tmpFileHDR.Permissions = 0x35;
tmpFileHDR.type = File::IsDirectory(FilesList[i]) ? 2 : 1;
SplitPath(FilesList[i], NULL, &__name, &__ext);
@@ -342,8 +362,6 @@ void CWiiSaveCrypted::ExportWiiSaveFiles()
for (size_t j = 0; (j = __name.find(iter->second, j)) != __name.npos; ++j)
{
- /*std::string tmp = __name.substr(0, j) + iter->first +__name.substr(j+iter->second.length(), __name.length());
- __name = tmp;*/
__name.replace(j, iter->second.length(), 1, iter->first);
}
}
@@ -409,16 +427,10 @@ void CWiiSaveCrypted::do_sig()
char name[64];
u8 *data;
u32 data_size;
-//allow customization
- u32 ng_id = Common::swap32(1);
- u32 ng_key_id = Common::swap32(2);
- u8 ng_sig[0x3C] = {0};
- u8 ng_priv[0x1E] = {0};
-//allow customization
sprintf(signer, "Root-CA00000001-MS00000002");
- sprintf(name, "NG%08x", ng_id);
- make_ec_cert(ng_cert, ng_sig, signer, name, ng_priv, ng_key_id);
+ sprintf(name, "NG%08x", Common::swap32(keys.NG_id));
+ make_ec_cert(ng_cert, keys.NG_sig, signer, name, keys.NG_priv, Common::swap32(keys.NG_key_id));
memset(ap_priv, 0, sizeof ap_priv);
@@ -426,12 +438,12 @@ void CWiiSaveCrypted::do_sig()
memset(ap_sig, 81, sizeof ap_sig); // temp
- sprintf(signer, "Root-CA00000001-MS00000002-NG%08x", ng_id);
+ sprintf(signer, "Root-CA00000001-MS00000002-NG%08x", Common::swap32(keys.NG_id));
sprintf(name, "AP%08x%08x", 1, 2);
make_ec_cert(ap_cert, ap_sig, signer, name, ap_priv, 0);
sha1(ap_cert + 0x80, 0x100, hash);
- generate_ecdsa(ap_sig, ap_sig + 30, ng_priv, hash);
+ generate_ecdsa(ap_sig, ap_sig + 30, keys.NG_priv, hash);
make_ec_cert(ap_cert, ap_sig, signer, name, ap_priv, 0);
data_size = Common::swap32(bkhdr.sizeOfFiles) + 0x80;
@@ -446,7 +458,10 @@ void CWiiSaveCrypted::do_sig()
fpData_bin.Seek(0xf0c0, SEEK_SET);
if (!fpData_bin.ReadBytes(data, data_size))
- PanicAlert("read data for sig check");
+ {
+ b_valid = false;
+ return;
+ }
sha1(data, data_size, hash);
sha1(hash, 20, hash);
@@ -460,13 +475,12 @@ void CWiiSaveCrypted::do_sig()
}
generate_ecdsa(sig, sig + 30, ap_priv, hash);
*(u32*)(sig + 60) = Common::swap32(0x2f536969);
+
+ fpData_bin.WriteArray(sig, sizeof(sig));
+ fpData_bin.WriteArray(ng_cert, sizeof(ng_cert));
+ fpData_bin.WriteArray(ap_cert, sizeof(ap_cert));
- if (!fpData_bin.WriteArray(sig, sizeof(sig)))
- PanicAlert("write sig");
- if (!fpData_bin.WriteArray(ng_cert, sizeof(ng_cert)))
- PanicAlert("write NG cert");
- if (!fpData_bin.WriteArray(ap_cert, sizeof(ap_cert)))
- PanicAlert("write AP cert");
+ b_valid = fpData_bin.IsGood();
}
@@ -485,40 +499,40 @@ void CWiiSaveCrypted::make_ec_cert(u8 *cert, u8 *sig, char *signer, char *name,
bool CWiiSaveCrypted::getPaths(bool forExport)
{
- if (_saveGameTitle)
+ if (m_TitleID)
{
- sprintf(pathSavedir, "%stitle/%08x/%08x/data/",
- File::GetUserPath(D_WIIUSER_IDX).c_str(),
- (u32)(_saveGameTitle>>32), (u32)_saveGameTitle);
- sprintf(pathBanner_bin, "%sbanner.bin", pathSavedir);
- sprintf(_saveGameString, "%c%c%c%c",
- (u8)(_saveGameTitle >> 24) & 0xFF, (u8)(_saveGameTitle >> 16) & 0xFF,
- (u8)(_saveGameTitle >> 8) & 0xFF, (u8)_saveGameTitle & 0xFF);
+ WiiTitlePath = Common::GetTitleDataPath(m_TitleID);
+ BannerFilePath = WiiTitlePath + "banner.bin";
}
if (forExport)
{
- if(!File::IsDirectory(pathSavedir))
+ char GameID[5];
+ sprintf(GameID, "%c%c%c%c",
+ (u8)(m_TitleID >> 24) & 0xFF, (u8)(m_TitleID >> 16) & 0xFF,
+ (u8)(m_TitleID >> 8) & 0xFF, (u8)m_TitleID & 0xFF);
+
+ if(!File::IsDirectory(WiiTitlePath))
{
b_valid = false;
- PanicAlertT("No save folder found for title %s", _saveGameString);
+ PanicAlertT("No save folder found for title %s", GameID);
return false;
}
- if(!File::Exists(pathBanner_bin))
+ if(!File::Exists(BannerFilePath))
{
b_valid = false;
- PanicAlertT("No banner file found for title %s", _saveGameString);
+ PanicAlertT("No banner file found for title %s", GameID);
return false;
}
if (strlen(pathData_bin) == 0)
strcpy(pathData_bin, "."); // If no path was passed, use current dir
- sprintf(pathData_bin, "%s/private/wii/title/%s/data.bin", pathData_bin, _saveGameString);
+ sprintf(pathData_bin, "%s/private/wii/title/%s/data.bin", pathData_bin, GameID);
File::CreateFullPath(pathData_bin);
}
else
{
- File::CreateFullPath(pathSavedir);
- if (!AskYesNoT("Warning! it is advised to backup all files in the folder:\n%s\nDo you wish to continue?", pathSavedir))
+ File::CreateFullPath(WiiTitlePath);
+ if (!AskYesNoT("Warning! it is advised to backup all files in the folder:\n%s\nDo you wish to continue?", WiiTitlePath.c_str()))
return false;
}
return true;
diff --git a/Source/Core/DolphinWX/Src/MemoryCards/WiiSaveCrypted.h b/Source/Core/DolphinWX/Src/MemoryCards/WiiSaveCrypted.h
index 1743dee1ee..79066de928 100644
--- a/Source/Core/DolphinWX/Src/MemoryCards/WiiSaveCrypted.h
+++ b/Source/Core/DolphinWX/Src/MemoryCards/WiiSaveCrypted.h
@@ -30,7 +30,7 @@
class CWiiSaveCrypted
{
public:
- CWiiSaveCrypted(const char* FileName, u64 title = 0);
+ CWiiSaveCrypted(const char* FileName, u64 TitleID = 0);
~CWiiSaveCrypted();
void ReadHDR();
void ReadBKHDR();
@@ -50,11 +50,10 @@ private:
u8 SD_IV[0x10];
std::vector<std::string> FilesList;
- char pathData_bin[2048],
- pathSavedir[2048],
- pathBanner_bin[2048], //should always be FULL_WII_USER_DIR "title/%08x/%08x/data/"
- pathRawSave[2048],
- _saveGameString[5];
+ char pathData_bin[2048];
+
+ std::string BannerFilePath,
+ WiiTitlePath;
u8 IV[0x10],
*_encryptedData,
@@ -62,6 +61,14 @@ private:
md5_file[16],
md5_calc[16];
+ struct _keys
+ {
+ u8 NG_priv[0x1E],
+ NG_sig[0x3C],
+ NG_id[4],
+ NG_key_id[4];
+ }keys;
+
u32 _bannerSize,
_numberOfFiles,
_sizeOfFiles,
@@ -69,7 +76,7 @@ private:
_fileSize,
_roundedfileSize;
- u64 _saveGameTitle;
+ u64 m_TitleID;
bool b_valid,
b_tryAgain;