From 582bc916053ab2f30aeb78d7932232a5bbd78bd5 Mon Sep 17 00:00:00 2001 From: shchmue Date: Thu, 31 Mar 2022 12:28:32 -0600 Subject: [PATCH] Move Mariko partial key dump to main menu --- source/gfx/tui.c | 2 +- source/gfx/tui.h | 4 +-- source/keys/keys.c | 36 ++++++++++--------- source/keys/keys.h | 1 + source/main.c | 90 +++++++++++++++++++++++++++++++++++----------- 5 files changed, 92 insertions(+), 41 deletions(-) diff --git a/source/gfx/tui.c b/source/gfx/tui.c index 6d0e6b4..ec6c08a 100644 --- a/source/gfx/tui.c +++ b/source/gfx/tui.c @@ -135,7 +135,7 @@ void *tui_do_menu(menu_t *menu) gfx_con_setcol(0xFF1B1B1B, 1, 0xFFCCCCCC); else gfx_con_setcol(0xFFCCCCCC, 1, 0xFF1B1B1B); - if (menu->ents[cnt].type != MENT_CHGLINE && menu->ents[cnt].type != MENT_MENU) + if (menu->ents[cnt].type != MENT_CHGLINE) { if (cnt == idx) gfx_printf(" %s", menu->ents[cnt].caption); diff --git a/source/gfx/tui.h b/source/gfx/tui.h index 6f02781..98330b6 100644 --- a/source/gfx/tui.h +++ b/source/gfx/tui.h @@ -54,8 +54,8 @@ typedef struct _menu_t #define MDEF_END() {MENT_END} #define MDEF_HANDLER(caption, _handler, color) { MENT_HANDLER, caption, color, NULL, { .handler = _handler } } #define MDEF_HANDLER_EX(caption, data, _handler, color) { MENT_HANDLER, caption, color, data, { .handler = _handler } } -#define MDEF_MENU(caption, _menu) { MENT_MENU, caption, 0, NULL, { .menu = _menu } } -#define MDEF_BACK() { MENT_BACK, "Back" } +#define MDEF_MENU(caption, _menu, color) { MENT_MENU, caption, color, NULL, { .menu = _menu } } +#define MDEF_BACK(color) { MENT_BACK, "Back", color } #define MDEF_CAPTION(caption, color) { MENT_CAPTION, caption, color } #define MDEF_CHGLINE() {MENT_CHGLINE} diff --git a/source/keys/keys.c b/source/keys/keys.c index 74d2ecf..c5c4bae 100644 --- a/source/keys/keys.c +++ b/source/keys/keys.c @@ -583,11 +583,15 @@ static bool _derive_emmc_keys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit // The security engine supports partial key override for locked keyslots // This allows for a manageable brute force on a PC // Then the Mariko AES class keys, KEK, BEK, unique SBK and SSK can be recovered -static void _save_mariko_partial_keys(u32 start, u32 count, bool append) { +int save_mariko_partial_keys(u32 start, u32 count, bool append) { if (start + count > SE_AES_KEYSLOT_COUNT) { - return; + return 1; } + display_backlight_brightness(h_cfg.backlight, 1000); + gfx_clear_partial_grey(0x1B, 32, 1224); + gfx_con_setpos(0, 32); + u32 pos = 0; u32 zeros[AES_128_KEY_SIZE / 4] = {0}; u8 *data = malloc(4 * AES_128_KEY_SIZE); @@ -632,11 +636,11 @@ static void _save_mariko_partial_keys(u32 start, u32 count, bool append) { if (strlen(text_buffer) == 0) { EPRINTFARGS("Failed to dump partial keys %d-%d.", start, start + count - 1); - return; + free(text_buffer); + return 2; } FIL fp; - u32 res = 0; BYTE mode = FA_WRITE; if (append) { @@ -645,10 +649,16 @@ static void _save_mariko_partial_keys(u32 start, u32 count, bool append) { mode |= FA_CREATE_ALWAYS; } - res = f_open(&fp, "sd:/switch/partialaes.keys", mode); - if (res) { + if (!sd_mount()) { + EPRINTF("Unable to mount SD."); + free(text_buffer); + return 3; + } + + if (f_open(&fp, "sd:/switch/partialaes.keys", mode)) { EPRINTF("Unable to write partial keys to SD."); - return; + free(text_buffer); + return 3; } f_write(&fp, text_buffer, strlen(text_buffer), NULL); @@ -657,6 +667,8 @@ static void _save_mariko_partial_keys(u32 start, u32 count, bool append) { gfx_printf("%kWrote partials to sd:/switch/partialaes.keys\n", colors[(color_idx++) % 6]); free(text_buffer); + + return 0; } static void _save_keys_to_sd(key_derivation_ctx_t *keys, titlekey_buffer_t *titlekey_buffer, bool is_dev) { @@ -756,10 +768,6 @@ static void _save_keys_to_sd(key_derivation_ctx_t *keys, titlekey_buffer_t *titl } else EPRINTF("Unable to save keys to SD."); - if (h_cfg.t210b01) { - _save_mariko_partial_keys(12, 4, true); - } - if (_titlekey_count == 0 || !titlekey_buffer) { free(text_buffer); return; @@ -801,12 +809,6 @@ static void _derive_keys() { minerva_periodic_training(); - if (h_cfg.t210b01) { - _save_mariko_partial_keys(0, 12, false); - } - - minerva_periodic_training(); - if (!_check_keyslot_access()) { EPRINTF("Unable to set crypto keyslots!\nTry launching payload differently\n or flash Spacecraft-NX if using a modchip."); return; diff --git a/source/keys/keys.h b/source/keys/keys.h index 676fddb..8e2fb23 100644 --- a/source/keys/keys.h +++ b/source/keys/keys.h @@ -141,5 +141,6 @@ typedef struct { #define SAVE_KEY_FAMILY_VAR(name, varname, start) _save_key_family(#name, varname, start, ARRAY_SIZE(varname), sizeof(*(varname)), text_buffer) void dump_keys(); +int save_mariko_partial_keys(u32 start, u32 count, bool append); #endif diff --git a/source/main.c b/source/main.c index cd8e92e..b4aa670 100644 --- a/source/main.c +++ b/source/main.c @@ -304,26 +304,80 @@ void dump_emunand() dump_keys(); } +void dump_mariko_partial_keys(); + +ment_t ment_partials[] = { + MDEF_BACK(colors[0]), + MDEF_CHGLINE(), + MDEF_CAPTION("This dumps the results of writing zeros", colors[1]), + MDEF_CAPTION("over consecutive 32-bit portions of each", colors[1]), + MDEF_CAPTION("keyslot, the results of which can then", colors[1]), + MDEF_CAPTION("be bruteforced quickly on a computer", colors[1]), + MDEF_CAPTION("to recover keys from unreadable keyslots.", colors[1]), + MDEF_CHGLINE(), + MDEF_CAPTION("This includes the Mariko KEK and BEK", colors[2]), + MDEF_CAPTION("as well as the unique SBK.", colors[2]), + MDEF_CHGLINE(), + MDEF_CAPTION("These are not useful for most users", colors[3]), + MDEF_CAPTION("but are included for archival purposes.", colors[3]), + MDEF_CHGLINE(), + MDEF_CAPTION("Warning: this wipes keyslots!", colors[4]), + MDEF_CAPTION("The console must be completely restarted!", colors[4]), + MDEF_CAPTION("Modchip must run again to fix the keys!", colors[4]), + MDEF_CAPTION("---------------", colors[5]), + MDEF_HANDLER("Dump Mariko Partials", dump_mariko_partial_keys, colors[0]), + MDEF_END() +}; + +menu_t menu_partials = { ment_partials, NULL, 0, 0 }; + power_state_t STATE_POWER_OFF = POWER_OFF_RESET; power_state_t STATE_REBOOT_FULL = POWER_OFF_REBOOT; power_state_t STATE_REBOOT_RCM = REBOOT_RCM; power_state_t STATE_REBOOT_BYPASS_FUSES = REBOOT_BYPASS_FUSES; ment_t ment_top[] = { - MDEF_HANDLER("Dump from SysNAND", dump_sysnand, COLOR_RED), - MDEF_HANDLER("Dump from EmuNAND", dump_emunand, COLOR_ORANGE), - MDEF_CAPTION("---------------", COLOR_YELLOW), - MDEF_HANDLER("Payloads...", launch_tools, COLOR_GREEN), - MDEF_HANDLER("Reboot to hekate", launch_hekate, COLOR_BLUE), - MDEF_CAPTION("---------------", COLOR_VIOLET), - MDEF_HANDLER_EX("Reboot (OFW)", &STATE_REBOOT_BYPASS_FUSES, power_set_state_ex, COLOR_RED), - MDEF_HANDLER_EX("Reboot (RCM)", &STATE_REBOOT_RCM, power_set_state_ex, COLOR_ORANGE), - MDEF_HANDLER_EX("Power off", &STATE_POWER_OFF, power_set_state_ex, COLOR_YELLOW), + MDEF_HANDLER("Dump from SysNAND", dump_sysnand, colors[0]), + MDEF_HANDLER("Dump from EmuNAND", dump_emunand, colors[1]), + MDEF_CAPTION("---------------", colors[2]), + MDEF_MENU("Dump Mariko Partials (requires reboot)", &menu_partials, colors[3]), + MDEF_CAPTION("---------------", colors[4]), + MDEF_HANDLER("Payloads...", launch_tools, colors[5]), + MDEF_HANDLER("Reboot to hekate", launch_hekate, colors[0]), + MDEF_CAPTION("---------------", colors[1]), + MDEF_HANDLER_EX("Reboot (OFW)", &STATE_REBOOT_BYPASS_FUSES, power_set_state_ex, colors[2]), + MDEF_HANDLER_EX("Reboot (RCM)", &STATE_REBOOT_RCM, power_set_state_ex, colors[3]), + MDEF_HANDLER_EX("Power off", &STATE_POWER_OFF, power_set_state_ex, colors[4]), MDEF_END() }; menu_t menu_top = { ment_top, NULL, 0, 0 }; +void grey_out_menu_item(ment_t *menu) +{ + menu->type = MENT_CAPTION; + menu->color = 0xFF555555; + menu->handler = NULL; +} + +void dump_mariko_partial_keys() +{ + if (h_cfg.t210b01) { + int res = save_mariko_partial_keys(0, 16, false); + if (res == 0 || res == 3) + { + // Grey out dumping menu items as the keyslots have been invalidated. + grey_out_menu_item(&ment_top[0]); + grey_out_menu_item(&ment_top[1]); + grey_out_menu_item(&ment_top[3]); + grey_out_menu_item(&ment_partials[18]); + } + + gfx_printf("\n%kPress a button to return to the menu.", COLOR_ORANGE); + btn_wait(); + } +} + extern void pivot_stack(u32 stack_top); void ipl_main() @@ -373,30 +427,24 @@ void ipl_main() // Grey out emummc option if not present. if (h_cfg.emummc_force_disable) { - ment_top[1].type = MENT_CAPTION; - ment_top[1].color = 0xFF555555; - ment_top[1].handler = NULL; + grey_out_menu_item(&ment_top[1]); } // Grey out reboot to RCM option if on Mariko or patched console. if (h_cfg.t210b01 || h_cfg.rcm_patched) { - ment_top[7].type = MENT_CAPTION; - ment_top[7].color = 0xFF555555; - ment_top[7].handler = NULL; + grey_out_menu_item(&ment_top[9]); } - if (h_cfg.rcm_patched) - { - ment_top[7].data = &STATE_REBOOT_FULL; + // Grey out Mariko partial dump option on Erista. + if (!h_cfg.t210b01) { + grey_out_menu_item(&ment_top[3]); } // Grey out reboot to hekate option if no update.bin found. if (f_stat("bootloader/update.bin", NULL)) { - ment_top[4].type = MENT_CAPTION; - ment_top[4].color = 0xFF555555; - ment_top[4].handler = NULL; + grey_out_menu_item(&ment_top[6]); } minerva_change_freq(FREQ_800);