mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@777 385bec56-5757-e545-9c3a-d8741f4650f1
245 lines
6.5 KiB
C++
245 lines
6.5 KiB
C++
/*---------------------------------------------------------------------------*
|
|
Project: Horizon
|
|
File: SdReaderWriter.cpp
|
|
|
|
Copyright 2009 Nintendo. All rights reserved.
|
|
|
|
These coded instructions, statements, and computer programs contain
|
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
|
Company Ltd., and are protected by Federal copyright law. They may
|
|
not be disclosed to third parties or copied or duplicated in any form,
|
|
in whole or in part, without the prior written consent of Nintendo.
|
|
|
|
$Rev$
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
#include "SdReaderWriter.h"
|
|
#include "SdMountManager.h"
|
|
#include "CommonLogger.h"
|
|
#include "Aes_define.h"
|
|
|
|
#include <nn/crypto/crypto_AesCmac.h>
|
|
#include <nn/crypto/crypto_SwAesCtrContext.h>
|
|
#include <nn/crypto/crypto_Sha256.h>
|
|
#include <nn/crypto/crypto_SwAesCmac.h>
|
|
|
|
#include <cstdlib>
|
|
|
|
namespace common
|
|
{
|
|
|
|
nn::Result SdReaderWriter::Initialize()
|
|
{
|
|
nn::Result result;
|
|
|
|
// 初期化済みなら何もしない
|
|
if(m_IsInitialized)
|
|
{
|
|
return nn::ResultSuccess();
|
|
}
|
|
|
|
result = SdMountManager::Mount();
|
|
if(result.IsSuccess())
|
|
{
|
|
m_IsInitialized = true;
|
|
return nn::ResultSuccess();
|
|
}
|
|
else
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
nn::Result SdReaderWriter::Finalize()
|
|
{
|
|
nn::Result result;
|
|
result = SdMountManager::Unmount();
|
|
|
|
m_IsInitialized = false;
|
|
return result;
|
|
}
|
|
|
|
nn::Result SdReaderWriter::WriteBufCore(nn::fs::FileStream& file, const wchar_t* path, void* buf, size_t size)
|
|
{
|
|
NN_ASSERT(path != NULL);
|
|
NN_ASSERT(size > 0);
|
|
|
|
nn::Result result = Initialize();
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(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, false);
|
|
if (result.IsSuccess())
|
|
{
|
|
// 何もしない
|
|
}
|
|
else
|
|
{
|
|
NN_LOG("SD TryWrite failed\n");
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
NN_LOG("SD TryInitialize failed\n");
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
nn::Result SdReaderWriter::WriteBuf(nn::fs::FileStream& file, const wchar_t* path, void* buf, size_t size)
|
|
{
|
|
nn::Result result;
|
|
|
|
result = WriteBufCore(file, path, buf, size);
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
result = file.TryFlush();
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
file.Finalize();
|
|
|
|
result = Finalize();
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
return result;
|
|
}
|
|
|
|
nn::Result SdReaderWriter::WriteBufWithCmac(const wchar_t* path, void* buf, size_t size)
|
|
{
|
|
nn::Result result;
|
|
nn::fs::FileStream file;
|
|
|
|
result = WriteBufCore(file, path, buf, size);
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE];
|
|
nn::crypto::CalculateSha256(sha256Hash, buf, size);
|
|
|
|
bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE];
|
|
result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey);
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
s32 writeSize;
|
|
result = file.TryWrite(&writeSize, cmac, sizeof(cmac), false);
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
result = file.TryFlush();
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
file.Finalize();
|
|
|
|
result = Finalize();
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
nn::Result SdReaderWriter::ReadBufCore(nn::fs::FileStream& file, 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();
|
|
}
|
|
|
|
result = file.TryInitialize(path, nn::fs::OPEN_MODE_READ);
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
s32 readSize;
|
|
result = file.TryRead(&readSize, buf, size);
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
// TODO バッファを超えるサイズのファイル読み込み
|
|
*totalSize = readSize;
|
|
|
|
return result;
|
|
}
|
|
|
|
nn::Result SdReaderWriter::ReadBuf(nn::fs::FileStream& file, const wchar_t* path, void* buf, size_t size,
|
|
size_t* totalSize)
|
|
{
|
|
nn::Result result;
|
|
|
|
result = ReadBufCore(file, path, buf, size, totalSize);
|
|
COMMON_LOGGER_RETURN_RESULT_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::fs::FileStream file;
|
|
|
|
NN_ASSERT(size > nn::crypto::AES_CMAC_MAC_SIZE);
|
|
|
|
result = ReadBufCore(file, path, buf, size, totalSize);
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
file.Finalize();
|
|
// ハッシュが付加されていない
|
|
if(*totalSize < nn::crypto::AES_CMAC_MAC_SIZE)
|
|
{
|
|
return nn::fs::ResultVerificationFailed();
|
|
}
|
|
*totalSize -= nn::crypto::AES_CMAC_MAC_SIZE;
|
|
|
|
// CMACの検証を行う
|
|
|
|
bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE];
|
|
nn::crypto::CalculateSha256(sha256Hash, buf, *totalSize);
|
|
|
|
bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE];
|
|
result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey);
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
if(std::memcmp(reinterpret_cast<bit8*>(buf) + *totalSize, cmac, sizeof(cmac)) != 0)
|
|
{
|
|
// 無効なファイル
|
|
char filename[256];
|
|
std::wcstombs(filename, path, sizeof(filename));
|
|
filename[sizeof(filename) - 1] = '\0';
|
|
COMMON_LOGGER("Verification Failed %s\n", filename);
|
|
return nn::fs::ResultVerificationFailed();
|
|
}
|
|
|
|
// CMACを0埋め
|
|
std::memset(reinterpret_cast<bit8*>(buf) + *totalSize, 0, sizeof(cmac));
|
|
|
|
return result;
|
|
}
|
|
|
|
nn::Result SdReaderWriter::CreateDirectory(const wchar_t* path)
|
|
{
|
|
nn::Result result;
|
|
|
|
if(!m_IsInitialized)
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
NN_LOG("Create Directory %ls\n", path);
|
|
result = nn::fs::TryCreateDirectory(path);
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
result = Finalize();
|
|
COMMON_LOGGER_RETURN_RESULT_IF_FAILED(result);
|
|
|
|
return nn::ResultSuccess();
|
|
}
|
|
|
|
}
|