Remove the size limitation on BOSS files

This commit is contained in:
d0k3 2017-05-30 01:58:18 +02:00
parent d8d2901ec1
commit 4d91a86d12
4 changed files with 26 additions and 13 deletions

View File

@ -49,7 +49,7 @@
#endif #endif
// GodMode9 version // GodMode9 version
#define VERSION "1.1.9" #define VERSION "1.2.0"
// Maximum payload size (arbitrary value!) // Maximum payload size (arbitrary value!)
#define SELF_MAX_SIZE (320 * 1024) // 320kB #define SELF_MAX_SIZE (320 * 1024) // 320kB

View File

@ -26,7 +26,6 @@ u32 ValidateBossHeader(BossHeader* header, u32 fsize) {
// base checks // base checks
if ((memcmp(header->magic, boss_magic, sizeof(boss_magic)) != 0) || if ((memcmp(header->magic, boss_magic, sizeof(boss_magic)) != 0) ||
(fsize && (fsize != getbe32(header->filesize))) || (fsize && (fsize != getbe32(header->filesize))) ||
(getbe32(header->filesize) > BOSS_MAX_SIZE) ||
(getbe32(header->filesize) < sizeof(BossHeader)) || (getbe32(header->filesize) < sizeof(BossHeader)) ||
(getbe16(header->unknown0) != 0x0001) || (getbe16(header->unknown0) != 0x0001) ||
(getbe16(header->cnthdr_hash_type) != 0x0002) || (getbe16(header->cnthdr_hash_type) != 0x0002) ||

View File

@ -3,7 +3,6 @@
#include "common.h" #include "common.h"
#define BOSS_MAGIC 0x62, 0x6F, 0x73, 0x73, 0x00, 0x01, 0x00, 0x01 #define BOSS_MAGIC 0x62, 0x6F, 0x73, 0x73, 0x00, 0x01, 0x00, 0x01
#define BOSS_MAX_SIZE 0xF0000 // 960 kB, should be more than enough
#define BOSS_OFFSET_PAYLOAD sizeof(BossHeader) #define BOSS_OFFSET_PAYLOAD sizeof(BossHeader)
#define BOSS_SIZE_PAYLOAD_HEADER (0x1C + 2) #define BOSS_SIZE_PAYLOAD_HEADER (0x1C + 2)

View File

@ -549,26 +549,32 @@ u32 VerifyFirmFile(const char* path) {
u32 VerifyBossFile(const char* path) { u32 VerifyBossFile(const char* path) {
BossHeader* boss = (BossHeader*) TEMP_BUFFER; BossHeader* boss = (BossHeader*) TEMP_BUFFER;
u8* payload_hdr = MAIN_BUFFER;
u8* payload = MAIN_BUFFER + BOSS_SIZE_PAYLOAD_HEADER;
u32 payload_size; u32 payload_size;
bool encrypted = false; bool encrypted = false;
FIL file;
UINT btr;
char pathstr[32 + 1]; char pathstr[32 + 1];
TruncateString(pathstr, path, 32, 8); TruncateString(pathstr, path, 32, 8);
// read file header // read file header
UINT btr;
if ((fvx_qread(path, boss, 0, sizeof(BossHeader), &btr) != FR_OK) || if (fvx_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
return 1;
fvx_lseek(&file, 0);
if ((fvx_read(&file, boss, sizeof(BossHeader), &btr) != FR_OK) ||
(btr != sizeof(BossHeader)) || (ValidateBossHeader(boss, 0) != 0)) { (btr != sizeof(BossHeader)) || (ValidateBossHeader(boss, 0) != 0)) {
ShowPrompt(false, "%s\nError: Not a BOSS file", pathstr); ShowPrompt(false, "%s\nError: Not a BOSS file", pathstr);
fvx_close(&file);
return 1; return 1;
} }
// get / check size // get / check size
payload_size = getbe32(boss->filesize) - sizeof(BossHeader); payload_size = getbe32(boss->filesize) - sizeof(BossHeader);
if ((payload_size + BOSS_SIZE_PAYLOAD_HEADER > MAIN_BUFFER_SIZE) || !payload_size) if (!payload_size) {
fvx_close(&file);
return 1; return 1;
}
// check if encrypted, decrypt if required // check if encrypted, decrypt if required
encrypted = (CheckBossEncrypted(boss) == 0); encrypted = (CheckBossEncrypted(boss) == 0);
@ -576,11 +582,20 @@ u32 VerifyBossFile(const char* path) {
// actual hash calculation & compare // actual hash calculation & compare
u8 hash[32]; u8 hash[32];
memset(MAIN_BUFFER, 0, MAIN_BUFFER_SIZE); sha_init(SHA256_MODE);
GetBossPayloadHashHeader(payload_hdr, boss); GetBossPayloadHashHeader(MAIN_BUFFER, boss);
fvx_qread(path, payload, sizeof(BossHeader), payload_size, &btr); u32 read_bytes = min((MAIN_BUFFER_SIZE - BOSS_SIZE_PAYLOAD_HEADER), payload_size);
if (encrypted) CryptBoss(payload, sizeof(BossHeader), payload_size, boss); fvx_read(&file, MAIN_BUFFER + BOSS_SIZE_PAYLOAD_HEADER, read_bytes, &btr);
sha_quick(hash, MAIN_BUFFER, payload_size + BOSS_SIZE_PAYLOAD_HEADER, SHA256_MODE); if (encrypted) CryptBoss(MAIN_BUFFER + BOSS_SIZE_PAYLOAD_HEADER, sizeof(BossHeader), read_bytes, boss);
sha_update(MAIN_BUFFER, read_bytes + BOSS_SIZE_PAYLOAD_HEADER);
for (u32 i = read_bytes; i < payload_size; i += MAIN_BUFFER_SIZE) {
read_bytes = min(MAIN_BUFFER_SIZE, (payload_size - i));
fvx_read(&file, MAIN_BUFFER, read_bytes, &btr);
if (encrypted) CryptBoss(MAIN_BUFFER, sizeof(BossHeader) + i, read_bytes, boss);
sha_update(MAIN_BUFFER, read_bytes);
}
fvx_close(&file);
sha_get(hash);
if (memcmp(hash, boss->hash_payload, 0x20) != 0) { if (memcmp(hash, boss->hash_payload, 0x20) != 0) {
ShowPrompt(false, "%s\nBOSS payload hash mismatch", pathstr); ShowPrompt(false, "%s\nBOSS payload hash mismatch", pathstr);
return 1; return 1;