diff --git a/branches/work/SD_AesCmac/ConsoleBackup/Exporter.cpp b/branches/work/SD_AesCmac/ConsoleBackup/Exporter.cpp index 69778bd..f857ebe 100644 --- a/branches/work/SD_AesCmac/ConsoleBackup/Exporter.cpp +++ b/branches/work/SD_AesCmac/ConsoleBackup/Exporter.cpp @@ -154,7 +154,7 @@ void WriteRegionData() nn::cfg::CTR::CfgRegionCode region; region = nn::cfg::CTR::GetRegion(); - s_SdWriter.WriteBuf(common::REGION_DATA_PATHNAME, ®ion, sizeof(nn::cfg::CTR::CfgRegionCode)); + s_SdWriter.WriteBufWithCmac(common::REGION_DATA_PATHNAME, ®ion, sizeof(nn::cfg::CTR::CfgRegionCode)); } void WriteCountryLanguageData() @@ -172,7 +172,7 @@ void WriteCountryLanguageData() // 言語設定 s_CountryLanguage.language = nn::cfg::CTR::GetLanguage(); - s_SdWriter.WriteBuf(common::COUNTRY_SETTING_PATHNAME, &s_CountryLanguage, sizeof(s_CountryLanguage)); + s_SdWriter.WriteBufWithCmac(common::COUNTRY_SETTING_PATHNAME, &s_CountryLanguage, sizeof(s_CountryLanguage)); } } @@ -198,7 +198,7 @@ void WriteNorData() result = nn::cfg::nor::CTR::ReadNtrWifiSetting(0, s_NtrNorData.NtrWiFiSetting, common::NTR_WIFI_SETTING_SIZE); COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); - s_SdWriter.WriteBuf(common::NOR_PATHNAME, &s_NtrNorData, sizeof(common::NtrNorData)); + s_SdWriter.WriteBufWithCmac(common::NOR_PATHNAME, &s_NtrNorData, sizeof(common::NtrNorData)); } void WriteSerialNumber() @@ -209,7 +209,7 @@ void WriteSerialNumber() size_t size; GetSerialNumber(&serial, &size); - s_SdWriter.WriteBuf(common::SERIAL_PATHNAME, serial, size); + s_SdWriter.WriteBufWithCmac(common::SERIAL_PATHNAME, serial, size); } void WriteIvs() @@ -239,7 +239,7 @@ void WriteIvs() swAesCtrContest.Initialize(iv, common::key, sizeof(common::key)); swAesCtrContest.Encrypt(enc, ivs, size); - s_SdWriter.WriteBuf(common::IVS_PATHNAME, enc, size); + s_SdWriter.WriteBufWithCmac(common::IVS_PATHNAME, enc, size); common::HeapManager::GetHeap()->Free(enc); } @@ -385,7 +385,7 @@ void WriteMcuRtcData() NN_LOG("RTC = 20%02d/%02d/%02d %02d:%02d:%02d\n", rtc.m_Year, rtc.m_Month, rtc.m_Day, rtc.m_Hour, rtc.m_Minute, rtc.m_Second); COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); - s_SdWriter.WriteBuf(common::MCU_RTC_PATHNAME, &rtc, sizeof(rtc)); + s_SdWriter.WriteBufWithCmac(common::MCU_RTC_PATHNAME, &rtc, sizeof(rtc)); } else { @@ -474,7 +474,7 @@ void WriteVersionData() common::VerDef versionData; GetVersionData(&versionData); - s_SdWriter.WriteBuf(common::VERSION_DATA_PATHNAME, &versionData, sizeof(common::VerDef)); + s_SdWriter.WriteBufWithCmac(common::VERSION_DATA_PATHNAME, &versionData, sizeof(common::VerDef)); } void WritePlayHistory() diff --git a/branches/work/SD_AesCmac/ConsoleRestore/Importer.cpp b/branches/work/SD_AesCmac/ConsoleRestore/Importer.cpp index 0e81600..d0bffaa 100644 --- a/branches/work/SD_AesCmac/ConsoleRestore/Importer.cpp +++ b/branches/work/SD_AesCmac/ConsoleRestore/Importer.cpp @@ -206,6 +206,8 @@ bool CreateEmptyFile(const wchar_t* path) u8* ReadSerialNumber() { + nn::Result result; + if(s_ReadSerialNumber) { return s_SerialNo; @@ -213,11 +215,20 @@ u8* ReadSerialNumber() COMMON_LOGGER("Read Serial Number in SD.\n"); - size_t size; - + size_t readSize; common::SdReaderWriter sdReader; - sdReader.ReadBuf(common::SERIAL_PATHNAME, s_SerialNo, nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN, &size); - s_ReadSerialNumber = true; + size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize(); + void* buf = common::HeapManager::GetHeap()->Allocate(bufSize); + if(buf != NULL) + { + result = sdReader.ReadBufWithCmac(common::SERIAL_PATHNAME, buf, bufSize, &readSize); + if(result.IsSuccess()) + { + std::memcpy(s_SerialNo, buf, sizeof(s_SerialNo)); + s_ReadSerialNumber = true; + } + common::HeapManager::GetHeap()->Free(buf); + } return s_SerialNo; } @@ -246,7 +257,7 @@ bool EqualsIVSFileandIVS() { common::SdReaderWriter sdReader; - result = sdReader.ReadBuf(common::IVS_PATHNAME, enc, bufSize, &readSize); + result = sdReader.ReadBufWithCmac(common::IVS_PATHNAME, enc, bufSize, &readSize); if(result.IsSuccess()) { void *dec = common::HeapManager::GetHeap()->Allocate(readSize); @@ -305,20 +316,33 @@ bool EqualsRegionDataandRegion() nn::cfg::CTR::CfgRegionCode sdRegion; common::SdReaderWriter sdReader; - size_t dummy; + size_t readSize; + size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize(); + void* buf = common::HeapManager::GetHeap()->Allocate(bufSize); + if (buf != NULL) + { + result = sdReader.ReadBufWithCmac(common::REGION_DATA_PATHNAME, buf, bufSize, &readSize); + if (result.IsSuccess()) + { + std::memcpy(&sdRegion, buf, sizeof(sdRegion)); + s_CheckedEqualsRegionDataandRegion = true; + if (result.IsSuccess()) + { + retval = (region == sdRegion); + } + else + { + retval = false; + } + } + else + { + retval = false; + } + common::HeapManager::GetHeap()->Free(buf); + } - result = sdReader.ReadBuf(common::REGION_DATA_PATHNAME, &sdRegion, sizeof(sdRegion), &dummy); - s_CheckedEqualsRegionDataandRegion = true; - if(result.IsSuccess()) - { - retval = (region == sdRegion); - return retval; - } - else - { - retval = false; - return retval; - } + return retval; } void SetCountry(nn::cfg::CTR::CfgCountryCode countryCode) @@ -372,7 +396,7 @@ void ImportCountryLanguageData() common::SdReaderWriter sdReader; size_t readSize; - result = sdReader.ReadBuf(common::COUNTRY_SETTING_PATHNAME, buf, bufSize, &readSize); + result = sdReader.ReadBufWithCmac(common::COUNTRY_SETTING_PATHNAME, buf, bufSize, &readSize); if (result.IsSuccess()) { // SDから読み出し成功 @@ -468,7 +492,7 @@ void ImportMcuRtc() common::SdReaderWriter sdReader; size_t readSize; - result = sdReader.ReadBuf(common::MCU_RTC_PATHNAME, buf, bufSize, &readSize); + result = sdReader.ReadBufWithCmac(common::MCU_RTC_PATHNAME, buf, bufSize, &readSize); if (result.IsSuccess()) { // mcuを使ってセットする @@ -590,7 +614,7 @@ void ImportIvs() common::SdReaderWriter sdReader; size_t readSize; - result = sdReader.ReadBuf(common::IVS_PATHNAME, enc, bufSize, &readSize); + result = sdReader.ReadBufWithCmac(common::IVS_PATHNAME, enc, bufSize, &readSize); if(result.IsSuccess()) { // SDから読み出し成功 @@ -715,7 +739,7 @@ void ImportNorData() common::SdReaderWriter sdReader; size_t readSize; - result = sdReader.ReadBuf(common::NOR_PATHNAME, buf, bufSize, &readSize); + result = sdReader.ReadBufWithCmac(common::NOR_PATHNAME, buf, bufSize, &readSize); if(result.IsSuccess()) { // cfgを使ってセットする @@ -763,7 +787,7 @@ void ReadVersionData() common::SdReaderWriter sdReader; size_t readSize; - result = sdReader.ReadBuf(common::VERSION_DATA_PATHNAME, buf, bufSize, &readSize); + result = sdReader.ReadBufWithCmac(common::VERSION_DATA_PATHNAME, buf, bufSize, &readSize); if(result.IsSuccess()) { // バージョン情報を保持する @@ -1379,7 +1403,7 @@ void ExportTouchPanelCfgData() COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); if (result.IsSuccess()) { - result = sdWriter.WriteBuf(common::TOUCH_PANEL_CALIBRATION_PATHNAME, &touchPanelCfgData, sizeof(touchPanelCfgData)); + result = sdWriter.WriteBufWithCmac(common::TOUCH_PANEL_CALIBRATION_PATHNAME, &touchPanelCfgData, sizeof(touchPanelCfgData)); COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); } @@ -1404,7 +1428,7 @@ bool ImportTouchPanelCfgData(nn::cfg::CTR::detail::TouchPanelCfgData* data) common::SdReaderWriter sdReader; size_t readSize; - result = sdReader.ReadBuf(common::TOUCH_PANEL_CALIBRATION_PATHNAME, buf, bufSize, &readSize); + result = sdReader.ReadBufWithCmac(common::TOUCH_PANEL_CALIBRATION_PATHNAME, buf, bufSize, &readSize); if(result.IsSuccess()) { // SDから読み出し成功 diff --git a/branches/work/SD_AesCmac/common/Aes_define.h b/branches/work/SD_AesCmac/common/Aes_define.h index 34436ec..e79fe3e 100644 --- a/branches/work/SD_AesCmac/common/Aes_define.h +++ b/branches/work/SD_AesCmac/common/Aes_define.h @@ -16,13 +16,21 @@ #ifndef AES_DEFINE_H_ #define AES_DEFINE_H_ +#include + namespace common { - bit8 key[AES_KEY_SIZE] = + const bit8 key[AES_KEY_SIZE] = { 0x81, 0x35, 0xc6, 0x54, 0x19, 0x1a, 0x47, 0x2a, 0x6b, 0x78, 0xbe, 0x25, 0x90, 0xf6, 0xee, 0x74 }; + + const bit8 cmacKey[AES_KEY_SIZE] = + { + 0x87, 0xdd, 0xc6, 0xd6, 0xf2, 0xe0, 0x2c, 0xa6, + 0x04, 0x21, 0x9c, 0x5e, 0x33, 0x8c, 0x3d, 0xaa + }; } #endif /* AES_DEFINE_H_ */ diff --git a/branches/work/SD_AesCmac/common/PlayHistoryManager.cpp b/branches/work/SD_AesCmac/common/PlayHistoryManager.cpp index 32c8f7e..bb8607e 100644 --- a/branches/work/SD_AesCmac/common/PlayHistoryManager.cpp +++ b/branches/work/SD_AesCmac/common/PlayHistoryManager.cpp @@ -52,7 +52,7 @@ void PlayHistoryManager::Export() } // SDに書き込む - result = sd.WriteBuf(common::PLAYHISTORY_COUNT_PATHNAME, reinterpret_cast(&historyNum), + result = sd.WriteBufWithCmac(common::PLAYHISTORY_COUNT_PATHNAME, reinterpret_cast(&historyNum), sizeof(historyNum)); COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); @@ -69,7 +69,7 @@ void PlayHistoryManager::Export() nn::pl::CTR::GetPlayHistory(pEvent, 0, historyNum); // SDに書き込む - result = sd.WriteBuf(common::PLAYHISTORY_PATHNAME, reinterpret_cast(pEvent), + result = sd.WriteBufWithCmac(common::PLAYHISTORY_PATHNAME, reinterpret_cast(pEvent), sizeof(nn::pl::CTR::PlayEvent) * historyNum); COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); @@ -89,11 +89,12 @@ void PlayHistoryManager::GetPlayHistoryNums(size_t* nums) common::SdReaderWriter sdReader; size_t readSize; - result = sdReader.ReadBuf(common::PLAYHISTORY_COUNT_PATHNAME, buf, bufSize, &readSize); + result = sdReader.ReadBufWithCmac(common::PLAYHISTORY_COUNT_PATHNAME, buf, bufSize, &readSize); if (result.IsSuccess()) { *nums = *reinterpret_cast (buf); } + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); } HeapManager::GetHeap()->Free(buf); } @@ -124,7 +125,7 @@ void PlayHistoryManager::Import() common::SdReaderWriter sdReader; size_t readSize; - result = sdReader.ReadBuf(common::PLAYHISTORY_PATHNAME, buf, bufSize, &readSize); + result = sdReader.ReadBufWithCmac(common::PLAYHISTORY_PATHNAME, buf, bufSize, &readSize); if(result.IsSuccess()) { nn::pl::CTR::PlayEvent* pEvent = reinterpret_cast(buf); diff --git a/branches/work/SD_AesCmac/common/SdReaderWriter.cpp b/branches/work/SD_AesCmac/common/SdReaderWriter.cpp index 8164695..60282be 100644 --- a/branches/work/SD_AesCmac/common/SdReaderWriter.cpp +++ b/branches/work/SD_AesCmac/common/SdReaderWriter.cpp @@ -16,10 +16,30 @@ #include "SdReaderWriter.h" #include "SdMountManager.h" #include "CommonLogger.h" +#include "Aes_define.h" + +#include +#include +#include namespace common { +bool Compare(const bit8* p0, const bit8* p1, size_t size) +{ + s32 i; + bool result = true; + for (i = 0; i < size; ++i) + { + if (*(p0 + i) != *(p1 + i)) + { + result = false; + } + } + return result; +} // Compare + + nn::Result SdReaderWriter::Initialize() { nn::Result result; @@ -52,28 +72,23 @@ nn::Result SdReaderWriter::Finalize() return result; } -nn::Result SdReaderWriter::WriteBuf(const wchar_t* path, void* buf, size_t size) +nn::Result SdReaderWriter::WriteBufCore(const wchar_t* path, void* buf, size_t size) { NN_ASSERT(path != NULL); NN_ASSERT(size > 0); - nn::Result result; - result = Initialize(); + nn::Result result = Initialize(); COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); result = file.TryInitialize(path, nn::fs::OPEN_MODE_WRITE | nn::fs::OPEN_MODE_CREATE); + if (result.IsSuccess()) { s32 writeSize; - result = file.TryWrite(&writeSize, buf, size, true); + result = file.TryWrite(&writeSize, buf, size, false); if (result.IsSuccess()) { - result = file.TryFlush(); - if (result.IsFailure()) - { - NN_LOG("SD TryFlush failed\n"); - COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); - } + // 何もしない } else { @@ -87,6 +102,18 @@ nn::Result SdReaderWriter::WriteBuf(const wchar_t* path, void* buf, size_t size) COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); } + return result; +} + +nn::Result SdReaderWriter::WriteBuf(const wchar_t* path, void* buf, size_t size) +{ + nn::Result result; + + result = WriteBufCore(path, buf, size); + NN_UTIL_RETURN_IF_FAILED(result); + + result = file.TryFlush(); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); file.Finalize(); result = Finalize(); @@ -95,12 +122,44 @@ nn::Result SdReaderWriter::WriteBuf(const wchar_t* path, void* buf, size_t size) return result; } -nn::Result SdReaderWriter::ReadBuf(const wchar_t* path, void* buf, size_t size, size_t* totalSize) +nn::Result SdReaderWriter::WriteBufWithCmac(const wchar_t* path, void* buf, size_t size) +{ + nn::Result result; + + result = WriteBufCore(path, buf, size); + NN_UTIL_RETURN_IF_FAILED(result); + + nn::crypto::Initialize(); + bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE]; + nn::crypto::CalculateSha256(sha256Hash, buf, size); + + bit8 cmac[nn::crypto::Sha256Context::HASH_SIZE]; + result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + + s32 writeSize; + result = file.TryWrite(&writeSize, cmac, sizeof(cmac), false); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + + result = file.TryFlush(); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + + file.Finalize(); + + result = Finalize(); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + + return result; + +} + +nn::Result SdReaderWriter::ReadBufCore(const wchar_t* path, void* buf, size_t size, size_t* totalSize) { NN_ASSERT(path != NULL); NN_ASSERT(size > 0); nn::Result result; + if(!m_IsInitialized) { Initialize(); @@ -128,10 +187,51 @@ nn::Result SdReaderWriter::ReadBuf(const wchar_t* path, void* buf, size_t size, COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); } + return result; +} + +nn::Result SdReaderWriter::ReadBuf(const wchar_t* path, void* buf, size_t size, size_t* totalSize) +{ + nn::Result result; + + result = ReadBufCore(path, buf, size, totalSize); + NN_UTIL_RETURN_IF_FAILED(result); + file.Finalize(); return result; } +nn::Result SdReaderWriter::ReadBufWithCmac(const wchar_t* path, void* buf, size_t size, size_t* totalSize) +{ + nn::Result result; + + NN_ASSERT(size > nn::crypto::Sha256Context::HASH_SIZE); + + result = ReadBufCore(path, buf, size, totalSize); + NN_UTIL_RETURN_IF_FAILED(result); + + file.Finalize(); + + // CMACの検証を行う + nn::crypto::Initialize(); + bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE]; + nn::crypto::CalculateSha256(sha256Hash, buf, size - sizeof(sha256Hash)); + + bit8 cmac[nn::crypto::Sha256Context::HASH_SIZE]; + result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + + if(!Compare(reinterpret_cast(buf) + size - sizeof(sha256Hash), cmac, sizeof(cmac))) + { + // 無効なファイル + COMMON_LOGGER("Verification Failed\n"); + return nn::fs::ResultVerificationFailed(); + } + + *totalSize -= nn::crypto::Sha256Context::HASH_SIZE; + return result; +} + void SdReaderWriter::CreateDirectory(const wchar_t* path) { nn::Result result; diff --git a/branches/work/SD_AesCmac/common/SdReaderWriter.h b/branches/work/SD_AesCmac/common/SdReaderWriter.h index dbb2772..c3d2f63 100644 --- a/branches/work/SD_AesCmac/common/SdReaderWriter.h +++ b/branches/work/SD_AesCmac/common/SdReaderWriter.h @@ -34,6 +34,12 @@ public : //! @param[in] size 入力データのサイズ nn::Result WriteBuf(const wchar_t* path, void* buf, size_t size); + //! @brief 渡されたバッファからsizeバイト指定されたパス名で書きこみます。CMACが付加されます。 + //! @param[in] path sdmc:で始まる出力パス名。予めディレクトリを作っておく必要があります。 + //! @param[in] buf 入力データへのポインタ + //! @param[in] size 入力データのサイズ + nn::Result WriteBufWithCmac(const wchar_t* path, void* buf, size_t size); + //! @brief 渡されたバッファへサイズ分指定されたパス名から読み込みます //! @param[in] path sdmc:で始まる入力パス名 //! @param[in] buf 出力バッファへのポインタ @@ -41,11 +47,21 @@ public : //! @param[out] totalSize 読み込んだデータのサイズ nn::Result ReadBuf(const wchar_t* path, void* buf, size_t size, size_t* totalSize); + //! @brief 渡されたバッファへ(size - CMAC)バイト指定されたパス名から読み込みます + //! @param[in] path sdmc:で始まるCMAC付きの入力パス名 + //! @param[in] buf 出力バッファへのポインタ + //! @param[in] size バッファサイズ + //! @param[out] totalSize 読み込んだデータのサイズ + nn::Result ReadBufWithCmac(const wchar_t* path, void* buf, size_t size, size_t* totalSize); //! @brief 渡されたディレクトリ名のディレクトリを作成します void CreateDirectory(const wchar_t* path); private: + nn::Result WriteBufCore(const wchar_t*path, void* buf, size_t size); + + nn::Result ReadBufCore(const wchar_t* path, void* buf, size_t size, size_t* totalSize); + //! @brief 初期化します。 nn::Result Initialize();