[GC] Support Tencent XCI validation. Improved formatting.

This commit is contained in:
Jack 2020-05-17 12:30:14 +08:00
parent 449a825ee6
commit 395b1b662f
2 changed files with 26 additions and 10 deletions

View file

@ -198,7 +198,7 @@ void GameCardProcess::displayHeader()
std::cout << " Wait1TimeWrite: 0x" << std::hex << mHdr.getWait1TimeWrite() << std::endl; std::cout << " Wait1TimeWrite: 0x" << std::hex << mHdr.getWait1TimeWrite() << std::endl;
std::cout << " Wait2TimeWrite: 0x" << std::hex << mHdr.getWait2TimeWrite() << std::endl; std::cout << " Wait2TimeWrite: 0x" << std::hex << mHdr.getWait2TimeWrite() << std::endl;
std::cout << " FwMode: 0x" << std::hex << mHdr.getFwMode() << std::endl; std::cout << " FwMode: 0x" << std::hex << mHdr.getFwMode() << std::endl;
std::cout << " CompatibilityType: " << nn::hac::GameCardUtil::getCompatibilityTypeAsString((nn::hac::gc::CompatibilityType)mHdr.getCompatibilityType()) << "(" << std::dec << mHdr.getCompatibilityType() << ")" << std::endl; std::cout << " CompatibilityType: " << nn::hac::GameCardUtil::getCompatibilityTypeAsString((nn::hac::gc::CompatibilityType)mHdr.getCompatibilityType()) << " (" << std::dec << (uint32_t) mHdr.getCompatibilityType() << ")" << std::endl;
std::cout << " Update Partition Info:" << std::endl; std::cout << " Update Partition Info:" << std::endl;
#define _SPLIT_VER(ver) std::dec << ((ver>>26) & 0x3f) << "." << ((ver>>20) & 0x3f) << "." << ((ver>>16) & 0xf) << "." << (ver & 0xffff) #define _SPLIT_VER(ver) std::dec << ((ver>>26) & 0x3f) << "." << ((ver>>20) & 0x3f) << "." << ((ver>>16) & 0xf) << "." << (ver & 0xffff)
std::cout << " CUP Version: v" << std::dec << mHdr.getUppVersion() << " (" << _SPLIT_VER(mHdr.getUppVersion()) << ")" << std::endl; std::cout << " CUP Version: v" << std::dec << mHdr.getUppVersion() << " (" << _SPLIT_VER(mHdr.getUppVersion()) << ")" << std::endl;
@ -208,16 +208,31 @@ void GameCardProcess::displayHeader()
} }
} }
bool GameCardProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash) bool GameCardProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash, bool use_salt, byte_t salt)
{ {
fnd::Vec<byte_t> scratch; fnd::Vec<byte_t> scratch;
fnd::sha::sSha256Hash calc_hash; fnd::sha::sSha256Hash calc_hash;
if (use_salt)
{
scratch.alloc(len + 1);
scratch.data()[len] = salt;
}
else
{
scratch.alloc(len); scratch.alloc(len);
(*mFile)->read(scratch.data(), offset, scratch.size()); }
(*mFile)->read(scratch.data(), offset, len);
fnd::sha::Sha256(scratch.data(), scratch.size(), calc_hash.bytes); fnd::sha::Sha256(scratch.data(), scratch.size(), calc_hash.bytes);
return calc_hash.compare(test_hash); return calc_hash.compare(test_hash);
} }
bool GameCardProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash)
{
return validateRegionOfFile(offset, len, test_hash, false, 0);
}
void GameCardProcess::validateXciSignature() void GameCardProcess::validateXciSignature()
{ {
fnd::rsa::sRsa2048Key header_sign_key; fnd::rsa::sRsa2048Key header_sign_key;
@ -231,7 +246,7 @@ void GameCardProcess::validateXciSignature()
void GameCardProcess::processRootPfs() void GameCardProcess::processRootPfs()
{ {
if (mVerify && validateRegionOfFile(mHdr.getPartitionFsAddress(), mHdr.getPartitionFsSize(), mHdr.getPartitionFsHash().bytes) == false) if (mVerify && validateRegionOfFile(mHdr.getPartitionFsAddress(), mHdr.getPartitionFsSize(), mHdr.getPartitionFsHash().bytes, mHdr.getCompatibilityType() != nn::hac::gc::COMPAT_GLOBAL, mHdr.getCompatibilityType()) == false)
{ {
std::cout << "[WARNING] GameCard Root HFS0: FAIL (bad hash)" << std::endl; std::cout << "[WARNING] GameCard Root HFS0: FAIL (bad hash)" << std::endl;
} }

View file

@ -69,6 +69,7 @@ private:
void importHeader(); void importHeader();
void displayHeader(); void displayHeader();
bool validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash, bool use_salt, byte_t salt);
bool validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash); bool validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash);
void validateXciSignature(); void validateXciSignature();
void processRootPfs(); void processRootPfs();