From add71a74821021e20eeeffc00ec1030224526378 Mon Sep 17 00:00:00 2001 From: Aetias Date: Wed, 18 Oct 2023 23:10:24 +0200 Subject: [PATCH] Load encryption key and CRC encrypted secure area --- tools/rom/build.c | 58 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/tools/rom/build.c b/tools/rom/build.c index b895a6d6..363d244a 100644 --- a/tools/rom/build.c +++ b/tools/rom/build.c @@ -104,17 +104,21 @@ void BlowfishApplyCode(uint32_t code[3]) { } } -bool BlowfishInit(const char *arm7bios, const Header *pHeader, size_t level, size_t modulo) { - FILE *fp = fopen(arm7bios, "rb"); - if (fp == NULL) FATAL("Failed to open ARM7 BIOS '%s'\n", arm7bios); - if (fread(&blowfish, sizeof(blowfish), 1, fp) != 1) FATAL("Failed to read encrypion key\n"); - fclose(fp); +bool BlowfishInit(const uint8_t *encKey, const Header *pHeader, size_t level) { + memcpy(&blowfish, encKey, sizeof(blowfish)); uint32_t code[3]; memcpy(&code[0], pHeader->gamecode, sizeof(code[0])); code[1] = code[0] << 1; code[2] = code[0] >> 1; BlowfishApplyCode(code); + if (level >= 2) BlowfishApplyCode(code); + if (level >= 3) { + code[1] <<= 1; + code[2] >>= 1; + BlowfishApplyCode(code); + } + return true; } void InitHeader(Header *pHeader, const BuildInfo *info) { @@ -508,17 +512,27 @@ bool RewriteFat(FILE *fpRom, size_t fatStart, const FatEntry *entries, size_t nu fseek(fpRom, 0, SEEK_END); } -bool FinalizeHeader(FILE *fpRom, Header *pHeader) { +bool FinalizeHeader(FILE *fpRom, Header *pHeader, const char *arm7bios, uint32_t *secureArea) { Header header; memcpy(&header, pHeader, sizeof(header)); - FILE *fp = fopen(ARM9_PROGRAM_FILE, "rb"); - if (fp == NULL) FATAL("Failed to open ARM9 program '" ARM9_PROGRAM_FILE "'\n"); - uint8_t secureArea[0x4000]; - if (fread(secureArea, sizeof(secureArea), 1, fp) != 1) FATAL("Failed to read secure area\n"); - fclose(fp); + if (arm7bios != NULL) { + FILE *fp = fopen(arm7bios, "rb"); + if (fp == NULL) FATAL("Failed to open ARM7 BIOS '%s'\n", arm7bios); + fseek(fp, 0x30, SEEK_SET); + uint8_t encKey[sizeof(Blowfish)]; + if (fread(&encKey, sizeof(encKey), 1, fp) != 1) FATAL("Failed to read encrypion key\n"); + fclose(fp); + + if (!BlowfishInit(encKey, pHeader, 2)) return false; + BlowfishEncrypt(&secureArea[0], &secureArea[1]); + if (!BlowfishInit(encKey, pHeader, 3)) return false; + for (size_t i = 2; i < 0x200; i += 2) { + BlowfishEncrypt(&secureArea[i], &secureArea[i + 1]); + } + header.secureAreaCrc = Crc(secureArea, sizeof(secureArea)); + } - header.secureAreaCrc = Crc(secureArea, sizeof(secureArea)); header.headerCrc = Crc(&header, offsetof(Header, headerCrc)); size_t prevPos = ftell(fpRom); @@ -537,11 +551,12 @@ void PrintUsage(const char *program) { printf( "buildrom " VERSION "\n" "\n" - "Usage: %s -a BASEDIR -b BUILDDIR -r REGION -o OUTFILE\n" + "Usage: %s -a BASEDIR -b BUILDDIR -r REGION -o OUTFILE [-7 ARM7BIOS]\n" " -a BASEDIR \tBase directory generated by extractrom\n" " -b BUILDDIR\tBuild directory generated by Makefile\n" " -r REGION \tJ = Japan, E = USA, P = Europe\n" - " -o OUTFILE \tOutput ROM file\n", + " -o OUTFILE \tOutput ROM file\n" + " -7 ARM7BIOS\tPath to ARM7 BIOS file\n", program ); } @@ -555,6 +570,7 @@ int main(int argc, const char **argv) { const char *baseDir = NULL; const char *buildDir = NULL; const char *romFile = NULL; + const char *arm7bios = NULL; Region region = 0; for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "-o") == 0) { @@ -575,6 +591,12 @@ int main(int argc, const char **argv) { return 1; } buildDir = argv[i]; + } else if (strcmp(argv[i], "-7") == 0) { + if (++i >= argc) { + fprintf(stderr, "Expected pathname after -7\n"); + return 1; + } + arm7bios = argv[i]; } else if (strcmp(argv[i], "-r") == 0) { if (++i >= argc) { fprintf(stderr, "Expected region after -r\n"); @@ -740,13 +762,19 @@ int main(int argc, const char **argv) { return 1; } - if (!FinalizeHeader(fpRom, &header)) return false; + FILE *fp = fopen(ARM9_PROGRAM_FILE, "rb"); + if (fp == NULL) FATAL("Failed to open ARM9 program '" ARM9_PROGRAM_FILE "'\n"); + uint32_t secureArea[0x1000]; + if (fread(secureArea, sizeof(secureArea), 1, fp) != 1) FATAL("Failed to read secure area\n"); + fclose(fp); if (chdir(rootDir) != 0) { fprintf(stderr, "Failed to leave build directory '%s'\n", buildDir); return 1; } + if (!FinalizeHeader(fpRom, &header, arm7bios, secureArea)) return false; + free(readBuffer); fclose(fpRom); }