void CWiiSaveCrypted::ReadHDR() { File::IOFile fpData_bin(pathData_bin, "rb"); if (!fpData_bin) { PanicAlertT("Cannot open %s", pathData_bin); b_valid = false; return; } if (!fpData_bin.ReadBytes(&_encryptedHeader, HEADER_SZ)) { PanicAlertT("Failed to read header"); b_valid = false; return; } fpData_bin.Close(); AES_cbc_encrypt((const u8*)&_encryptedHeader, (u8*)&_header, HEADER_SZ, &m_AES_KEY, SD_IV, AES_DECRYPT); _bannerSize = Common::swap32(_header.hdr.BannerSize); if ((_bannerSize < FULL_BNR_MIN) || (_bannerSize > FULL_BNR_MAX) || (((_bannerSize - BNR_SZ) % ICON_SZ) != 0)) { PanicAlertT("Not a Wii save or read failure for file header size %x", _bannerSize); b_valid = false; return; } m_TitleID = Common::swap64(_header.hdr.SaveGameTitle); memcpy(md5_file, _header.hdr.Md5, 0x10); memcpy(_header.hdr.Md5, MD5_BLANKER, 0x10); md5((u8*)&_header, HEADER_SZ, md5_calc); if (memcmp(md5_file, md5_calc, 0x10)) { PanicAlertT("MD5 mismatch\n %016llx%016llx != %016llx%016llx", Common::swap64(md5_file),Common::swap64(md5_file+8), Common::swap64(md5_calc), Common::swap64(md5_calc+8)); b_valid= false; } if (!getPaths()) { b_valid = false; return; } if (!File::Exists(BannerFilePath) || AskYesNoT("%s already exists, overwrite?", BannerFilePath.c_str())) { INFO_LOG(CONSOLE, "Creating file %s", BannerFilePath.c_str()); File::IOFile fpBanner_bin(BannerFilePath, "wb"); fpBanner_bin.WriteBytes(_header.BNR, _bannerSize); } }
void CWiiSaveCrypted::WriteHDR() { if (!b_valid) return; memset(&_header, 0, HEADER_SZ); std::string BannerFilePath = WiiTitlePath + "banner.bin"; u32 bannerSize = File::GetSize(BannerFilePath); _header.hdr.BannerSize = Common::swap32(bannerSize); _header.hdr.SaveGameTitle = Common::swap64(m_TitleID); memcpy(_header.hdr.Md5, MD5_BLANKER, 0x10); _header.hdr.Permissions = 0x3C; File::IOFile fpBanner_bin(BannerFilePath, "rb"); if (!fpBanner_bin.ReadBytes(_header.BNR, bannerSize)) { PanicAlertT("Failed to read banner.bin"); b_valid = false; return; } // remove nocopy flag _header.BNR[7] &= ~1; u8 md5_calc[16]; md5((u8*)&_header, HEADER_SZ, md5_calc); memcpy(_header.hdr.Md5, md5_calc, 0x10); aes_crypt_cbc(&m_AES_ctx, AES_ENCRYPT, HEADER_SZ, SD_IV, (const u8*)&_header, (u8*)&_encryptedHeader); File::IOFile fpData_bin(encryptedSavePath, "wb"); if (!fpData_bin.WriteBytes(&_encryptedHeader, HEADER_SZ)) { PanicAlertT("Failed to write header for %s", encryptedSavePath.c_str()); b_valid = false; } }