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.
This commit is contained in:
CTCaer 2019-12-16 00:53:22 +02:00
parent 9b2d906648
commit 8584493c7f
8 changed files with 120 additions and 61 deletions

View file

@ -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. |

View file

@ -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;

View file

@ -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;
}
}
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;
}

View file

@ -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

View file

@ -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

View file

@ -17,6 +17,7 @@
#include <string.h>
#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);

View file

@ -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

View file

@ -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!");