firm_h* firm = buffer[0];
if (sdmmc_nand_readsectors(firm_offset / SECTOR_SIZE, firm_size / SECTOR_SIZE, (uint8_t*)firm))
- abort("Failed to read NAND!\n");
+ abort(" Failed to read NAND!\n");
- fprintf(stderr, "Read FIRM%u off NAND.\n", index);
+ fprintf(stderr, " Read FIRM%u off NAND.\n", index);
sdmmc_get_cid(1, (uint32_t*)cid);
sha(sha_t, cid, 0x10, SHA_256_MODE);
aes_setiv(ctr, AES_INPUT_BE|AES_INPUT_NORMAL);
aes((uint8_t*)firm, (uint8_t*)firm, firm_size / AES_BLOCK_SIZE, ctr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
- fprintf(stderr, "AES decrypted FIRM%u.\n", index);
+ fprintf(stderr, " AES decrypted FIRM%u.\n", index);
if (memcmp((char*) & firm->magic, "FIRM", 4))
- abort("Decryption failed on FIRM.\n");
+ abort(" Decryption failed on FIRM.\n");
- fprintf(stderr, "Magic is intact on FIRM%u.\n", index);
+ fprintf(stderr, " Magic is intact on FIRM%u.\n", index);
uint8_t detver = 0;
detver = 0x10;
if(decrypt_arm9bin((arm9bin_h*)((uint8_t*)firm + firm->section[2].offset), NATIVE_FIRM_TITLEID, detver)) {
- abort("\rFailed to decrypt FIRM%u arm9loader.\n", index);
+ abort(" Failed to decrypt FIRM%u arm9loader.\n", index);
}
- fprintf(stderr, "\rDecrypted FIRM%u arm9loader.\n", index);
+ fprintf(stderr, " Decrypted FIRM%u arm9loader.\n", index);
}
void
uint8_t* key_data = key_search(key_loc, search_size, sha256, 0x4D);
if (!key_data)
- abort("0x05 KeyY not found!\n");
+ abort(" 0x05 KeyY not found!\n");
- fprintf(stderr, "0x05 KeyY at %lx in FIRM1\n", (uint32_t)key_data - (uint32_t)key_loc);
+ fprintf(stderr, " 0x05 KeyY at %lx in FIRM1\n", (uint32_t)key_data - (uint32_t)key_loc);
memcpy(mem, key_data, 16);
uint8_t* key_data = key_search(key_loc, search_size, sha256, 0x0C);
if (!key_data)
- abort("0x3D KeyY #1 not found!\n");
+ abort(" 0x3D KeyY #1 not found!\n");
- fprintf(stderr, "0x3D KeyY #1 at %lx in FIRM0\n", (uint32_t)key_data - (uint32_t)key_loc);
+ fprintf(stderr, " 0x3D KeyY #1 at %lx in FIRM0\n", (uint32_t)key_data - (uint32_t)key_loc);
memcpy(mem, key_data, 16);
uint8_t* key_data = key_search(key_loc, search_size, sha256, 0xDD);
if (!key_data)
- abort("FIRM Section key not found!\n");
+ abort(" FIRM Section key not found!\n");
- fprintf(stderr, "FIRM Section key at %lx in FIRM\n", (uint32_t)key_data - (uint32_t)key_loc);
+ fprintf(stderr, " FIRM Section key at %lx in FIRM\n", (uint32_t)key_data - (uint32_t)key_loc);
return key_data;
}
int
decrypt_cetk_key(void *key, const void *cetk)
{
+ static int got_cetk = 0;
uint8_t iv[AES_BLOCK_SIZE] = { 0 };
uint32_t sigtype = __builtin_bswap32(*(uint32_t *)cetk);
if (ticket->ticketCommonKeyYIndex != 1)
return 1;
+ if (got_cetk == 0) {
+ extract_slot0x3DkeyY();
+ got_cetk = 1;
+ }
+
aes_use_keyslot(0x3D);
memcpy(iv, ticket->titleID, sizeof(ticket->titleID));
memcpy(key, ticket->titleKey, sizeof(ticket->titleKey));
aes(key, key, 1, iv, AES_CBC_DECRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
- fprintf(stderr, "g");
+ fprintf(stderr, " Extracted titlekey from cetk.\n");
return 0;
}
uint8_t exefs_key[16] = { 0 };
uint8_t exefs_iv[16] = { 0 };
- fprintf(BOTTOM_SCREEN, "n");
+ fprintf(stderr, " Decrypting FIRM container\n");
aes_setkey(0x16, key, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_use_keyslot(0x16);
aes(ncch, ncch, *size / AES_BLOCK_SIZE, firm_iv, AES_CBC_DECRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
exefs_h *exefs = (exefs_h *)((void *)ncch + ncch->exeFSOffset * MEDIA_UNITS);
uint32_t exefs_size = ncch->exeFSSize * MEDIA_UNITS;
- fprintf(BOTTOM_SCREEN, "e");
+ fprintf(stderr, " Decrypting ExeFs for FIRM\n");
aes_setkey(0x2C, exefs_key, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_use_keyslot(0x2C);
aes(exefs, exefs, exefs_size / AES_BLOCK_SIZE, exefs_iv, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
if (!read_file(firm_key, path_firmkey, AES_BLOCK_SIZE)) {
// Missing firmkey. Attempt to get from CETK (only works if system was booted)
if (!read_file((void *)FCRAM_JUNK_LOC, path_cetk, FCRAM_SPACING) || decrypt_cetk_key(firm_key, (void *)FCRAM_JUNK_LOC)) {
- fprintf(BOTTOM_SCREEN, "!");
+ fprintf(stderr, " No firmkey and failed to extract from cetk\n");
return 1;
} else {
- fprintf(BOTTOM_SCREEN, "t");
+ fprintf(stderr, " Saving firmkey for future use.\n");
write_file(firm_key, path_firmkey, AES_BLOCK_SIZE);
}
} else {
- fprintf(BOTTOM_SCREEN, "k");
+ fprintf(stderr, " Read firmkey from filesystem.\n");
}
- fprintf(BOTTOM_SCREEN, "d");
+ fprintf(stderr, " Decrypting FIRM\n");
if (decrypt_firm_title(dest, (void *)dest, size, firm_key) != 0) {
- fprintf(BOTTOM_SCREEN, "!");
+ fprintf(stderr, " Failed to decrypt FIRM title.\n");
return 1;
}
return 0;
int firmware_changed = 0;
if (read_file(dest, path, *size) == 0) {
- fprintf(BOTTOM_SCREEN, "!");
+ fprintf(stderr, " FIRM file is missing.\n");
return 1;
} else {
- fprintf(BOTTOM_SCREEN, "l");
+ fprintf(stderr, " Loaded FIRM off filesystem\n");
}
// Check and decrypt FIRM if it is encrypted.
if (dest->magic != FIRM_MAGIC) {
status = decrypt_firm(dest, path_firmkey, path_cetk, size);
if (status != 0) {
- fprintf(BOTTOM_SCREEN, "!");
+ fprintf(stderr, " Decryption seems to have failed\n");
return 1;
}
firmware_changed = 1; // Decryption performed.
} else {
- fprintf(BOTTOM_SCREEN, "_");
+ fprintf(stderr, " FIRM is decrypted\n");
}
struct firm_signature *fsig = get_firm_info(dest);
}
firmware_changed = 1; // Decryption of arm9bin performed.
} else {
- fprintf(BOTTOM_SCREEN, "_");
+ fprintf(stderr, " ARM9 segment is decrypted\n");
if (firm_title == NATIVE_FIRM_TITLEID && fsig->version > 0x0F) {
slot0x11key96_init(); // This has to be loaded
// regardless, otherwise boot will
// Save firmware.bin if decryption was done.
if (firmware_changed) {
- fprintf(BOTTOM_SCREEN, "s");
+ fprintf(stderr, " Overwriting FIRM with decrypted FIRM\n");
write_file(dest, path, *size);
}
if (fsig->console == console_n3ds) {
- fprintf(BOTTOM_SCREEN, "f");
+ fprintf(stderr, " Patching arm9 entrypoint\n");
// Patch the entrypoint to skip arm9loader
if (firm_title == NATIVE_FIRM_TITLEID) {
if (update_96_keys && fsig->console == console_n3ds && fsig->version > 0x0F) {
void *keydata = find_section_key();
if (!keydata) {
- abort("Couldn't find key!\n");
+ abort("Couldn't find section key.\n");
}
wait();
*(uint8_t *)(keydata + 0xF) += 1;
}
- fprintf(BOTTOM_SCREEN, "Updated keyX keyslots\n");
+ fprintf(stderr, "Updated keyX keyslots.\n");
}
for (firm_section_h *section = firm_loc->section; section < firm_loc->section + 4 && section->address != 0; section++) {
memcpy((void *)section->address, (void *)firm_loc + section->offset, section->size);
}
- fprintf(BOTTOM_SCREEN, "Copied FIRM\n");
+ fprintf(stderr, "Copied FIRM.\n");
wait();
- clear_disp(BOTTOM_SCREEN);
- set_cursor(BOTTOM_SCREEN, 0, 0);
+ clear_disp(stderr);
+ set_cursor(stderr, 0, 0);
fflush(stderr); // Flush logs if need be before unmount.
process9->address = p9exheader->sci.textCodeSet.address;
process9->size = (*p9exefs)->fileHeaders[0].size;
process9->offset = (void *)((*p9exefs) + 1) - (void *)firm;
- fprintf(BOTTOM_SCREEN, "p");
+ fprintf(stderr, " Found process9 offset\n");
return 0;
}
}
}
}
}
- fprintf(BOTTOM_SCREEN, "\n Couldn't find Process9?\n");
+ fprintf(stderr, " Couldn't find Process9?\n");
return 1;
}
if (firm_loaded)
return 0;
- fprintf(BOTTOM_SCREEN, "FIRM load triggered.\n");
+ fprintf(stderr, "FIRM load triggered.\n");
- fprintf(BOTTOM_SCREEN, "NATIVE_FIRM\n [");
+ fprintf(stderr, "Loading NATIVE_FIRM\n");
if (load_firm(firm_loc, PATH_NATIVE_F, PATH_NATIVE_FIRMKEY, PATH_NATIVE_CETK, &firm_size, NATIVE_FIRM_TITLEID) != 0) {
- abort("]\n Failed to load NATIVE_FIRM.\n");
+ abort("\n Failed to load NATIVE_FIRM.\n");
}
find_proc9(firm_loc, &firm_proc9, &firm_p9_exefs);
- fprintf(stderr, "]\n");
- fprintf(stderr, "Ver: %x, %u\n", get_firm_info(firm_loc)->version, get_firm_info(firm_loc)->console );
+ fprintf(stderr, " Ver: %x, %u\n", get_firm_info(firm_loc)->version, get_firm_info(firm_loc)->console );
- fprintf(BOTTOM_SCREEN, "TWL_FIRM\n [");
+ fprintf(stderr, "TWL_FIRM\n");
if (load_firm(twl_firm_loc, PATH_TWL_F, PATH_TWL_FIRMKEY, PATH_TWL_CETK, &twl_firm_size, TWL_FIRM_TITLEID) != 0) {
- fprintf(BOTTOM_SCREEN, "]\n TWL_FIRM failed to load.\n");
+ fprintf(stderr, "\n TWL_FIRM failed to load.\n");
state = 1;
} else {
find_proc9(twl_firm_loc, &twl_firm_proc9, &twl_firm_p9_exefs);
- fprintf(stderr, "]\n");
- fprintf(stderr, "Ver: %x, %u\n", get_firm_info(twl_firm_loc)->version, get_firm_info(twl_firm_loc)->console );
+ fprintf(stderr, " Ver: %x, %u\n", get_firm_info(twl_firm_loc)->version, get_firm_info(twl_firm_loc)->console );
}
- fprintf(BOTTOM_SCREEN, "AGB_FIRM\n [");
+ fprintf(stderr, "AGB_FIRM\n");
if (load_firm(agb_firm_loc, PATH_AGB_F, PATH_AGB_FIRMKEY, PATH_AGB_CETK, &agb_firm_size, AGB_FIRM_TITLEID) != 0) {
- fprintf(BOTTOM_SCREEN, "]\n AGB_FIRM failed to load.\n");
+ fprintf(stderr, "\n AGB_FIRM failed to load.\n");
state = 1;
} else {
find_proc9(agb_firm_loc, &agb_firm_proc9, &agb_firm_p9_exefs);
- fprintf(stderr, "]\n");
- fprintf(stderr, "Ver: %x, %u\n", get_firm_info(agb_firm_loc)->version, get_firm_info(agb_firm_loc)->console );
+ fprintf(stderr, " Ver: %x, %u\n", get_firm_info(agb_firm_loc)->version, get_firm_info(agb_firm_loc)->console );
}
firm_loaded = 1; // Loaded.
void
boot_cfw()
{
- fprintf(BOTTOM_SCREEN, "Loading firmware...\n");
+ fprintf(stderr, "Loading firmware...\n");
load_firms();
generate_patch_cache();
}
- fprintf(BOTTOM_SCREEN, "Patching firmware...\n");
+ fprintf(stderr, "Patching firmware...\n");
if (patch_firm_all() != 0)
return;