Load encryption key and CRC encrypted secure area

This commit is contained in:
Aetias
2023-10-18 23:10:24 +02:00
parent a20ae6843f
commit add71a7482
+43 -15
View File
@@ -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);
}