diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index 2d250e8..f4cbfc1 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -117,9 +117,14 @@ static const u8 master_keyseed_4xx[SE_KEY_128_SIZE] = static const u8 master_kekseed_620[SE_KEY_128_SIZE] = { 0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A }; -//!TODO: Update on mkey changes. -static const u8 master_kekseed_t210_max[SE_KEY_128_SIZE] = - { 0x84, 0x67, 0xB6, 0x7F, 0x13, 0x11, 0xAE, 0xE6, 0x58, 0x9B, 0x19, 0xAF, 0x13, 0x6C, 0x80, 0x7A }; // 12.1.0. +//!TODO: Update on tsec/mkey changes. +static const u8 master_kekseed_t210_tsec_v4[][SE_KEY_128_SIZE] = { + { 0xDE, 0xDC, 0xE3, 0x39, 0x30, 0x88, 0x16, 0xF8, 0xAE, 0x97, 0xAD, 0xEC, 0x64, 0x2D, 0x41, 0x41 }, // 8.1.0. + { 0x1A, 0xEC, 0x11, 0x82, 0x2B, 0x32, 0x38, 0x7A, 0x2B, 0xED, 0xBA, 0x01, 0x47, 0x7E, 0x3B, 0x67 }, // 9.0.0. + { 0x30, 0x3F, 0x02, 0x7E, 0xD8, 0x38, 0xEC, 0xD7, 0x93, 0x25, 0x34, 0xB5, 0x30, 0xEB, 0xCA, 0x7A }, // 9.1.0. + { 0x84, 0x67, 0xB6, 0x7F, 0x13, 0x11, 0xAE, 0xE6, 0x58, 0x9B, 0x19, 0xAF, 0x13, 0x6C, 0x80, 0x7A }, // 12.1.0. + { 0x68, 0x3B, 0xCA, 0x54, 0xB8, 0x6F, 0x92, 0x48, 0xC3, 0x05, 0x76, 0x87, 0x88, 0x70, 0x79, 0x23 }, // 13.0.0. +}; //!TODO: Update on mkey changes. static const u8 master_kekseed_t210b01[][SE_KEY_128_SIZE] = { @@ -130,6 +135,7 @@ static const u8 master_kekseed_t210b01[][SE_KEY_128_SIZE] = { { 0x86, 0x69, 0xF0, 0x09, 0x87, 0xC8, 0x05, 0xAE, 0xB5, 0x7B, 0x48, 0x74, 0xDE, 0x62, 0xA6, 0x13 }, // 9.0.0. { 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82 }, // 9.1.0. { 0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1 }, // 12.1.0. + { 0x52, 0x71, 0x9B, 0xDF, 0xA7, 0x8B, 0x61, 0xD8, 0xD5, 0x85, 0x11, 0xE4, 0x8E, 0x4F, 0x74, 0xC6 }, // 13.0.0. }; static const u8 console_keyseed[SE_KEY_128_SIZE] = @@ -248,7 +254,7 @@ out: } } -static void _hos_eks_save(u32 kb) +static void _hos_eks_save() { // Check if Erista based unit. if (h_cfg.t210b01) @@ -263,7 +269,7 @@ static void _hos_eks_save(u32 kb) } // If matching blob doesn't exist, create it. - if (h_cfg.eks->enabled < kb) + if (h_cfg.eks->enabled != HOS_EKS_TSEC_VER) { // Read EKS blob. u8 *mbr = calloc(512 , 1); @@ -284,7 +290,7 @@ static void _hos_eks_save(u32 kb) // Set magic and personalized info. h_cfg.eks->magic = HOS_EKS_MAGIC; - h_cfg.eks->enabled = KB_FIRMWARE_VERSION_MAX; + h_cfg.eks->enabled = HOS_EKS_TSEC_VER; h_cfg.eks->lot0 = FUSE(FUSE_OPT_LOT_CODE_0); // Copy new keys. @@ -387,8 +393,8 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock, bool i // Use HOS EKS if it exists. _hos_eks_get(); - // Use tsec keygen for old firmware or if EKS keys do not exist for newer. - if (kb <= KB_FIRMWARE_VERSION_620 || !h_cfg.eks || (h_cfg.eks && h_cfg.eks->enabled < kb)) + // Use tsec keygen for old firmware or if EKS keys does not exist for newer. + if (kb <= KB_FIRMWARE_VERSION_620 || !h_cfg.eks || (h_cfg.eks && h_cfg.eks->enabled != HOS_EKS_TSEC_VER)) use_tsec = true; if (kb <= KB_FIRMWARE_VERSION_600) @@ -451,14 +457,19 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock, bool i // For 7.0.0 and up, save EKS slot if it doesn't exist. if (use_tsec) { - _hos_eks_save(kb); + _hos_eks_save(); free(tsec_ctxt->fw); } + // Use 8.1.0 for 7.0.0 otherwise the proper one. + u32 mkey_idx = 0; + if (kb >= KB_FIRMWARE_VERSION_810) + mkey_idx = kb - KB_FIRMWARE_VERSION_810; + if (!is_exo) { // Derive Package2 key in secmon compatible way. - se_aes_unwrap_key(7, 13, master_kekseed_t210_max); + se_aes_unwrap_key(7, 13, master_kekseed_t210_tsec_v4[mkey_idx]); se_aes_unwrap_key(7, 7, master_keyseed_retail); se_aes_unwrap_key(8, 7, package2_keyseed); } @@ -472,7 +483,7 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock, bool i se_aes_unwrap_key(15, 15, console_keyseed); // Derive master kek. - se_aes_unwrap_key(13, 13, master_kekseed_t210_max); + se_aes_unwrap_key(13, 13, master_kekseed_t210_tsec_v4[mkey_idx]); // Derive device master key and master key. se_aes_unwrap_key(12, 13, master_keyseed_4xx); @@ -949,8 +960,7 @@ int hos_launch(ini_sec_t *cfg) pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(ctxt.pkg2, kb, is_exo); if (!pkg2_hdr) { - _hos_crit_error("Pkg2 decryption failed!"); - EPRINTF("Is hekate updated?"); + _hos_crit_error("Pkg2 decryption failed!\npkg1/pkg2 mismatch or old hekate!"); // Clear EKS slot, in case something went wrong with tsec keygen. hos_eks_clear(kb); diff --git a/bootloader/hos/hos.h b/bootloader/hos/hos.h index d24af8b..a74e3b4 100644 --- a/bootloader/hos/hos.h +++ b/bootloader/hos/hos.h @@ -39,10 +39,14 @@ #define KB_FIRMWARE_VERSION_900 9 #define KB_FIRMWARE_VERSION_910 10 #define KB_FIRMWARE_VERSION_1210 11 -#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_1210 //!TODO: Update on mkey changes. +#define KB_FIRMWARE_VERSION_1300 12 +#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_1300 //!TODO: Update on mkey changes. -#define HOS_PKG11_MAGIC 0x31314B50 -#define HOS_EKS_MAGIC 0x31534B45 // EKS1. +#define HOS_TSEC_VERSION 4 //! TODO: Update on TSEC Root Key changes. + +#define HOS_PKG11_MAGIC 0x31314B50 +#define HOS_EKS_MAGIC 0x31534B45 // EKS1. +#define HOS_EKS_TSEC_VER (KB_FIRMWARE_VERSION_700 + HOS_TSEC_VERSION) // Use official Mariko secmon when in stock. Needs access to TZRAM. //#define HOS_MARIKO_STOCK_SECMON diff --git a/bootloader/hos/pkg1.c b/bootloader/hos/pkg1.c index 6cf4fc6..f4ae12c 100644 --- a/bootloader/hos/pkg1.c +++ b/bootloader/hos/pkg1.c @@ -170,7 +170,8 @@ static const pkg1_id_t _pkg1_ids[] = { { "20201030110855", 10, 14, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 11.0.0 - 11.0.1. { "20210129111626", 10, 14, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 12.0.0 - 12.0.1. { "20210422145837", 10, 15, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 12.0.2 - 12.0.3. - { "20210607122020", 11, 15, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 12.1.0+ + { "20210607122020", 11, 15, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 12.1.0. + { "20210805123738", 12, 15, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 13.0.0+ }; const pkg1_id_t *pkg1_get_latest() diff --git a/bootloader/hos/pkg2.c b/bootloader/hos/pkg2.c index ec636be..cb3d74b 100644 --- a/bootloader/hos/pkg2.c +++ b/bootloader/hos/pkg2.c @@ -595,7 +595,7 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames) emummc_patch_selected = true; patchesApplied |= appliedMask; - continue; // Continue in case it's double defined. + continue; // Patching is done later. } if (currPatchset->patches == NULL) @@ -657,7 +657,7 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames) if (currKipIdx > 17) emu_cfg.fs_ver -= 2; - gfx_printf("Injecting emuMMC. FS ver: %d\n", emu_cfg.fs_ver); + gfx_printf("Injecting emuMMC. FS ID: %d\n", emu_cfg.fs_ver); if (_kipm_inject("/bootloader/sys/emummc.kipm", "FS", ki)) return "emummc"; } @@ -673,42 +673,14 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames) return NULL; } -//!TODO: Update on mkey changes. -static const u8 mkey_vector_7xx[][SE_KEY_128_SIZE] = -{ - // Master key 7 encrypted with 8. (7.0.0 with 8.1.0) - { 0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29 }, - // Master key 8 encrypted with 9. (8.1.0 with 9.0.0) - { 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 }, - // Master key 9 encrypted with 10. (9.0.0 with 9.1.0) - { 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A }, - // Master key 10 encrypted with 11. (9.1.0 with 12.1.0) - { 0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98 }, -}; - -static bool _pkg2_key_unwrap_validate(pkg2_hdr_t *tmp_test, pkg2_hdr_t *hdr, u8 src_slot, u8 *mkey, const u8 *key_seed) -{ - // Decrypt older encrypted mkey. - se_aes_crypt_ecb(src_slot, DECRYPT, mkey, SE_KEY_128_SIZE, key_seed, SE_KEY_128_SIZE); - // Set and unwrap pkg2 key. - se_aes_key_set(9, mkey, SE_KEY_128_SIZE); - se_aes_unwrap_key(9, 9, package2_keyseed); - - // Decrypt header. - se_aes_crypt_ctr(9, tmp_test, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr); - - // Return if header is valid. - return (tmp_test->magic == PKG2_MAGIC); -} +// Master key 7 encrypted with 8. (7.0.0 with 8.1.0). AES-ECB +static const u8 mkey_vector_7xx[SE_KEY_128_SIZE] = + { 0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29 }; u8 pkg2_keyslot; -bool pkg2_broken_keygen_700; pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb, bool is_exo) { - pkg2_hdr_t mkey_test; u8 *pdata = (u8 *)data; - pkg2_keyslot = 8; - pkg2_broken_keygen_700 = false; // Skip signature. pdata += 0x100; @@ -718,55 +690,24 @@ pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb, bool is_exo) // Skip header. pdata += sizeof(pkg2_hdr_t); - // Check if we need to decrypt with newer mkeys. Valid for THK for 7.0.0 and up. - se_aes_crypt_ctr(8, &mkey_test, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr); + // Set pkg2 key slot to default. If 7.0.0 it will change to 9. + pkg2_keyslot = 8; - if (mkey_test.magic == PKG2_MAGIC) - goto key_found; - - // Decrypt older pkg2 via new mkeys. - if ((kb >= KB_FIRMWARE_VERSION_700) && (kb < KB_FIRMWARE_VERSION_MAX)) + // Decrypt 7.0.0 pkg2 via 8.1.0 mkey on Erista. + if (!h_cfg.t210b01 && kb == KB_FIRMWARE_VERSION_700) { u8 tmp_mkey[SE_KEY_128_SIZE]; - u8 decr_slot = (h_cfg.t210b01 || !is_exo) ? 7 : 13; // THK mkey or T210B01 mkey. - u8 mkey_seeds_cnt = sizeof(mkey_vector_7xx) / SE_KEY_128_SIZE; - u8 mkey_seeds_idx = mkey_seeds_cnt; // Real index + 1. - u8 mkey_seeds_min_idx = mkey_seeds_cnt - (KB_FIRMWARE_VERSION_MAX - kb); - // Re-encrypt with initial pkg2 key if 7.0.0 and Erista, because of a bug in Exo2. - pkg2_broken_keygen_700 = kb == KB_FIRMWARE_VERSION_700 && decr_slot == 13; - while (mkey_seeds_cnt) - { - // Decrypt and validate mkey. - int res = _pkg2_key_unwrap_validate(&mkey_test, hdr, decr_slot, - tmp_mkey, mkey_vector_7xx[mkey_seeds_idx - 1]); + // Decrypt 7.0.0 encrypted mkey. + se_aes_crypt_ecb(!is_exo ? 7 : 13, DECRYPT, tmp_mkey, SE_KEY_128_SIZE, mkey_vector_7xx, SE_KEY_128_SIZE); - if (res) - { - pkg2_keyslot = 9; - goto key_found; - } - else - { - // Set current mkey in order to decrypt a lower mkey. - mkey_seeds_idx--; - se_aes_key_set(9, tmp_mkey, SE_KEY_128_SIZE); + // Set and unwrap pkg2 key. + se_aes_key_set(9, tmp_mkey, SE_KEY_128_SIZE); + se_aes_unwrap_key(9, 9, package2_keyseed); - decr_slot = 9; // Temp key. - - // Check if we tried last key for that pkg2 version. - // And start with a lower mkey in case mkey is older. - if (mkey_seeds_idx == mkey_seeds_min_idx) - { - mkey_seeds_cnt--; - mkey_seeds_idx = mkey_seeds_cnt; - decr_slot = (h_cfg.t210b01 || !is_exo) ? 7 : 13; // THK mkey or T210B01 mkey. - } - } - } + pkg2_keyslot = 9; } -key_found: // Decrypt header. se_aes_crypt_ctr(pkg2_keyslot, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr); //gfx_hexdump((u32)hdr, hdr, 0x100); @@ -786,9 +727,6 @@ DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]); pdata += hdr->sec_size[i]; } - if (pkg2_broken_keygen_700) - pkg2_keyslot = 8; - return hdr; } @@ -796,9 +734,13 @@ static u32 _pkg2_ini1_build(u8 *pdst, pkg2_hdr_t *hdr, link_t *kips_info, bool n { u32 ini1_size = sizeof(pkg2_ini1_t); pkg2_ini1_t *ini1 = (pkg2_ini1_t *)pdst; + + // Set initial header and magic. memset(ini1, 0, sizeof(pkg2_ini1_t)); ini1->magic = INI1_MAGIC; pdst += sizeof(pkg2_ini1_t); + + // Merge kips into INI1. LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link) { DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->size); @@ -807,8 +749,12 @@ DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->s ini1_size += ki->size; ini1->num_procs++; } + + // Align size and set it. ini1_size = ALIGN(ini1_size, 4); ini1->size = ini1_size; + + // Encrypt INI1 in its own section if old pkg2. Otherwise it gets embedded into Kernel. if (!new_pkg2) { hdr->sec_size[PKG2_SEC_INI1] = ini1_size; @@ -836,6 +782,14 @@ void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info) if (is_meso) ctxt->new_pkg2 = true; + // Set key version. For Erista 7.0.0, use 8.1.0 because of a bug in Exo2? + u8 key_ver = kb ? kb + 1 : 0; + if (pkg2_keyslot == 9) + { + key_ver = KB_FIRMWARE_VERSION_810 + 1; + pkg2_keyslot = 8; + } + // Signature. memset(pdst, 0, 0x100); pdst += 0x100; @@ -875,7 +829,7 @@ DPRINTF("%s @ %08X (%08X)\n", is_meso ? "Mesosphere": "kernel",(u32)ctxt->kernel pdst += kernel_size; DPRINTF("kernel encrypted\n"); - /// Build INI1 for old Package2. + // Build INI1 for old Package2. u32 ini1_size = 0; if (!ctxt->new_pkg2) ini1_size = _pkg2_ini1_build(pdst, hdr, kips_info, false); @@ -889,12 +843,7 @@ DPRINTF("INI1 encrypted\n"); se_calc_sha256_oneshot(&hdr->sec_sha256[0x20 * PKG2_SEC_INI1], (void *)pk2_hash_data, hdr->sec_size[PKG2_SEC_INI1]); - // Set key version. For Erista 7.0.0, use max because of a bug in Exo2? - u8 key_ver = kb ? kb + 1 : 0; - if (pkg2_broken_keygen_700) - key_ver = KB_FIRMWARE_VERSION_MAX + 1; - - //Encrypt header. + // Encrypt header. *(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size; hdr->ctr[4] = key_ver; se_aes_crypt_ctr(pkg2_keyslot, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr); diff --git a/bootloader/hos/pkg2_patches.inl b/bootloader/hos/pkg2_patches.inl index 19f6b24..e4066d5 100644 --- a/bootloader/hos/pkg2_patches.inl +++ b/bootloader/hos/pkg2_patches.inl @@ -440,10 +440,11 @@ static const pkg2_kernel_id_t _pkg2_kernel_ids[] = { "\xf1\x5e\xc8\x34\xfd\x68\xf0\xf0", _kernel_8_patchset }, // 8.0.0 - 8.1.0. Kernel only. { "\x69\x00\x39\xdf\x21\x56\x70\x6b", _kernel_9_patchset }, // 9.0.0 - 9.1.0. Kernel only. { "\xa2\xe3\xad\x1c\x98\xd8\x7a\x62", _kernel_9_patchset }, // 9.2.0. Kernel only. - { "\x21\xc1\xd7\x24\x8e\xcd\xbd\xa8", _kernel_10_patchset }, // 10.0.0. Kernel only. + { "\x21\xc1\xd7\x24\x8e\xcd\xbd\xa8", _kernel_10_patchset }, // 10.0.0 - 10.2.0. Kernel only. { "\xD5\xD0\xBA\x5D\x52\xB9\x77\x85", _kernel_11_patchset }, // 11.0.0. Kernel only. { "\xF8\x1E\xE0\x30\x3C\x7A\x08\x04", _kernel_1101_patchset },// 11.0.1. Kernel only. - { "\xA6\xD8\xFF\xF3\x67\x4A\x33\xFC", _kernel_12_patchset }, // 12.0.0. Kernel only. + { "\xA6\xD8\xFF\xF3\x67\x4A\x33\xFC", _kernel_12_patchset }, // 12.0.0 - 12.1.0. Kernel only. + //! TODO: Mesosphere is now mandatory. Missing patches: 13.0.0+ }; // All kip patch offsets are without the 0x100-sized header. @@ -698,49 +699,65 @@ static kip1_patchset_t _fs_patches_1203[] = { NULL, NULL } }; +static kip1_patch_t _fs_nogc_1300[] = +{ + { KPS(KIP_TEXT) | 0x1425D0, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" }, + { KPS(KIP_TEXT) | 0x159018, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" }, + { 0, 0, NULL, NULL } +}; + +static kip1_patchset_t _fs_patches_1300[] = +{ + { "nogc", _fs_nogc_1300 }, + { "emummc", _fs_emummc }, + { NULL, NULL } +}; + // SHA256 hashes. static kip1_id_t _kip_ids[] = { { "FS", "\xde\x9f\xdd\xa4\x08\x5d\xd5\xfe", _fs_patches_100 }, // FS 1.0.0 - { "FS", "\xfc\x3e\x80\x99\x1d\xca\x17\x96", _fs_patches_100 }, // FS 1.0.0 exfat + { "FS", "\xfc\x3e\x80\x99\x1d\xca\x17\x96", _fs_patches_100 }, // FS 1.0.0 exFAT { "FS", "\xcd\x7b\xbe\x18\xd6\x13\x0b\x28", _fs_patches_100 }, // FS 2.0.0 - { "FS", "\xe7\x66\x92\xdf\xaa\x04\x20\xe9", _fs_patches_100 }, // FS 2.0.0 exfat + { "FS", "\xe7\x66\x92\xdf\xaa\x04\x20\xe9", _fs_patches_100 }, // FS 2.0.0 exFAT { "FS", "\x0d\x70\x05\x62\x7b\x07\x76\x7c", _fs_patches_100 }, // FS 2.1.0 - { "FS", "\xdb\xd8\x5f\xca\xcc\x19\x3d\xa8", _fs_patches_100 }, // FS 2.1.0 exfat + { "FS", "\xdb\xd8\x5f\xca\xcc\x19\x3d\xa8", _fs_patches_100 }, // FS 2.1.0 exFAT { "FS", "\xa8\x6d\xa5\xe8\x7e\xf1\x09\x7b", _fs_patches_100 }, // FS 3.0.0 - { "FS", "\x98\x1c\x57\xe7\xf0\x2f\x70\xf7", _fs_patches_100 }, // FS 3.0.0 exfat + { "FS", "\x98\x1c\x57\xe7\xf0\x2f\x70\xf7", _fs_patches_100 }, // FS 3.0.0 exFAT { "FS", "\x57\x39\x7c\x06\x3f\x10\xb6\x31", _fs_patches_100 }, // FS 3.0.1 - { "FS", "\x07\x30\x99\xd7\xc6\xad\x7d\x89", _fs_patches_100 }, // FS 3.0.1 exfat + { "FS", "\x07\x30\x99\xd7\xc6\xad\x7d\x89", _fs_patches_100 }, // FS 3.0.1 exFAT { "FS", "\x06\xe9\x07\x19\x59\x5a\x01\x0c", _fs_patches_40x }, // FS 4.0.1 - { "FS", "\x54\x9b\x0f\x8d\x6f\x72\xc4\xe9", _fs_patches_40x }, // FS 4.0.1 exfat + { "FS", "\x54\x9b\x0f\x8d\x6f\x72\xc4\xe9", _fs_patches_40x }, // FS 4.0.1 exFAT { "FS", "\x80\x96\xaf\x7c\x6a\x35\xaa\x82", _fs_patches_410 }, // FS 4.1.0 - { "FS", "\x02\xd5\xab\xaa\xfd\x20\xc8\xb0", _fs_patches_410 }, // FS 4.1.0 exfat + { "FS", "\x02\xd5\xab\xaa\xfd\x20\xc8\xb0", _fs_patches_410 }, // FS 4.1.0 exFAT { "FS", "\xa6\xf2\x7a\xd9\xac\x7c\x73\xad", _fs_patches_50x }, // FS 5.0.0 - { "FS", "\xce\x3e\xcb\xa2\xf2\xf0\x62\xf5", _fs_patches_50x }, // FS 5.0.0 exfat + { "FS", "\xce\x3e\xcb\xa2\xf2\xf0\x62\xf5", _fs_patches_50x }, // FS 5.0.0 exFAT { "FS", "\x76\xf8\x74\x02\xc9\x38\x7c\x0f", _fs_patches_510 }, // FS 5.1.0 - { "FS", "\x10\xb2\xd8\x16\x05\x48\x85\x99", _fs_patches_510 }, // FS 5.1.0 exfat + { "FS", "\x10\xb2\xd8\x16\x05\x48\x85\x99", _fs_patches_510 }, // FS 5.1.0 exFAT { "FS", "\x1b\x82\xcb\x22\x18\x67\xcb\x52", _fs_patches_600 }, // FS 6.0.0-4.0 - { "FS", "\x96\x6a\xdd\x3d\x20\xb6\x27\x13", _fs_patches_600_exfat }, // FS 6.0.0-4.0 exfat + { "FS", "\x96\x6a\xdd\x3d\x20\xb6\x27\x13", _fs_patches_600_exfat }, // FS 6.0.0-4.0 exFAT { "FS", "\x3a\x57\x4d\x43\x61\x86\x19\x1d", _fs_patches_600 }, // FS 6.0.0-5.0 - { "FS", "\x33\x05\x53\xf6\xb5\xfb\x55\xc4", _fs_patches_600_exfat }, // FS 6.0.0-5.0 exfat + { "FS", "\x33\x05\x53\xf6\xb5\xfb\x55\xc4", _fs_patches_600_exfat }, // FS 6.0.0-5.0 exFAT { "FS", "\x2A\xDB\xE9\x7E\x9B\x5F\x41\x77", _fs_patches_700 }, // FS 7.0.0 - { "FS", "\x2C\xCE\x65\x9C\xEC\x53\x6A\x8E", _fs_patches_700_exfat }, // FS 7.0.0 exfat + { "FS", "\x2C\xCE\x65\x9C\xEC\x53\x6A\x8E", _fs_patches_700_exfat }, // FS 7.0.0 exFAT { "FS", "\xB2\xF5\x17\x6B\x35\x48\x36\x4D", _fs_patches_800 }, // FS 8.0.0 - { "FS", "\xDB\xD9\x41\xC0\xC5\x3C\x52\xCC", _fs_patches_800_exfat }, // FS 8.0.0 exfat + { "FS", "\xDB\xD9\x41\xC0\xC5\x3C\x52\xCC", _fs_patches_800_exfat }, // FS 8.0.0 exFAT { "FS", "\x6B\x09\xB6\x7B\x29\xC0\x20\x24", _fs_patches_800 }, // FS 8.1.0 - { "FS", "\xB4\xCA\xE1\xF2\x49\x65\xD9\x2E", _fs_patches_800_exfat }, // FS 8.1.0 exfat + { "FS", "\xB4\xCA\xE1\xF2\x49\x65\xD9\x2E", _fs_patches_800_exfat }, // FS 8.1.0 exFAT { "FS", "\x46\x87\x40\x76\x1E\x19\x3E\xB7", _fs_patches_900 }, // FS 9.0.0 - { "FS", "\x7C\x95\x13\x76\xE5\xC1\x2D\xF8", _fs_patches_900 }, // FS 9.0.0 exfat + { "FS", "\x7C\x95\x13\x76\xE5\xC1\x2D\xF8", _fs_patches_900 }, // FS 9.0.0 exFAT { "FS", "\xB5\xE7\xA6\x4C\x6F\x5C\x4F\xE3", _fs_patches_910 }, // FS 9.1.0 - { "FS", "\xF1\x96\xD1\x44\xD0\x44\x45\xB6", _fs_patches_910 }, // FS 9.1.0 exfat + { "FS", "\xF1\x96\xD1\x44\xD0\x44\x45\xB6", _fs_patches_910 }, // FS 9.1.0 exFAT { "FS", "\x3E\xEB\xD9\xB7\xBC\xD1\xB5\xE0", _fs_patches_1000 }, // FS 10.0.0 - { "FS", "\x81\x7E\xA2\xB0\xB7\x02\xC1\xF3", _fs_patches_1000 }, // FS 10.0.0 exfat + { "FS", "\x81\x7E\xA2\xB0\xB7\x02\xC1\xF3", _fs_patches_1000 }, // FS 10.0.0 exFAT { "FS", "\xA9\x52\xB6\x57\xAD\xF9\xC2\xBA", _fs_patches_1020 }, // FS 10.2.0 - { "FS", "\x16\x0D\x3E\x10\x4E\xAD\x61\x76", _fs_patches_1020 }, // FS 10.2.0 exfat + { "FS", "\x16\x0D\x3E\x10\x4E\xAD\x61\x76", _fs_patches_1020 }, // FS 10.2.0 exFAT { "FS", "\xE3\x99\x15\x6E\x84\x4E\xB0\xAA", _fs_patches_1100 }, // FS 11.0.0 - { "FS", "\x0B\xA1\x5B\xB3\x04\xB5\x05\x63", _fs_patches_1100 }, // FS 11.0.0 exfat + { "FS", "\x0B\xA1\x5B\xB3\x04\xB5\x05\x63", _fs_patches_1100 }, // FS 11.0.0 exFAT { "FS", "\xDC\x2A\x08\x49\x96\xBB\x3C\x01", _fs_patches_1200 }, // FS 12.0.0 - { "FS", "\xD5\xA5\xBF\x36\x64\x0C\x49\xEA", _fs_patches_1200 }, // FS 12.0.0 exfat + { "FS", "\xD5\xA5\xBF\x36\x64\x0C\x49\xEA", _fs_patches_1200 }, // FS 12.0.0 exFAT { "FS", "\xC8\x67\x62\xBE\x19\xA5\x1F\xA0", _fs_patches_1203 }, // FS 12.0.3 - { "FS", "\xE1\xE8\xD3\xD6\xA2\xFE\x0B\x10", _fs_patches_1203 }, // FS 12.0.3 exfat + { "FS", "\xE1\xE8\xD3\xD6\xA2\xFE\x0B\x10", _fs_patches_1203 }, // FS 12.0.3 exFAT + { "FS", "\x7D\x20\x05\x47\x17\x8A\x83\x6A", _fs_patches_1300 }, // FS 13.0.0 + { "FS", "\x51\xEB\xFA\x9C\xCF\x66\xC0\x9E", _fs_patches_1300 }, // FS 13.0.0 exFAT }; diff --git a/bootloader/hos/secmon_exo.c b/bootloader/hos/secmon_exo.c index 825e81c..3ecade6 100644 --- a/bootloader/hos/secmon_exo.c +++ b/bootloader/hos/secmon_exo.c @@ -151,7 +151,7 @@ typedef struct _atm_fatal_error_ctx void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base) { - u32 exo_fw_no = 0; + u32 exo_fw_no; u32 exo_flags = 0; bool usb3_force = false; bool user_debug = false; @@ -162,16 +162,19 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base) volatile exo_cfg_t *exo_cfg = (exo_cfg_t *)EXO_CFG_ADDR; - // Old exosphere target versioning. Use fuses for a simpler encoding. + //! TODO: Replace current HOS version decoding (as it's bound to break in the future). + + // Old exosphere target versioning. Use fuses for a simpler decoding. if (ctxt->pkg1_id->fuses <= 3 || ctxt->pkg1_id->fuses >= 10) // 1.0.0 - 3.0.0, 8.1.0+. exo_fw_no = ctxt->pkg1_id->fuses; else - exo_fw_no = ctxt->pkg1_id->fuses - 1; // 3.0.1 - 7.0.1, 8.0.0 - 8.0.1. + exo_fw_no = ctxt->pkg1_id->fuses - 1; // 3.0.1 - 7.0.1, 8.0.x. - if (!memcmp(ctxt->pkg1_id->id, "20190314172056", 8)) // 8.0.0 - 8.0.1. - exo_fw_no++; - - if (!memcmp(ctxt->pkg1_id->id, "20210129111626", 8)) // 12.0.0. + // Handle versions that change API and do not burn new fuse. + if (!memcmp(ctxt->pkg1_id->id, "20190314172056", 8) || // 8.0.x, same fuses with 7.0.1. + !memcmp(ctxt->pkg1_id->id, "20210129111626", 8) || // 12.0.0, same fuses with 11.0.0. + !memcmp(ctxt->pkg1_id->id, "20210805123730", 8) // 13.0.0, same fuses with 12.1.0. + ) exo_fw_no++; // Feed old exosphere target versioning to new. @@ -199,7 +202,7 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base) case 12: exo_fw_no = EXO_FW_VER(9, 1, 0); break; - case 13 ... 15: + case 13 ... 16: //!TODO: Update on API changes. 16: 13.0.0. exo_fw_no = EXO_FW_VER(exo_fw_no - 3, ctxt->exo_ctx.hos_revision, 0); break; } diff --git a/nyx/nyx_gui/hos/hos.c b/nyx/nyx_gui/hos/hos.c index 2979d47..616c93c 100644 --- a/nyx/nyx_gui/hos/hos.c +++ b/nyx/nyx_gui/hos/hos.c @@ -90,7 +90,7 @@ static const u8 master_kekseed_620[SE_KEY_128_SIZE] = //!TODO: Update on mkey changes. static const u8 master_kekseed_t210_max[SE_KEY_128_SIZE] = - { 0x84, 0x67, 0xB6, 0x7F, 0x13, 0x11, 0xAE, 0xE6, 0x58, 0x9B, 0x19, 0xAF, 0x13, 0x6C, 0x80, 0x7A }; // 12.1.0. + { 0x68, 0x3B, 0xCA, 0x54, 0xB8, 0x6F, 0x92, 0x48, 0xC3, 0x05, 0x76, 0x87, 0x88, 0x70, 0x79, 0x23 }; // 13.0.0. //!TODO: Update on mkey changes. static const u8 master_kekseed_t210b01[][SE_KEY_128_SIZE] = { @@ -101,6 +101,7 @@ static const u8 master_kekseed_t210b01[][SE_KEY_128_SIZE] = { { 0x86, 0x69, 0xF0, 0x09, 0x87, 0xC8, 0x05, 0xAE, 0xB5, 0x7B, 0x48, 0x74, 0xDE, 0x62, 0xA6, 0x13 }, // 9.0.0. { 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82 }, // 9.1.0. { 0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1 }, // 12.1.0. + { 0x52, 0x71, 0x9B, 0xDF, 0xA7, 0x8B, 0x61, 0xD8, 0xD5, 0x85, 0x11, 0xE4, 0x8E, 0x4F, 0x74, 0xC6 }, // 13.0.0. }; static const u8 console_keyseed[SE_KEY_128_SIZE] = @@ -126,6 +127,7 @@ static const u8 mkey_vectors[KB_FIRMWARE_VERSION_MAX + 1][SE_KEY_128_SIZE] = { { 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 }, // Mkey 08 encrypted with mkey 09. { 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A }, // Mkey 09 encrypted with mkey 10. { 0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98 }, // Mkey 10 encrypted with mkey 11. + { 0xA3, 0x24, 0x65, 0x75, 0xEA, 0xCC, 0x6E, 0x8D, 0xFB, 0x5A, 0x16, 0x50, 0x74, 0xD2, 0x15, 0x06 }, // Mkey 11 encrypted with mkey 12. }; //!TODO: Update on mkey changes. @@ -139,6 +141,7 @@ static const u8 new_console_keyseed[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSIO { 0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49 }, // 9.0.0 New Device Key Source. { 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 }, // 9.1.0 New Device Key Source. { 0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6 }, // 12.1.0 New Device Key Source. + { 0xE4, 0xF3, 0x45, 0x6F, 0x18, 0xA1, 0x89, 0xF8, 0xDA, 0x4C, 0x64, 0x75, 0x68, 0xE6, 0xBD, 0x4F }, // 13.0.0 New Device Key Source. }; //!TODO: Update on mkey changes. @@ -152,6 +155,7 @@ static const u8 new_console_kekseed[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSIO { 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED }, // 9.0.0 New Device Keygen Source. { 0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36 }, // 9.1.0 New Device Keygen Source. { 0xC2, 0x65, 0x34, 0x6E, 0xC7, 0xC6, 0x5D, 0x97, 0x3E, 0x34, 0x5C, 0x6B, 0xB3, 0x7E, 0xC6, 0xE3 }, // 12.1.0 New Device Keygen Source. + { 0x77, 0x52, 0x92, 0xF0, 0xAA, 0xE3, 0xFB, 0xE0, 0x60, 0x16, 0xB3, 0x78, 0x68, 0x53, 0xF7, 0xA8 }, // 13.0.0 New Device Keygen Source. }; static const u8 gen_keyseed[SE_KEY_128_SIZE] = @@ -224,7 +228,7 @@ out: } } -static void _hos_eks_save(u32 kb) +static void _hos_eks_save() { // Check if Erista based unit. if (h_cfg.t210b01) @@ -239,7 +243,7 @@ static void _hos_eks_save(u32 kb) } // If matching blob doesn't exist, create it. - if (h_cfg.eks->enabled < kb) + if (h_cfg.eks->enabled != HOS_EKS_TSEC_VER) { // Read EKS blob. u8 *mbr = calloc(512 , 1); @@ -260,7 +264,7 @@ static void _hos_eks_save(u32 kb) // Set magic and personalized info. h_cfg.eks->magic = HOS_EKS_MAGIC; - h_cfg.eks->enabled = KB_FIRMWARE_VERSION_MAX; + h_cfg.eks->enabled = HOS_EKS_TSEC_VER; h_cfg.eks->lot0 = FUSE(FUSE_OPT_LOT_CODE_0); // Copy new keys. @@ -352,8 +356,8 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt) // Use HOS EKS if it exists. _hos_eks_get(); - // Use tsec keygen for old firmware or if EKS keys do not exist for newer. - if (kb <= KB_FIRMWARE_VERSION_620 || !h_cfg.eks || (h_cfg.eks && h_cfg.eks->enabled < kb)) + // Use tsec keygen for old firmware or if EKS keys does not exist for newer. + if (kb <= KB_FIRMWARE_VERSION_620 || !h_cfg.eks || (h_cfg.eks && h_cfg.eks->enabled != HOS_EKS_TSEC_VER)) use_tsec = true; if (kb <= KB_FIRMWARE_VERSION_600) @@ -416,7 +420,7 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt) // For 7.0.0 and up, save EKS slot if it doesn't exist. if (use_tsec) { - _hos_eks_save(kb); + _hos_eks_save(); free(tsec_ctxt->fw); } diff --git a/nyx/nyx_gui/hos/hos.h b/nyx/nyx_gui/hos/hos.h index b81146e..82bbb14 100644 --- a/nyx/nyx_gui/hos/hos.h +++ b/nyx/nyx_gui/hos/hos.h @@ -39,10 +39,14 @@ #define KB_FIRMWARE_VERSION_900 9 #define KB_FIRMWARE_VERSION_910 10 #define KB_FIRMWARE_VERSION_1210 11 -#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_1210 +#define KB_FIRMWARE_VERSION_1300 12 +#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_1300 //!TODO: Update on mkey changes. -#define HOS_PKG11_MAGIC 0x31314B50 -#define HOS_EKS_MAGIC 0x31534B45 // EKS1. +#define HOS_TSEC_VERSION 4 //! TODO: Update on TSEC Root Key changes. + +#define HOS_PKG11_MAGIC 0x31314B50 +#define HOS_EKS_MAGIC 0x31534B45 // EKS1. +#define HOS_EKS_TSEC_VER (KB_FIRMWARE_VERSION_700 + HOS_TSEC_VERSION) typedef struct _hos_eks_mbr_t { diff --git a/nyx/nyx_gui/hos/pkg1.c b/nyx/nyx_gui/hos/pkg1.c index 29bd1e0..cfa8b78 100644 --- a/nyx/nyx_gui/hos/pkg1.c +++ b/nyx/nyx_gui/hos/pkg1.c @@ -61,7 +61,8 @@ static const pkg1_id_t _pkg1_ids[] = { { "20201030110855", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 11.0.0 - 11.0.1. { "20210129111626", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 12.0.0 - 12.0.1. { "20210422145837", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 12.0.2 - 12.0.3. - { "20210607122020", 11, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 12.1.0+ + { "20210607122020", 11, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 12.1.0. + { "20210805123738", 11, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 13.0.0+ }; const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date) diff --git a/nyx/nyx_gui/hos/pkg2.c b/nyx/nyx_gui/hos/pkg2.c index 104511d..0fb48c6 100644 --- a/nyx/nyx_gui/hos/pkg2.c +++ b/nyx/nyx_gui/hos/pkg2.c @@ -123,6 +123,8 @@ static const u8 mkey_vector_7xx[][SE_KEY_128_SIZE] = { 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A }, // Master key 10 encrypted with 11. (9.1.0 with 12.1.0) { 0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98 }, + // Master key 11 encrypted with 12. (12.1.0 with 13.0.0) + { 0xA3, 0x24, 0x65, 0x75, 0xEA, 0xCC, 0x6E, 0x8D, 0xFB, 0x5A, 0x16, 0x50, 0x74, 0xD2, 0x15, 0x06 }, }; static bool _pkg2_key_unwrap_validate(pkg2_hdr_t *tmp_test, pkg2_hdr_t *hdr, u8 src_slot, u8 *mkey, const u8 *key_seed)