From 8584493c7fc7964d7a694b0cd5823ca336a05463 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Mon, 16 Dec 2019 00:53:22 +0200 Subject: [PATCH] sept: Add support for loading sept from fss0 If `fss0=` key is detected, sept will be loaded from fusee-secondary.bin instead of `sept/sept_*`. This will negate missing sept and failed to decrypt pkg2 errors, when booting HOS, for users that forget to update sept folder. --- README.md | 3 +- bootloader/frontend/fe_tools.c | 2 +- bootloader/hos/fss.c | 84 +++++++++++++++++++++++----------- bootloader/hos/fss.h | 12 ++++- bootloader/hos/hos_config.c | 2 +- bootloader/hos/sept.c | 66 ++++++++++++++++---------- bootloader/hos/sept.h | 4 +- bootloader/main.c | 8 ++-- 8 files changed, 120 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 1c18f9e..4627cf6 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Custom Nintendo Switch bootloader, firmware patcher, and more. | bootloader/screenshots/ | Folder where Nyx screenshots are saved | | bootloader/payloads/ | For payloads. 'Payloads...' menu. Autoboot only supported by including them into an ini. All CFW bootloaders, tools, Linux payloads are supported. | | bootloader/libtools/ | Future reserved | +| sept | Sept folder. This must be always get updated via the Atmosphère release zip. Needed for tools and booting HOS on 7.0.0 and up. Unused for booting HOS if `fss0=` key is defined. | **Note**: Sept files for booting 7.0.0 and up are expected at /sept folder at root of sd card. @@ -68,7 +69,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini) | kernel={SD path} | Replaces the kernel binary | | kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. | | kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. | -| fss0={SD path} | Takes a fusee-secondary binary and `extracts` all needed parts from it. | +| fss0={SD path} | Takes a fusee-secondary binary and `extracts` all needed parts from it. kips, exosphere, warmboot and sept. | | kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or as CSV. If not found, an error will show up | | fullsvcperm=1 | Disables SVC verification (full services permission) | | debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. | diff --git a/bootloader/frontend/fe_tools.c b/bootloader/frontend/fe_tools.c index 597e4fe..484364c 100644 --- a/bootloader/frontend/fe_tools.c +++ b/bootloader/frontend/fe_tools.c @@ -109,7 +109,7 @@ void dump_packages12() gfx_printf("sept will run to get the keys.\nThen rerun this option."); btn_wait(); - if (!reboot_to_sept((u8 *)tsec_ctxt.fw, kb)) + if (!reboot_to_sept((u8 *)tsec_ctxt.fw, kb, NULL)) { gfx_printf("Failed to run sept\n"); goto out_free; diff --git a/bootloader/hos/fss.c b/bootloader/hos/fss.c index 5d2455d..1685acb 100644 --- a/bootloader/hos/fss.c +++ b/bootloader/hos/fss.c @@ -90,11 +90,12 @@ static void _update_r2p(const char *path) free(r2p_path); } -int parse_fss(launch_ctxt_t *ctxt, const char *path) +int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt) { FIL fp; bool stock = false; + int sept_used = 0; LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link) { @@ -103,13 +104,14 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path) stock = true; } - if (stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable)) + if (!sept_ctxt && stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable)) return 1; if (f_open(&fp, path, FA_READ) != FR_OK) return 0; - ctxt->atmosphere = true; + if (!sept_ctxt) + ctxt->atmosphere = true; void *fss = malloc(f_size(&fp)); // Read header. @@ -135,29 +137,48 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path) continue; // Load content to launch context. - switch (curr_fss_cnt[i].type) + if (!sept_ctxt) { - case CNT_TYPE_KIP: - if (stock) + switch (curr_fss_cnt[i].type) + { + case CNT_TYPE_KIP: + if (stock) + continue; + merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t)); + mkip1->kip1 = content; + list_append(&ctxt->kip1_list, &mkip1->link); + DPRINTF("Loaded %s.kip1 from FSS0 (size %08X)\n", curr_fss_cnt[i].name, curr_fss_cnt[i].size); + break; + case CNT_TYPE_EXO: + ctxt->secmon_size = curr_fss_cnt[i].size; + ctxt->secmon = content; + break; + case CNT_TYPE_WBT: + ctxt->warmboot_size = curr_fss_cnt[i].size; + ctxt->warmboot = content; + break; + default: continue; - merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t)); - mkip1->kip1 = content; - list_append(&ctxt->kip1_list, &mkip1->link); - DPRINTF("Loaded %s.kip1 from FSS0 (size %08X)\n", curr_fss_cnt[i].name, curr_fss_cnt[i].size); - break; - case CNT_TYPE_EXO: - ctxt->secmon_size = curr_fss_cnt[i].size; - ctxt->secmon = content; - break; - case CNT_TYPE_WBT: - ctxt->warmboot_size = curr_fss_cnt[i].size; - ctxt->warmboot = content; - break; - default: - continue; - // TODO: add more types? - // case CNT_TYPE_SP1: - // case CNT_TYPE_SP2: + } + } + else + { + // Load content to launch context. + switch (curr_fss_cnt[i].type) + { + case CNT_TYPE_SP1: + memcpy(sept_ctxt->sept_primary, content, curr_fss_cnt[i].size); + break; + case CNT_TYPE_SP2: + if (!memcmp(curr_fss_cnt[i].name, (sept_ctxt->kb < KB_FIRMWARE_VERSION_810) ? "septsecondary00" : "septsecondary01", 15)) + { + memcpy(sept_ctxt->sept_secondary, content, curr_fss_cnt[i].size); + sept_used = 1; + } + break; + default: + continue; + } } f_lseek(&fp, curr_fss_cnt[i].offset); @@ -169,11 +190,22 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path) _update_r2p(path); - return 1; + return (!sept_ctxt ? 1 : sept_used); } f_close(&fp); free(fss); return 0; -} \ No newline at end of file +} + +int load_sept_from_ffs0(fss0_sept_t *sept_ctxt) +{ + LIST_FOREACH_ENTRY(ini_kv_t, kv, &sept_ctxt->cfg_sec->kvs, link) + { + if (!strcmp("fss0", kv->key)) + return parse_fss(NULL, kv->val, sept_ctxt); + } + + return 0; +} diff --git a/bootloader/hos/fss.h b/bootloader/hos/fss.h index e003647..3f56d7c 100644 --- a/bootloader/hos/fss.h +++ b/bootloader/hos/fss.h @@ -19,6 +19,16 @@ #include "hos.h" -int parse_fss(launch_ctxt_t *ctxt, const char *path); +typedef struct _fss0_sept_t +{ + u32 kb; + ini_sec_t *cfg_sec; + void *sept_primary; + void *sept_secondary; + +} fss0_sept_t; + +int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt); +int load_sept_from_ffs0(fss0_sept_t *sept_ctxt); #endif diff --git a/bootloader/hos/hos_config.c b/bootloader/hos/hos_config.c index 7d68713..d0b09c8 100644 --- a/bootloader/hos/hos_config.c +++ b/bootloader/hos/hos_config.c @@ -213,7 +213,7 @@ static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value) static int _config_fss(launch_ctxt_t *ctxt, const char *value) { - return parse_fss(ctxt, value); + return parse_fss(ctxt, value, NULL); } typedef struct _cfg_handler_t diff --git a/bootloader/hos/sept.c b/bootloader/hos/sept.c index 672e7dd..f37019e 100644 --- a/bootloader/hos/sept.c +++ b/bootloader/hos/sept.c @@ -17,6 +17,7 @@ #include #include "hos.h" +#include "fss.h" #include "sept.h" #include "../config/config.h" #include "../gfx/di.h" @@ -73,7 +74,7 @@ extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size); extern sdmmc_t sd_sdmmc; extern sdmmc_storage_t sd_storage; -void check_sept() +void check_sept(ini_sec_t *cfg_sec) { // Check if non-hekate payload is used for sept and restore it. if (h_cfg.sept_run) @@ -117,7 +118,7 @@ void check_sept() if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run) { sdmmc_storage_end(&storage); - reboot_to_sept((u8 *)pkg1 + pkg1_id->tsec_off, pkg1_id->kb); + reboot_to_sept((u8 *)pkg1 + pkg1_id->tsec_off, pkg1_id->kb, cfg_sec); } out_free: @@ -125,9 +126,10 @@ out_free: sdmmc_storage_end(&storage); } -int reboot_to_sept(const u8 *tsec_fw, u32 kb) +int reboot_to_sept(const u8 *tsec_fw, u32 kb, ini_sec_t *cfg_sec) { FIL fp; + bool fss0_sept_used = false; // Copy warmboot reboot code and TSEC fw. u32 tsec_fw_size = 0x3000; @@ -137,36 +139,50 @@ int reboot_to_sept(const u8 *tsec_fw, u32 kb) memcpy((void *)SEPT_PK1T_ADDR, tsec_fw, tsec_fw_size); *(vu32 *)SEPT_TCSZ_ADDR = tsec_fw_size; - // Copy sept-primary. - if (f_open(&fp, "sept/sept-primary.bin", FA_READ)) - goto error; + if (cfg_sec) + { + fss0_sept_t sept_ctxt; + sept_ctxt.kb = kb; + sept_ctxt.cfg_sec = cfg_sec; + sept_ctxt.sept_primary = (void *)SEPT_STG1_ADDR; + sept_ctxt.sept_secondary = (void *)SEPT_STG2_ADDR; - if (f_read(&fp, (u8 *)SEPT_STG1_ADDR, f_size(&fp), NULL)) - { - f_close(&fp); - goto error; + fss0_sept_used = load_sept_from_ffs0(&sept_ctxt); } - f_close(&fp); - // Copy sept-secondary. - if (kb < KB_FIRMWARE_VERSION_810) + if (!fss0_sept_used) { - if (f_open(&fp, "sept/sept-secondary_00.enc", FA_READ)) - if (f_open(&fp, "sept/sept-secondary.enc", FA_READ)) // Try the deprecated version. - goto error; - } - else - { - if (f_open(&fp, "sept/sept-secondary_01.enc", FA_READ)) + // Copy sept-primary. + if (f_open(&fp, "sept/sept-primary.bin", FA_READ)) goto error; - } - if (f_read(&fp, (u8 *)SEPT_STG2_ADDR, f_size(&fp), NULL)) - { + if (f_read(&fp, (u8 *)SEPT_STG1_ADDR, f_size(&fp), NULL)) + { + f_close(&fp); + goto error; + } + f_close(&fp); + + // Copy sept-secondary. + if (kb < KB_FIRMWARE_VERSION_810) + { + if (f_open(&fp, "sept/sept-secondary_00.enc", FA_READ)) + if (f_open(&fp, "sept/sept-secondary.enc", FA_READ)) // Try the deprecated version. + goto error; + } + else + { + if (f_open(&fp, "sept/sept-secondary_01.enc", FA_READ)) + goto error; + } + + if (f_read(&fp, (u8 *)SEPT_STG2_ADDR, f_size(&fp), NULL)) + { + f_close(&fp); + goto error; + } f_close(&fp); - goto error; } - f_close(&fp); b_cfg.boot_cfg |= (BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_SEPT_RUN); diff --git a/bootloader/hos/sept.h b/bootloader/hos/sept.h index 7b44c73..8cfc8af 100644 --- a/bootloader/hos/sept.h +++ b/bootloader/hos/sept.h @@ -19,7 +19,7 @@ #include "../utils/types.h" -void check_sept(); -int reboot_to_sept(const u8 *tsec_fw, u32 kb); +void check_sept(ini_sec_t *cfg_sec); +int reboot_to_sept(const u8 *tsec_fw, u32 kb, ini_sec_t *cfg_sec); #endif diff --git a/bootloader/main.c b/bootloader/main.c index d67b22b..80dfeb5 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -529,7 +529,7 @@ void ini_list_launcher() payload_path = ini_check_payload_section(cfg_sec); if (cfg_sec && !payload_path) - check_sept(); + check_sept(cfg_sec); if (!cfg_sec) { @@ -656,7 +656,7 @@ void launch_firmware() } if (cfg_sec && !payload_path) - check_sept(); + check_sept(cfg_sec); if (!cfg_sec) { @@ -793,7 +793,7 @@ static void _auto_launch_firmware() { if (!h_cfg.sept_run) EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD; - check_sept(); + check_sept(NULL); } if (!h_cfg.sept_run) @@ -1055,7 +1055,7 @@ skip_list: } else { - check_sept(); + check_sept(cfg_sec); hos_launch(cfg_sec); EPRINTF("\nFailed to launch HOS!");