From d607a8830bc2e08881224dd6b96e611ec7823829 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Sun, 14 Jun 2020 13:53:21 +0300 Subject: [PATCH] hos: Support new sept/exo keyslots --- bootloader/config/config.c | 3 +- bootloader/config/config.h | 1 + bootloader/hos/hos.c | 103 +++++++++++++++++++++++++----------- bootloader/hos/pkg2.c | 4 +- nyx/nyx_gui/config/config.c | 2 +- nyx/nyx_gui/config/config.h | 2 +- nyx/nyx_gui/hos/hos.c | 31 ++++++++--- nyx/nyx_gui/hos/pkg2.c | 6 ++- 8 files changed, 105 insertions(+), 47 deletions(-) diff --git a/bootloader/config/config.c b/bootloader/config/config.c index d4cd494..d60b4b5 100644 --- a/bootloader/config/config.c +++ b/bootloader/config/config.c @@ -47,10 +47,9 @@ void set_default_configuration() h_cfg.errors = 0; h_cfg.eks = NULL; h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN; + h_cfg.aes_slots_new = false; h_cfg.rcm_patched = fuse_check_patched_rcm(); h_cfg.emummc_force_disable = false; - - sd_power_cycle_time_start = 0; } int create_config_entry() diff --git a/bootloader/config/config.h b/bootloader/config/config.h index 6b54a0e..b8a8821 100644 --- a/bootloader/config/config.h +++ b/bootloader/config/config.h @@ -35,6 +35,7 @@ typedef struct _hekate_config // Global temporary config. bool se_keygen_done; bool sept_run; + bool aes_slots_new; bool emummc_force_disable; bool rcm_patched; u32 errors; diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index 7521b02..d697331 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -43,6 +43,7 @@ #include "../storage/nx_emmc.h" #include "../storage/nx_sd.h" #include "../storage/sdmmc.h" +#include "../utils/btn.h" #include "../utils/util.h" #include "../gfx/gfx.h" @@ -272,8 +273,16 @@ void hos_eks_save(u32 kb) memcpy(h_cfg.eks->dkg, keys + 10 * 0x10, 0x10); memcpy(h_cfg.eks->dkk, keys + 15 * 0x10, 0x10); - memcpy(h_cfg.eks->keys[key_idx].mkk, keys + 12 * 0x10, 0x10); - memcpy(h_cfg.eks->keys[key_idx].fdk, keys + 13 * 0x10, 0x10); + if (!h_cfg.aes_slots_new) + { + memcpy(h_cfg.eks->keys[key_idx].mkk, keys + 12 * 0x10, 0x10); + memcpy(h_cfg.eks->keys[key_idx].fdk, keys + 13 * 0x10, 0x10); + } + else // New sept slots. + { + memcpy(h_cfg.eks->keys[key_idx].mkk, keys + 13 * 0x10, 0x10); + memcpy(h_cfg.eks->keys[key_idx].fdk, keys + 12 * 0x10, 0x10); + } // Encrypt EKS blob. u8 *eks = calloc(512 , 1); @@ -386,17 +395,29 @@ int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_c se_aes_key_set(10, h_cfg.eks->dkg, 0x10); // Set Device key to slot 15. se_aes_key_set(15, h_cfg.eks->dkk, 0x10); - // Set Master key to slot 12. - se_aes_key_set(12, h_cfg.eks->keys[key_idx].mkk, 0x10); - // Set FW Device key key to slot 13. - se_aes_key_set(13, h_cfg.eks->keys[key_idx].fdk, 0x10); - // Lock FDK. - se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG); + if (!h_cfg.aes_slots_new) + { + // Set Master key to slot 12. + se_aes_key_set(12, h_cfg.eks->keys[key_idx].mkk, 0x10); + // Set FW Device key key to slot 13. + se_aes_key_set(13, h_cfg.eks->keys[key_idx].fdk, 0x10); + // Lock FDK. + se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG); + } + else // New exosphere. + { + // Set Master key to slot 13. + se_aes_key_set(13, h_cfg.eks->keys[key_idx].mkk, 0x10); + // Set FW Device key key to slot 12. + se_aes_key_set(12, h_cfg.eks->keys[key_idx].fdk, 0x10); + // Lock FDK. + se_key_acc_ctrl(12, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG); + } } se_aes_key_clear(8); - se_aes_unwrap_key(8, 12, package2_keyseed); + se_aes_unwrap_key(8, !h_cfg.aes_slots_new ? 12 : 13, package2_keyseed); } else if (kb == KB_FIRMWARE_VERSION_620) { @@ -422,11 +443,20 @@ int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_c se_aes_unwrap_key(15, 15, console_keyseed); se_aes_unwrap_key(13, 13, master_keyseed_620); - se_aes_unwrap_key(12, 13, master_keyseed_retail); - se_aes_unwrap_key(14, 13, master_keyseed_4xx_5xx_610); + + if (!h_cfg.aes_slots_new) + { + se_aes_unwrap_key(14, 13, master_keyseed_4xx_5xx_610); + se_aes_unwrap_key(12, 13, master_keyseed_retail); + } + else // New exosphere. + { + se_aes_unwrap_key(12, 13, master_keyseed_4xx_5xx_610); + se_aes_unwrap_key(13, 13, master_keyseed_retail); + } // Package2 key. - se_aes_unwrap_key(8, 12, package2_keyseed); + se_aes_unwrap_key(8, !h_cfg.aes_slots_new ? 12 : 13, package2_keyseed); h_cfg.se_keygen_done = 1; } @@ -465,32 +495,42 @@ int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_c se_aes_crypt_block_ecb(12, 0, tmp, master_keyseed_retail); - switch (kb) + if (!h_cfg.aes_slots_new) + { + switch (kb) + { + case KB_FIRMWARE_VERSION_100_200: + case KB_FIRMWARE_VERSION_300: + case KB_FIRMWARE_VERSION_301: + se_aes_unwrap_key(13, 15, console_keyseed); + se_aes_unwrap_key(12, 12, master_keyseed_retail); + break; + case KB_FIRMWARE_VERSION_400: + se_aes_unwrap_key(13, 15, console_keyseed_4xx_5xx); + se_aes_unwrap_key(15, 15, console_keyseed); + se_aes_unwrap_key(14, 12, master_keyseed_4xx_5xx_610); + se_aes_unwrap_key(12, 12, master_keyseed_retail); + break; + case KB_FIRMWARE_VERSION_500: + case KB_FIRMWARE_VERSION_600: + se_aes_unwrap_key(10, 15, console_keyseed_4xx_5xx); + se_aes_unwrap_key(15, 15, console_keyseed); + se_aes_unwrap_key(14, 12, master_keyseed_4xx_5xx_610); + se_aes_unwrap_key(12, 12, master_keyseed_retail); + break; + } + } + else // New exosphere. { - case KB_FIRMWARE_VERSION_100_200: - case KB_FIRMWARE_VERSION_300: - case KB_FIRMWARE_VERSION_301: - se_aes_unwrap_key(13, 15, console_keyseed); - se_aes_unwrap_key(12, 12, master_keyseed_retail); - break; - case KB_FIRMWARE_VERSION_400: - se_aes_unwrap_key(13, 15, console_keyseed_4xx_5xx); - se_aes_unwrap_key(15, 15, console_keyseed); - se_aes_unwrap_key(14, 12, master_keyseed_4xx_5xx_610); - se_aes_unwrap_key(12, 12, master_keyseed_retail); - break; - case KB_FIRMWARE_VERSION_500: - case KB_FIRMWARE_VERSION_600: se_aes_unwrap_key(10, 15, console_keyseed_4xx_5xx); se_aes_unwrap_key(15, 15, console_keyseed); - se_aes_unwrap_key(14, 12, master_keyseed_4xx_5xx_610); - se_aes_unwrap_key(12, 12, master_keyseed_retail); - break; + se_aes_unwrap_key(13, 12, master_keyseed_retail); + se_aes_unwrap_key(12, 12, master_keyseed_4xx_5xx_610); } // Package2 key. se_key_acc_ctrl(8, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG); - se_aes_unwrap_key(8, 12, package2_keyseed); + se_aes_unwrap_key(8, !h_cfg.aes_slots_new ? 12 : 13, package2_keyseed); } return 1; @@ -989,5 +1029,6 @@ int hos_launch(ini_sec_t *cfg) error: sdmmc_storage_end(&emmc_storage); + h_cfg.aes_slots_new = false; return 0; } diff --git a/bootloader/hos/pkg2.c b/bootloader/hos/pkg2.c index 4723bd3..d192c2a 100644 --- a/bootloader/hos/pkg2.c +++ b/bootloader/hos/pkg2.c @@ -1296,7 +1296,7 @@ pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb) if ((kb >= KB_FIRMWARE_VERSION_810) && (kb < KB_FIRMWARE_VERSION_MAX)) { u8 tmp_mkey[0x10]; - u8 decr_slot = 12; // Sept mkey. + u8 decr_slot = !h_cfg.aes_slots_new ? 12 : 13; // Sept mkey. u8 mkey_seeds_cnt = sizeof(mkey_vector_8xx) / 0x10; u8 mkey_seeds_idx = mkey_seeds_cnt; // Real index + 1. u8 mkey_seeds_min_idx = mkey_seeds_cnt - (KB_FIRMWARE_VERSION_MAX - kb); @@ -1327,7 +1327,7 @@ pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb) { mkey_seeds_cnt--; mkey_seeds_idx = mkey_seeds_cnt; - decr_slot = 12; // Sept mkey. + decr_slot = !h_cfg.aes_slots_new ? 12 : 13; // Sept mkey. } // Out of keys. pkg2 is latest or process failed. diff --git a/nyx/nyx_gui/config/config.c b/nyx/nyx_gui/config/config.c index 494ccc2..b442788 100644 --- a/nyx/nyx_gui/config/config.c +++ b/nyx/nyx_gui/config/config.c @@ -38,7 +38,6 @@ void set_default_configuration() h_cfg.autoboot_list = 0; h_cfg.bootwait = 3; h_cfg.se_keygen_done = 0; - h_cfg.sbar_time_keeping = 0; h_cfg.backlight = 100; h_cfg.autohosoff = 0; h_cfg.autonogc = 1; @@ -48,6 +47,7 @@ void set_default_configuration() h_cfg.errors = 0; h_cfg.eks = NULL; h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN; + h_cfg.aes_slots_new = false; h_cfg.rcm_patched = fuse_check_patched_rcm(); h_cfg.emummc_force_disable = false; diff --git a/nyx/nyx_gui/config/config.h b/nyx/nyx_gui/config/config.h index 61b3acd..2510110 100644 --- a/nyx/nyx_gui/config/config.h +++ b/nyx/nyx_gui/config/config.h @@ -35,9 +35,9 @@ typedef struct _hekate_config // Global temporary config. bool se_keygen_done; bool sept_run; + bool aes_slots_new; bool emummc_force_disable; bool rcm_patched; - u32 sbar_time_keeping; u32 errors; hos_eks_mbr_t *eks; } hekate_config; diff --git a/nyx/nyx_gui/hos/hos.c b/nyx/nyx_gui/hos/hos.c index 2fa133c..834a15b 100644 --- a/nyx/nyx_gui/hos/hos.c +++ b/nyx/nyx_gui/hos/hos.c @@ -181,8 +181,16 @@ void hos_eks_save(u32 kb) memcpy(h_cfg.eks->dkg, keys + 10 * 0x10, 0x10); memcpy(h_cfg.eks->dkk, keys + 15 * 0x10, 0x10); - memcpy(h_cfg.eks->keys[key_idx].mkk, keys + 12 * 0x10, 0x10); - memcpy(h_cfg.eks->keys[key_idx].fdk, keys + 13 * 0x10, 0x10); + if (!h_cfg.aes_slots_new) + { + memcpy(h_cfg.eks->keys[key_idx].mkk, keys + 12 * 0x10, 0x10); + memcpy(h_cfg.eks->keys[key_idx].fdk, keys + 13 * 0x10, 0x10); + } + else // New sept slots. + { + memcpy(h_cfg.eks->keys[key_idx].mkk, keys + 13 * 0x10, 0x10); + memcpy(h_cfg.eks->keys[key_idx].fdk, keys + 12 * 0x10, 0x10); + } // Encrypt EKS blob. u8 *eks = calloc(512 , 1); @@ -242,7 +250,7 @@ out: int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt) { - u8 tmp[0x20]; + u8 tmp[0x30]; u32 retries = 0; if (kb > KB_FIRMWARE_VERSION_MAX) @@ -300,9 +308,11 @@ int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt) // Set Device key to slot 15. se_aes_key_set(15, h_cfg.eks->dkk, 0x10); } + else + h_cfg.aes_slots_new = se_key_acc_ctrl_get(12) == 0x6A; se_aes_key_clear(8); - se_aes_unwrap_key(8, 12, package2_keyseed); + se_aes_unwrap_key(8, !h_cfg.aes_slots_new ? 12 : 13, package2_keyseed); } else if (kb == KB_FIRMWARE_VERSION_620) { @@ -311,11 +321,16 @@ int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt) // Set TSEC root key. se_aes_key_set(13, tmp + 0x10, 0x10); + // Decrypt keyblob and set keyslots + se_aes_crypt_block_ecb(12, 0, tmp + 0x20, keyblob_keyseeds[0]); + se_aes_unwrap_key(15, 14, tmp + 0x20); + se_aes_unwrap_key(10, 15, console_keyseed_4xx_5xx); + se_aes_unwrap_key(15, 15, console_keyseed); + // Package2 key. - se_aes_key_set(8, tmp + 0x10, 0x10); - se_aes_unwrap_key(8, 8, master_keyseed_620); - se_aes_unwrap_key(8, 8, master_keyseed_retail); - se_aes_unwrap_key(8, 8, package2_keyseed); + se_aes_unwrap_key(8, 13, master_keyseed_620); + se_aes_unwrap_key(9, 8, master_keyseed_retail); + se_aes_unwrap_key(8, 9, package2_keyseed); } else { diff --git a/nyx/nyx_gui/hos/pkg2.c b/nyx/nyx_gui/hos/pkg2.c index fe5cb9c..ac9ed6b 100644 --- a/nyx/nyx_gui/hos/pkg2.c +++ b/nyx/nyx_gui/hos/pkg2.c @@ -20,6 +20,7 @@ #include "pkg2.h" #include "hos.h" +#include "../config/config.h" #include "../libs/fatfs/ff.h" #include "../utils/aarch64_util.h" #include "../mem/heap.h" @@ -28,6 +29,7 @@ #include "../gfx/gfx.h" +extern hekate_config h_cfg; extern const u8 package2_keyseed[]; u32 pkg2_newkern_ini1_val; @@ -158,7 +160,7 @@ pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb) if ((kb >= KB_FIRMWARE_VERSION_810) && (kb < KB_FIRMWARE_VERSION_MAX)) { u8 tmp_mkey[0x10]; - u8 decr_slot = 12; // Sept mkey. + u8 decr_slot = !h_cfg.aes_slots_new ? 12 : 13; // Sept mkey. u8 mkey_seeds_cnt = sizeof(mkey_vector_8xx) / 0x10; u8 mkey_seeds_idx = mkey_seeds_cnt; // Real index + 1. u8 mkey_seeds_min_idx = mkey_seeds_cnt - (KB_FIRMWARE_VERSION_MAX - kb); @@ -189,7 +191,7 @@ pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb) { mkey_seeds_cnt--; mkey_seeds_idx = mkey_seeds_cnt; - decr_slot = 12; // Sept mkey. + decr_slot = !h_cfg.aes_slots_new ? 12 : 13; // Sept mkey. } // Out of keys. pkg2 is latest or process failed.