33
33
34
34
PrintConsole topScreen ;
35
35
PrintConsole bottomScreen ;
36
- char secure_area [0x4000 ];
37
- ncgc_ncard_t card ;
38
36
39
37
typedef struct {
40
38
uint32_t magic ;
@@ -75,8 +73,9 @@ static void wait_for_keys(uint32_t keys) {
75
73
}
76
74
77
75
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"
80
79
"(You may hotswap now.)\n" );
81
80
wait_for_keys (KEY_A );
82
81
return true;
@@ -103,6 +102,7 @@ static int32_t read_card(ncgc_ncard_t *const card, uint32_t address, uint32_t si
103
102
return 0 ;
104
103
}
105
104
105
+ mbedtls_sha256_context sha256_ctx ;
106
106
static bool verify_section (int i ,
107
107
ncgc_ncard_t * const card ,
108
108
const firm_hdr_t * const hdr ,
@@ -115,9 +115,8 @@ static bool verify_section(int i,
115
115
memcpy (iv , & hdr -> sections [i ], 12 );
116
116
memcpy (iv + 12 , & hdr -> sections [i ].size , 4 );
117
117
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 );
121
120
122
121
uint32_t cur_addr = hdr -> sections [i ].offset + 0x7E00 ;
123
122
uint32_t size_left = hdr -> sections [i ].size ;
@@ -131,7 +130,7 @@ static bool verify_section(int i,
131
130
return false;
132
131
}
133
132
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 );
135
134
136
135
if (cur_size == block_size ) {
137
136
// not last block (or size is multiple of block size, whatever)
@@ -143,11 +142,11 @@ static bool verify_section(int i,
143
142
}
144
143
145
144
unsigned char hash [0x20 ];
146
- mbedtls_sha256_finish (& ctx , hash );
145
+ mbedtls_sha256_finish (& sha256_ctx , hash );
147
146
// this just zeroes the struct
148
147
// FIRM hashes are top secret!
149
148
// hah, who am I kidding, don't even bother
150
- // mbedtls_sha256_free(&ctx );
149
+ // mbedtls_sha256_free(&sha256_ctx );
151
150
if (memcmp (hash , hdr -> sections [i ].sha256 , 0x20 )) {
152
151
iprintf ("Sect %d invalid hash\n" , i );
153
152
return false;
@@ -157,19 +156,40 @@ static bool verify_section(int i,
157
156
return true;
158
157
}
159
158
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
+ }
163
171
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
+ }
166
185
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 ();
169
191
consoleSelect (& topScreen );
170
-
171
- sysSetBusOwners (true, true);
172
-
192
+ consoleClear ();
173
193
bool dev = false;
174
194
iprintf ("Press X for retail FIRM\n"
175
195
" Y for dev FIRM\n" );
@@ -221,6 +241,9 @@ int main(void) {
221
241
goto fail ;
222
242
}
223
243
244
+ consoleClear ();
245
+ iprintf ("Checking for %s FIRM\n" , dev ? "dev" : "retail" );
246
+
224
247
firm_hdr_t * hdr = (firm_hdr_t * ) (secure_area + 0x3E00 );
225
248
if (memcmp (& hdr -> magic , "FIRM" , 4 )) {
226
249
iprintf ("FIRM magic not found\n"
@@ -289,8 +312,33 @@ int main(void) {
289
312
iprintf ("Errors reported.\n" );
290
313
}
291
314
315
+ consoleSelect (& bottomScreen );
316
+ print_magic (hdr );
317
+ iprintf ("\n" );
318
+ print_header_hash (hdr );
319
+ consoleSelect (& topScreen );
320
+
292
321
fail :
293
- iprintf ("Press B to exit .\n" );
322
+ iprintf ("Press B to check another cart .\n" );
294
323
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
+
295
343
return 0 ;
296
344
}
0 commit comments