From 92d013dd65e279869c3a7fe9e3b0aa0d5044d047 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Sun, 14 Jun 2020 13:42:48 +0300 Subject: [PATCH] eks: Upgrade to new version and support BIS keys --- bootloader/hos/hos.c | 74 ++++++++++++++++++++--------------------- bootloader/hos/hos.h | 21 ++++++++---- bootloader/hos/sept.c | 8 +++-- nyx/nyx_gui/hos/hos.c | 75 +++++++++++++++++++----------------------- nyx/nyx_gui/hos/hos.h | 21 ++++++++---- nyx/nyx_gui/hos/sept.c | 8 +++-- 6 files changed, 107 insertions(+), 100 deletions(-) diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index f712efb..6102dc8 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -183,24 +183,16 @@ void _sysctr0_reset() bool hos_eks_rw_try(u8 *buf, bool write) { - mbr_t *mbr = (mbr_t *)buf; for (u32 i = 0; i < 3; i++) { if (!write) { - if (sdmmc_storage_read(&sd_storage, 0, 1, mbr)) - { - if (mbr->partitions[0].status != 0xFF && - mbr->partitions[0].start_sct && - mbr->partitions[0].size_sct) - return true; - else - return false; - } + if (sdmmc_storage_read(&sd_storage, 0, 1, buf)) + return true; } else { - if (sdmmc_storage_write(&sd_storage, 0, 1, mbr)) + if (sdmmc_storage_write(&sd_storage, 0, 1, buf)) return true; } } @@ -219,15 +211,12 @@ void hos_eks_get() goto out; // Decrypt EKS blob. - hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x10); + hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x60); se_aes_crypt_ecb(14, 0, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t)); // Check if valid and for this unit. - if (eks->enabled && - eks->magic == HOS_EKS_MAGIC && - eks->magic2 == HOS_EKS_MAGIC && - eks->sbk_low[0] == FUSE(FUSE_PRIVATE_KEY0) && - eks->sbk_low[1] == FUSE(FUSE_PRIVATE_KEY1)) + if (eks->magic == HOS_EKS_MAGIC && + eks->sbk_low == FUSE(FUSE_PRIVATE_KEY0)) { h_cfg.eks = eks; return; @@ -242,10 +231,9 @@ void hos_eks_save(u32 kb) { if (kb >= KB_FIRMWARE_VERSION_700) { - // Only 6 Master keys for now. - u8 key_idx = kb - KB_FIRMWARE_VERSION_700; - if (key_idx > 5) - return; + u32 key_idx = 0; + if (kb >= KB_FIRMWARE_VERSION_810) + key_idx = 1; bool new_eks = false; if (!h_cfg.eks) @@ -255,7 +243,8 @@ void hos_eks_save(u32 kb) } // If matching blob doesn't exist, create it. - if (!(h_cfg.eks->enabled & (1 << key_idx))) + bool update_eks = key_idx ? (h_cfg.eks->enabled[key_idx] < kb) : !h_cfg.eks->enabled[0]; + if (update_eks) { // Read EKS blob. u8 *mbr = calloc(512 , 1); @@ -276,16 +265,15 @@ void hos_eks_save(u32 kb) // Set magic and personalized info. h_cfg.eks->magic = HOS_EKS_MAGIC; - h_cfg.eks->magic2 = HOS_EKS_MAGIC; - h_cfg.eks->enabled |= 1 << key_idx; - h_cfg.eks->sbk_low[0] = FUSE(FUSE_PRIVATE_KEY0); - h_cfg.eks->sbk_low[1] = FUSE(FUSE_PRIVATE_KEY1); + h_cfg.eks->enabled[key_idx] = kb; + h_cfg.eks->sbk_low = FUSE(FUSE_PRIVATE_KEY0); // Copy new keys. - memcpy(h_cfg.eks->keys[key_idx].dkg, keys + 10 * 0x10, 0x10); + 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); - memcpy(h_cfg.eks->keys[key_idx].dkk, keys + 15 * 0x10, 0x10); // Encrypt EKS blob. u8 *eks = calloc(512 , 1); @@ -293,8 +281,7 @@ void hos_eks_save(u32 kb) se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t)); // Write EKS blob to SD. - memset(mbr, 0, 0x10); - memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t)); + memcpy(mbr + 0x60, eks, sizeof(hos_eks_mbr_t)); hos_eks_rw_try(mbr, true); @@ -310,9 +297,12 @@ void hos_eks_clear(u32 kb) { if (h_cfg.eks && kb >= KB_FIRMWARE_VERSION_700) { + u32 key_idx = 0; + if (kb >= KB_FIRMWARE_VERSION_810) + key_idx = 1; + // Check if Current Master key is enabled. - u8 key_idx = kb - KB_FIRMWARE_VERSION_700; - if (h_cfg.eks->enabled & (1 << key_idx)) + if (h_cfg.eks->enabled[key_idx]) { // Read EKS blob. u8 *mbr = calloc(512 , 1); @@ -320,7 +310,7 @@ void hos_eks_clear(u32 kb) goto out; // Disable current Master key version. - h_cfg.eks->enabled &= ~(1 << key_idx); + h_cfg.eks->enabled[key_idx] = 0; // Encrypt EKS blob. u8 *eks = calloc(512 , 1); @@ -328,9 +318,12 @@ void hos_eks_clear(u32 kb) se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t)); // Write EKS blob to SD. - memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t)); + memcpy(mbr + 0x60, eks, sizeof(hos_eks_mbr_t)); hos_eks_rw_try(mbr, true); + EMC(EMC_SCRATCH0) &= ~EMC_SEPT_RUN; + h_cfg.sept_run = false; + free(eks); out: free(mbr); @@ -383,17 +376,20 @@ int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_c if (kb >= KB_FIRMWARE_VERSION_700) { // Use HOS EKS if it exists. - u8 key_idx = kb - KB_FIRMWARE_VERSION_700; - if (h_cfg.eks && (h_cfg.eks->enabled & (1 << key_idx))) + u32 key_idx = 0; + if (kb >= KB_FIRMWARE_VERSION_810) + key_idx = 1; + + if (h_cfg.eks && h_cfg.eks->enabled[key_idx] >= kb) { // Set Device keygen key to slot 10. - se_aes_key_set(10, h_cfg.eks->keys[key_idx].dkg, 0x10); + 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); - // Set Device key to slot 15. - se_aes_key_set(15, h_cfg.eks->keys[key_idx].dkk, 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); diff --git a/bootloader/hos/hos.h b/bootloader/hos/hos.h index f759725..82e8381 100644 --- a/bootloader/hos/hos.h +++ b/bootloader/hos/hos.h @@ -52,23 +52,30 @@ typedef struct _exo_ctxt_t typedef struct _hos_eks_keys_t { - u8 dkg[0x10]; u8 mkk[0x10]; u8 fdk[0x10]; - u8 dkk[0x10]; } hos_eks_keys_t; +typedef struct _hos_eks_bis_keys_t +{ + u8 crypt[0x10]; + u8 tweak[0x10]; +} hos_eks_bis_keys_t; + typedef struct _hos_eks_mbr_t { u32 magic; - u32 enabled; - u32 sbk_low[2]; + u8 enabled[6]; + u8 enabled_bis; + u8 rsvd; + u32 sbk_low; + u8 dkg[0x10]; + u8 dkk[0x10]; hos_eks_keys_t keys[6]; - u32 magic2; - u32 rsvd2[3]; + hos_eks_bis_keys_t bis_keys[3]; } hos_eks_mbr_t; -static_assert(sizeof(hos_eks_mbr_t) == 416, "HOS EKS storage bigger than MBR!"); +static_assert(sizeof(hos_eks_mbr_t) == 336, "HOS EKS size is wrong!"); typedef struct _launch_ctxt_t { diff --git a/bootloader/hos/sept.c b/bootloader/hos/sept.c index cbc6434..949fd08 100644 --- a/bootloader/hos/sept.c +++ b/bootloader/hos/sept.c @@ -113,11 +113,13 @@ void check_sept(ini_sec_t *cfg_sec) if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run) { - u8 key_idx = pkg1_id->kb - KB_FIRMWARE_VERSION_700; - if (h_cfg.eks && (h_cfg.eks->enabled & (1 << key_idx))) + u32 key_idx = 0; + if (pkg1_id->kb >= KB_FIRMWARE_VERSION_810) + key_idx = 1; + + if (h_cfg.eks && h_cfg.eks->enabled[key_idx] >= pkg1_id->kb) { h_cfg.sept_run = true; - EMC(EMC_SCRATCH0) |= EMC_SEPT_RUN; goto out_free; } diff --git a/nyx/nyx_gui/hos/hos.c b/nyx/nyx_gui/hos/hos.c index 5e22089..2fa133c 100644 --- a/nyx/nyx_gui/hos/hos.c +++ b/nyx/nyx_gui/hos/hos.c @@ -92,24 +92,16 @@ static const u8 console_keyseed_4xx_5xx[0x10] = bool hos_eks_rw_try(u8 *buf, bool write) { - mbr_t *mbr = (mbr_t *)buf; for (u32 i = 0; i < 3; i++) { if (!write) { - if (sdmmc_storage_read(&sd_storage, 0, 1, mbr)) - { - if (mbr->partitions[0].status != 0xFF && - mbr->partitions[0].start_sct && - mbr->partitions[0].size_sct) - return true; - else - return false; - } + if (sdmmc_storage_read(&sd_storage, 0, 1, buf)) + return true; } else { - if (sdmmc_storage_write(&sd_storage, 0, 1, mbr)) + if (sdmmc_storage_write(&sd_storage, 0, 1, buf)) return true; } } @@ -128,15 +120,12 @@ void hos_eks_get() goto out; // Decrypt EKS blob. - hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x10); + hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x60); se_aes_crypt_ecb(14, 0, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t)); // Check if valid and for this unit. - if (eks->enabled && - eks->magic == HOS_EKS_MAGIC && - eks->magic2 == HOS_EKS_MAGIC && - eks->sbk_low[0] == FUSE(FUSE_PRIVATE_KEY0) && - eks->sbk_low[1] == FUSE(FUSE_PRIVATE_KEY1)) + if (eks->magic == HOS_EKS_MAGIC && + eks->sbk_low == FUSE(FUSE_PRIVATE_KEY0)) { h_cfg.eks = eks; return; @@ -151,10 +140,9 @@ void hos_eks_save(u32 kb) { if (kb >= KB_FIRMWARE_VERSION_700) { - // Only 6 Master keys for now. - u8 key_idx = kb - KB_FIRMWARE_VERSION_700; - if (key_idx > 5) - return; + u32 key_idx = 0; + if (kb >= KB_FIRMWARE_VERSION_810) + key_idx = 1; bool new_eks = false; if (!h_cfg.eks) @@ -164,7 +152,8 @@ void hos_eks_save(u32 kb) } // If matching blob doesn't exist, create it. - if (!(h_cfg.eks->enabled & (1 << key_idx))) + bool update_eks = key_idx ? (h_cfg.eks->enabled[key_idx] < kb) : !h_cfg.eks->enabled[0]; + if (update_eks) { // Read EKS blob. u8 *mbr = calloc(512 , 1); @@ -185,16 +174,15 @@ void hos_eks_save(u32 kb) // Set magic and personalized info. h_cfg.eks->magic = HOS_EKS_MAGIC; - h_cfg.eks->magic2 = HOS_EKS_MAGIC; - h_cfg.eks->enabled |= 1 << key_idx; - h_cfg.eks->sbk_low[0] = FUSE(FUSE_PRIVATE_KEY0); - h_cfg.eks->sbk_low[1] = FUSE(FUSE_PRIVATE_KEY1); + h_cfg.eks->enabled[key_idx] = kb; + h_cfg.eks->sbk_low = FUSE(FUSE_PRIVATE_KEY0); // Copy new keys. - memcpy(h_cfg.eks->keys[key_idx].dkg, keys + 10 * 0x10, 0x10); + 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); - memcpy(h_cfg.eks->keys[key_idx].dkk, keys + 15 * 0x10, 0x10); // Encrypt EKS blob. u8 *eks = calloc(512 , 1); @@ -202,8 +190,7 @@ void hos_eks_save(u32 kb) se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t)); // Write EKS blob to SD. - memset(mbr, 0, 0x10); - memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t)); + memcpy(mbr + 0x60, eks, sizeof(hos_eks_mbr_t)); hos_eks_rw_try(mbr, true); @@ -219,9 +206,12 @@ void hos_eks_clear(u32 kb) { if (h_cfg.eks && kb >= KB_FIRMWARE_VERSION_700) { + u32 key_idx = 0; + if (kb >= KB_FIRMWARE_VERSION_810) + key_idx = 1; + // Check if Current Master key is enabled. - u8 key_idx = kb - KB_FIRMWARE_VERSION_700; - if (h_cfg.eks->enabled & (1 << key_idx)) + if (h_cfg.eks->enabled[key_idx]) { // Read EKS blob. u8 *mbr = calloc(512 , 1); @@ -229,7 +219,7 @@ void hos_eks_clear(u32 kb) goto out; // Disable current Master key version. - h_cfg.eks->enabled &= ~(1 << key_idx); + h_cfg.eks->enabled[key_idx] = 0; // Encrypt EKS blob. u8 *eks = calloc(512 , 1); @@ -237,9 +227,12 @@ void hos_eks_clear(u32 kb) se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t)); // Write EKS blob to SD. - memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t)); + memcpy(mbr + 0x60, eks, sizeof(hos_eks_mbr_t)); hos_eks_rw_try(mbr, true); + EMC(EMC_SCRATCH0) &= ~EMC_SEPT_RUN; + h_cfg.sept_run = false; + free(eks); out: free(mbr); @@ -292,20 +285,20 @@ int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt) if (kb >= KB_FIRMWARE_VERSION_700) { // Use HOS EKS if it exists. - u8 key_idx = kb - KB_FIRMWARE_VERSION_700; - if (h_cfg.eks && (h_cfg.eks->enabled & (1 << key_idx))) + u32 key_idx = 0; + if (kb >= KB_FIRMWARE_VERSION_810) + key_idx = 1; + + if (h_cfg.eks && h_cfg.eks->enabled[key_idx] >= kb) { // Set Device keygen key to slot 10. - se_aes_key_set(10, h_cfg.eks->keys[key_idx].dkg, 0x10); + se_aes_key_set(10, h_cfg.eks->dkg, 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); // Set Device key to slot 15. - se_aes_key_set(15, h_cfg.eks->keys[key_idx].dkk, 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); + se_aes_key_set(15, h_cfg.eks->dkk, 0x10); } se_aes_key_clear(8); diff --git a/nyx/nyx_gui/hos/hos.h b/nyx/nyx_gui/hos/hos.h index 3a4dce9..6d8e802 100644 --- a/nyx/nyx_gui/hos/hos.h +++ b/nyx/nyx_gui/hos/hos.h @@ -44,23 +44,30 @@ typedef struct _hos_eks_keys_t { - u8 dkg[0x10]; u8 mkk[0x10]; u8 fdk[0x10]; - u8 dkk[0x10]; } hos_eks_keys_t; +typedef struct _hos_eks_bis_keys_t +{ + u8 crypt[0x10]; + u8 tweak[0x10]; +} hos_eks_bis_keys_t; + typedef struct _hos_eks_mbr_t { u32 magic; - u32 enabled; - u32 sbk_low[2]; + u8 enabled[6]; + u8 enabled_bis; + u8 rsvd; + u32 sbk_low; + u8 dkg[0x10]; + u8 dkk[0x10]; hos_eks_keys_t keys[6]; - u32 magic2; - u32 rsvd2[3]; + hos_eks_bis_keys_t bis_keys[3]; } hos_eks_mbr_t; -static_assert(sizeof(hos_eks_mbr_t) == 416, "HOS EKS storage bigger than MBR!"); +static_assert(sizeof(hos_eks_mbr_t) == 336, "HOS EKS size is wrong!"); typedef struct _launch_ctxt_t { diff --git a/nyx/nyx_gui/hos/sept.c b/nyx/nyx_gui/hos/sept.c index d429033..1f91fc5 100644 --- a/nyx/nyx_gui/hos/sept.c +++ b/nyx/nyx_gui/hos/sept.c @@ -109,11 +109,13 @@ void check_sept() if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run) { - u8 key_idx = pkg1_id->kb - KB_FIRMWARE_VERSION_700; - if (h_cfg.eks && (h_cfg.eks->enabled & (1 << key_idx))) + u32 key_idx = 0; + if (pkg1_id->kb >= KB_FIRMWARE_VERSION_810) + key_idx = 1; + + if (h_cfg.eks && h_cfg.eks->enabled[key_idx] >= pkg1_id->kb) { h_cfg.sept_run = true; - EMC(EMC_SCRATCH0) |= EMC_SEPT_RUN; goto out_free; }