Fix false positives in crypto code hopefully

This commit is contained in:
wheremyfoodat 2023-07-03 17:25:09 +03:00
commit f262cf2836

View file

@ -44,15 +44,20 @@ bool NCCH::loadFromHeader(Crypto::AESEngine &aesEngine, IOFile& file, const FSIn
exheaderInfo.offset = info.offset + 0x200; exheaderInfo.offset = info.offset + 0x200;
exheaderInfo.size = exheaderSize; exheaderInfo.size = exheaderSize;
exheaderInfo.hashRegionSize = 0; exheaderInfo.hashRegionSize = 0;
exheaderInfo.encryptionInfo = std::nullopt;
exeFS.offset = info.offset + u64(*(u32*)&header[0x1A0]) * mediaUnit; exeFS.offset = info.offset + u64(*(u32*)&header[0x1A0]) * mediaUnit;
exeFS.size = u64(*(u32*)&header[0x1A4]) * mediaUnit; exeFS.size = u64(*(u32*)&header[0x1A4]) * mediaUnit;
exeFS.hashRegionSize = u64(*(u32*)&header[0x1A8]) * mediaUnit; exeFS.hashRegionSize = u64(*(u32*)&header[0x1A8]) * mediaUnit;
exeFS.encryptionInfo = std::nullopt;
romFS.offset = info.offset + u64(*(u32*)&header[0x1B0]) * mediaUnit; romFS.offset = info.offset + u64(*(u32*)&header[0x1B0]) * mediaUnit;
romFS.size = u64(*(u32*)&header[0x1B4]) * mediaUnit; romFS.size = u64(*(u32*)&header[0x1B4]) * mediaUnit;
romFS.hashRegionSize = u64(*(u32*)&header[0x1B8]) * mediaUnit; romFS.hashRegionSize = u64(*(u32*)&header[0x1B8]) * mediaUnit;
romFS.encryptionInfo = std::nullopt;
// Shows whether we got the primary and secondary keys correctly
bool gotCryptoKeys = true;
if (encrypted) { if (encrypted) {
Crypto::AESKey primaryKeyY; Crypto::AESKey primaryKeyY;
Crypto::AESKey secondaryKeyY; Crypto::AESKey secondaryKeyY;
@ -61,26 +66,17 @@ bool NCCH::loadFromHeader(Crypto::AESEngine &aesEngine, IOFile& file, const FSIn
if (!seedCrypto) { if (!seedCrypto) {
secondaryKeyY = primaryKeyY; secondaryKeyY = primaryKeyY;
} else { } else {
Helpers::panic("Seed crypto is not supported"); Helpers::warn("Seed crypto is not supported");
return false; gotCryptoKeys = false;
} }
auto primaryResult = getPrimaryKey(aesEngine, primaryKeyY); auto primaryResult = getPrimaryKey(aesEngine, primaryKeyY);
if (!primaryResult.first) {
Helpers::panic("getPrimaryKey failed!");
return false;
}
Crypto::AESKey primaryKey = primaryResult.second;
auto secondaryResult = getSecondaryKey(aesEngine, secondaryKeyY); auto secondaryResult = getSecondaryKey(aesEngine, secondaryKeyY);
if (!secondaryResult.first) { if (!primaryResult.first || !secondaryResult.first) {
Helpers::panic("getSecondaryKey failed!"); gotCryptoKeys = false;
return false; } else {
} Crypto::AESKey primaryKey = primaryResult.second;
Crypto::AESKey secondaryKey = secondaryResult.second; Crypto::AESKey secondaryKey = secondaryResult.second;
EncryptionInfo encryptionInfoTmp; EncryptionInfo encryptionInfoTmp;
@ -100,6 +96,7 @@ bool NCCH::loadFromHeader(Crypto::AESEngine &aesEngine, IOFile& file, const FSIn
encryptionInfoTmp.initialCounter[8] = 3; encryptionInfoTmp.initialCounter[8] = 3;
romFS.encryptionInfo = encryptionInfoTmp; romFS.encryptionInfo = encryptionInfoTmp;
} }
}
if (exheaderSize != 0) { if (exheaderSize != 0) {
std::unique_ptr<u8[]> exheader(new u8[exheaderSize]); std::unique_ptr<u8[]> exheader(new u8[exheaderSize]);
@ -117,7 +114,13 @@ bool NCCH::loadFromHeader(Crypto::AESEngine &aesEngine, IOFile& file, const FSIn
if (u32(programID) == u32(jumpID) && encrypted) { if (u32(programID) == u32(jumpID) && encrypted) {
printf("NCSD is supposedly ecrypted but not actually encrypted\n"); printf("NCSD is supposedly ecrypted but not actually encrypted\n");
encrypted = false; encrypted = false;
// Cartridge is not actually encrypted, set all of our encryption info structures to nullopt
exheaderInfo.encryptionInfo = std::nullopt;
romFS.encryptionInfo = std::nullopt;
exeFS.encryptionInfo = std::nullopt;
} }
// If it's truly encrypted, we need to read section again. // If it's truly encrypted, we need to read section again.
if (encrypted) { if (encrypted) {
if (!aesEngine.haveKeys()) { if (!aesEngine.haveKeys()) {
@ -128,6 +131,11 @@ bool NCCH::loadFromHeader(Crypto::AESEngine &aesEngine, IOFile& file, const FSIn
return false; return false;
} }
if (!gotCryptoKeys) {
Helpers::panic("ROM is encrypted but it seems we couldn't get either the primary or the secondary key");
return false;
}
auto [success, bytes] = readFromFile(file, exheaderInfo, &exheader[0], 0, exheaderSize); auto [success, bytes] = readFromFile(file, exheaderInfo, &exheader[0], 0, exheaderSize);
if (!success || bytes != exheaderSize) { if (!success || bytes != exheaderSize) {
printf("Failed to read Extended NCCH header\n"); printf("Failed to read Extended NCCH header\n");