From 9489eca4879cc37baef93796ea62935996bf02c5 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Sun, 14 Jun 2020 14:00:07 +0300 Subject: [PATCH] hos: Add secmon/warmboot base selection --- bootloader/hos/hos.c | 17 +++++++++++------ bootloader/hos/pkg1.c | 5 +++++ bootloader/hos/pkg1.h | 1 + bootloader/hos/secmon_exo.c | 6 +++--- bootloader/hos/secmon_exo.h | 2 +- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index 74ff7cb..91c1f6e 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -648,6 +648,8 @@ static bool _get_fs_exfat_compatible(link_t *info, bool *fs_is_510) int hos_launch(ini_sec_t *cfg) { u8 kb; + u32 secmon_base; + u32 warmboot_base; launch_ctxt_t ctxt; bool exo_new = false; tsec_ctxt_t tsec_ctxt; @@ -727,6 +729,9 @@ int hos_launch(ini_sec_t *cfg) // Check if secmon is new exosphere. if (ctxt.secmon) exo_new = !memcmp((void *)((u8 *)ctxt.secmon + ctxt.secmon_size - 4), "LENY", 4); + const pkg1_id_t *pk1_latest = pkg1_get_latest(); + secmon_base = exo_new ? pk1_latest->secmon_base : ctxt.pkg1_id->secmon_base; + warmboot_base = exo_new ? pk1_latest->warmboot_base : ctxt.pkg1_id->warmboot_base; h_cfg.aes_slots_new = exo_new; // Generate keys. @@ -735,7 +740,7 @@ int hos_launch(ini_sec_t *cfg) tsec_ctxt.fw = (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off; tsec_ctxt.pkg1 = ctxt.pkg1; tsec_ctxt.pkg11_off = ctxt.pkg1_id->pkg11_off; - tsec_ctxt.secmon_base = ctxt.pkg1_id->secmon_base; + tsec_ctxt.secmon_base = secmon_base; if (kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run) { @@ -770,7 +775,7 @@ int hos_launch(ini_sec_t *cfg) // Replace 'warmboot.bin' if requested. if (ctxt.warmboot) - memcpy((void *)ctxt.pkg1_id->warmboot_base, ctxt.warmboot, ctxt.warmboot_size); + memcpy((void *)warmboot_base, ctxt.warmboot, ctxt.warmboot_size); else { if (kb >= KB_FIRMWARE_VERSION_700) @@ -786,11 +791,11 @@ int hos_launch(ini_sec_t *cfg) } // Set warmboot address in PMC if required. if (ctxt.pkg1_id->set_warmboot) - PMC(APBDEV_PMC_SCRATCH1) = ctxt.pkg1_id->warmboot_base; + PMC(APBDEV_PMC_SCRATCH1) = warmboot_base; // Replace 'SecureMonitor' if requested. if (ctxt.secmon) - memcpy((void *)ctxt.pkg1_id->secmon_base, ctxt.secmon, ctxt.secmon_size); + memcpy((void *)secmon_base, ctxt.secmon, ctxt.secmon_size); else if (ctxt.pkg1_id->secmon_patchset) { // Else we patch it to allow for an unsigned package2 and patched kernel. @@ -983,7 +988,7 @@ int hos_launch(ini_sec_t *cfg) // Config Exosphère if booting full Atmosphère. if (ctxt.atmosphere && ctxt.secmon) - config_exosphere(&ctxt); + config_exosphere(&ctxt, warmboot_base); // Unmount SD card and eMMC. sd_end(); @@ -1031,7 +1036,7 @@ int hos_launch(ini_sec_t *cfg) if (smmu_is_used()) smmu_exit(); else - ccplex_boot_cpu0(ctxt.pkg1_id->secmon_base); + ccplex_boot_cpu0(secmon_base); while (!secmon_mailbox->out) ; // A usleep(1) only works when in IRAM or with a trained DRAM. diff --git a/bootloader/hos/pkg1.c b/bootloader/hos/pkg1.c index e9ff0dc..f1b0088 100644 --- a/bootloader/hos/pkg1.c +++ b/bootloader/hos/pkg1.c @@ -133,6 +133,11 @@ static const pkg1_id_t _pkg1_ids[] = { { NULL } //End. }; +const pkg1_id_t *pkg1_get_latest() +{ + return &_pkg1_ids[sizeof(_pkg1_ids) / sizeof(pkg1_id_t) - 2]; +} + const pkg1_id_t *pkg1_identify(u8 *pkg1) { char build_date[15]; diff --git a/bootloader/hos/pkg1.h b/bootloader/hos/pkg1.h index 455d746..957eef0 100644 --- a/bootloader/hos/pkg1.h +++ b/bootloader/hos/pkg1.h @@ -57,6 +57,7 @@ typedef struct _pk11_hdr_t u32 sm_off; } pk11_hdr_t; +const pkg1_id_t *pkg1_get_latest(); const pkg1_id_t *pkg1_identify(u8 *pkg1); void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1); void pkg1_unpack(void *warmboot_dst, void *secmon_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1); diff --git a/bootloader/hos/secmon_exo.c b/bootloader/hos/secmon_exo.c index def3c8c..4571d99 100644 --- a/bootloader/hos/secmon_exo.c +++ b/bootloader/hos/secmon_exo.c @@ -141,7 +141,7 @@ typedef struct _atm_fatal_error_ctx #define EXO_FW_VER(mj, mn, rv) (((mj) << 24) | ((mn) << 16) | ((rv) << 8)) -void config_exosphere(launch_ctxt_t *ctxt) +void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base) { u32 exoFwNo = 0; u32 exoFlags = 0; @@ -284,7 +284,7 @@ void config_exosphere(launch_ctxt_t *ctxt) exo_cfg->flags = exoFlags; // If warmboot is lp0fw, add in RSA modulus. - volatile wb_cfg_t *wb_cfg = (wb_cfg_t *)(ctxt->pkg1_id->warmboot_base + ATM_WB_HEADER_OFF); + volatile wb_cfg_t *wb_cfg = (wb_cfg_t *)(warmboot_base + ATM_WB_HEADER_OFF); if (wb_cfg->magic == ATM_WB_MAGIC) { @@ -302,7 +302,7 @@ void config_exosphere(launch_ctxt_t *ctxt) else rsa_mod[0x10] = 0x37; - memcpy((void *)(ctxt->pkg1_id->warmboot_base + 0x10), rsa_mod + 0x10, 0x100); + memcpy((void *)(warmboot_base + 0x10), rsa_mod + 0x10, 0x100); } if (emu_cfg.enabled && !h_cfg.emummc_force_disable) diff --git a/bootloader/hos/secmon_exo.h b/bootloader/hos/secmon_exo.h index 2ff0ee3..c5ef600 100644 --- a/bootloader/hos/secmon_exo.h +++ b/bootloader/hos/secmon_exo.h @@ -19,7 +19,7 @@ #include "../utils/types.h" -void config_exosphere(launch_ctxt_t *ctxt); +void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base); void secmon_exo_check_panic(); #endif