Skip to content

Commit 2fe1dae

Browse files
committed
Allow checking multiple carts without poweroff, and display header hash and magic
1 parent 9518ebb commit 2fe1dae

File tree

1 file changed

+69
-21
lines changed

1 file changed

+69
-21
lines changed

src/main.c

+69-21
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333

3434
PrintConsole topScreen;
3535
PrintConsole bottomScreen;
36-
char secure_area[0x4000];
37-
ncgc_ncard_t card;
3836

3937
typedef struct {
4038
uint32_t magic;
@@ -75,8 +73,9 @@ static void wait_for_keys(uint32_t keys) {
7573
}
7674

7775
static bool reset_card(void) {
78-
iprintf("Remove and reinsert the card,\n"
79-
"then press A.\n"
76+
iprintf("Remove the card FULLY from the\n"
77+
"slot. Reinsert the card, then\n"
78+
"press A.\n"
8079
"(You may hotswap now.)\n");
8180
wait_for_keys(KEY_A);
8281
return true;
@@ -103,6 +102,7 @@ static int32_t read_card(ncgc_ncard_t *const card, uint32_t address, uint32_t si
103102
return 0;
104103
}
105104

105+
mbedtls_sha256_context sha256_ctx;
106106
static bool verify_section(int i,
107107
ncgc_ncard_t *const card,
108108
const firm_hdr_t *const hdr,
@@ -115,9 +115,8 @@ static bool verify_section(int i,
115115
memcpy(iv, &hdr->sections[i], 12);
116116
memcpy(iv + 12, &hdr->sections[i].size, 4);
117117

118-
mbedtls_sha256_context ctx;
119-
mbedtls_sha256_init(&ctx);
120-
mbedtls_sha256_starts(&ctx, 0);
118+
mbedtls_sha256_init(&sha256_ctx);
119+
mbedtls_sha256_starts(&sha256_ctx, 0);
121120

122121
uint32_t cur_addr = hdr->sections[i].offset + 0x7E00;
123122
uint32_t size_left = hdr->sections[i].size;
@@ -131,7 +130,7 @@ static bool verify_section(int i,
131130
return false;
132131
}
133132
AES_CBC_decrypt_buffer(pt, ct, cur_size, key, iv);
134-
mbedtls_sha256_update(&ctx, pt, cur_size);
133+
mbedtls_sha256_update(&sha256_ctx, pt, cur_size);
135134

136135
if (cur_size == block_size) {
137136
// not last block (or size is multiple of block size, whatever)
@@ -143,11 +142,11 @@ static bool verify_section(int i,
143142
}
144143

145144
unsigned char hash[0x20];
146-
mbedtls_sha256_finish(&ctx, hash);
145+
mbedtls_sha256_finish(&sha256_ctx, hash);
147146
// this just zeroes the struct
148147
// FIRM hashes are top secret!
149148
// hah, who am I kidding, don't even bother
150-
// mbedtls_sha256_free(&ctx);
149+
// mbedtls_sha256_free(&sha256_ctx);
151150
if (memcmp(hash, hdr->sections[i].sha256, 0x20)) {
152151
iprintf("Sect %d invalid hash\n", i);
153152
return false;
@@ -157,19 +156,40 @@ static bool verify_section(int i,
157156
return true;
158157
}
159158

160-
int main(void) {
161-
videoSetMode(MODE_0_2D);
162-
videoSetModeSub(MODE_0_2D);
159+
static void print_header_hash(const firm_hdr_t *const hdr) {
160+
mbedtls_sha256_init(&sha256_ctx);
161+
mbedtls_sha256_starts(&sha256_ctx, 0);
162+
mbedtls_sha256_update(&sha256_ctx, (const unsigned char *) hdr, sizeof(firm_hdr_t));
163+
unsigned char hash[0x20];
164+
mbedtls_sha256_finish(&sha256_ctx, hash);
165+
iprintf("FIRM header SHA256:\n");
166+
for (unsigned int i = 0; i < sizeof(hash); ++i) {
167+
iprintf("%02x", hash[i]);
168+
}
169+
iprintf("\n");
170+
}
163171

164-
vramSetBankA(VRAM_A_MAIN_BG);
165-
vramSetBankC(VRAM_C_SUB_BG);
172+
static void print_magic(const firm_hdr_t *const hdr) {
173+
unsigned int start;
174+
for (start = sizeof(hdr->garbage); start; --start) {
175+
if (hdr->garbage[start-1] < 0x20 || hdr->garbage[start-1] > 0x7E) {
176+
break;
177+
}
178+
}
179+
iprintf("FIRM reserved area magic:\n");
180+
for (; start < sizeof(hdr->garbage); ++start) {
181+
iprintf("%c", hdr->garbage[start]);
182+
}
183+
iprintf("\n");
184+
}
166185

167-
consoleInit(&topScreen, 3, BgType_Text4bpp, BgSize_T_256x256, 31, 0, true, true);
168-
consoleInit(&bottomScreen, 3, BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true);
186+
char secure_area[0x4000];
187+
ncgc_ncard_t card;
188+
void do_check(void) {
189+
consoleSelect(&bottomScreen);
190+
consoleClear();
169191
consoleSelect(&topScreen);
170-
171-
sysSetBusOwners(true, true);
172-
192+
consoleClear();
173193
bool dev = false;
174194
iprintf("Press X for retail FIRM\n"
175195
" Y for dev FIRM\n");
@@ -221,6 +241,9 @@ int main(void) {
221241
goto fail;
222242
}
223243

244+
consoleClear();
245+
iprintf("Checking for %s FIRM\n", dev ? "dev" : "retail");
246+
224247
firm_hdr_t *hdr = (firm_hdr_t *) (secure_area + 0x3E00);
225248
if (memcmp(&hdr->magic, "FIRM", 4)) {
226249
iprintf("FIRM magic not found\n"
@@ -289,8 +312,33 @@ int main(void) {
289312
iprintf("Errors reported.\n");
290313
}
291314

315+
consoleSelect(&bottomScreen);
316+
print_magic(hdr);
317+
iprintf("\n");
318+
print_header_hash(hdr);
319+
consoleSelect(&topScreen);
320+
292321
fail:
293-
iprintf("Press B to exit.\n");
322+
iprintf("Press B to check another cart.\n");
294323
wait_for_keys(KEY_B);
324+
}
325+
326+
int main(void) {
327+
videoSetMode(MODE_0_2D);
328+
videoSetModeSub(MODE_0_2D);
329+
330+
vramSetBankA(VRAM_A_MAIN_BG);
331+
vramSetBankC(VRAM_C_SUB_BG);
332+
333+
consoleInit(&topScreen, 3, BgType_Text4bpp, BgSize_T_256x256, 31, 0, true, true);
334+
consoleInit(&bottomScreen, 3, BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true);
335+
consoleSelect(&topScreen);
336+
337+
sysSetBusOwners(true, true);
338+
339+
while (true) {
340+
do_check();
341+
}
342+
295343
return 0;
296344
}

0 commit comments

Comments
 (0)