mirror of
https://github.com/CTCaer/hekate.git
synced 2024-11-29 21:12:06 +00:00
hos: Add EKS
This commit is contained in:
parent
1d69809022
commit
c2e8d51115
11 changed files with 366 additions and 15 deletions
|
@ -45,6 +45,7 @@ void set_default_configuration()
|
||||||
h_cfg.brand = NULL;
|
h_cfg.brand = NULL;
|
||||||
h_cfg.tagline = NULL;
|
h_cfg.tagline = NULL;
|
||||||
h_cfg.errors = 0;
|
h_cfg.errors = 0;
|
||||||
|
h_cfg.eks = NULL;
|
||||||
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
||||||
h_cfg.rcm_patched = true;
|
h_cfg.rcm_patched = true;
|
||||||
h_cfg.emummc_force_disable = false;
|
h_cfg.emummc_force_disable = false;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#ifndef _CONFIG_H_
|
#ifndef _CONFIG_H_
|
||||||
#define _CONFIG_H_
|
#define _CONFIG_H_
|
||||||
|
|
||||||
|
#include "../hos/hos.h"
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
typedef struct _hekate_config
|
typedef struct _hekate_config
|
||||||
|
@ -38,6 +39,7 @@ typedef struct _hekate_config
|
||||||
bool rcm_patched;
|
bool rcm_patched;
|
||||||
u32 sbar_time_keeping;
|
u32 sbar_time_keeping;
|
||||||
u32 errors;
|
u32 errors;
|
||||||
|
hos_eks_mbr_t *eks;
|
||||||
} hekate_config;
|
} hekate_config;
|
||||||
|
|
||||||
void set_default_configuration();
|
void set_default_configuration();
|
||||||
|
|
|
@ -183,7 +183,114 @@ void _sysctr0_reset()
|
||||||
SYSCTR0(SYSCTR0_COUNTERID11) = 0;
|
SYSCTR0(SYSCTR0_COUNTERID11) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt)
|
void hos_eks_get()
|
||||||
|
{
|
||||||
|
// Check if EKS already found and parsed.
|
||||||
|
if (!h_cfg.eks)
|
||||||
|
{
|
||||||
|
u8 *mbr = calloc(512 , 1);
|
||||||
|
|
||||||
|
// Read EKS blob.
|
||||||
|
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||||
|
|
||||||
|
// Decrypt EKS blob.
|
||||||
|
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x10);
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
h_cfg.eks = eks;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(mbr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (!h_cfg.eks)
|
||||||
|
h_cfg.eks = calloc(512 , 1);
|
||||||
|
|
||||||
|
// If matching blob doesn't exist, create it.
|
||||||
|
if (!(h_cfg.eks->enabled & (1 << key_idx)))
|
||||||
|
{
|
||||||
|
// Get keys.
|
||||||
|
u8 *keys = (u8 *)calloc(0x1000, 1);
|
||||||
|
se_get_aes_keys(keys + 0x800, keys, 0x10);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Copy new keys.
|
||||||
|
memcpy(h_cfg.eks->keys[key_idx].dkg, keys + 10 * 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.
|
||||||
|
u8 *eks = calloc(512 , 1);
|
||||||
|
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||||
|
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||||
|
|
||||||
|
// Write EKS to SD.
|
||||||
|
u8 *mbr = calloc(512 , 1);
|
||||||
|
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||||
|
memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t));
|
||||||
|
sdmmc_storage_write(&sd_storage, 0, 1, mbr);
|
||||||
|
|
||||||
|
free(eks);
|
||||||
|
free(mbr);
|
||||||
|
free(keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hos_eks_clear(u32 kb)
|
||||||
|
{
|
||||||
|
if (h_cfg.eks && kb >= KB_FIRMWARE_VERSION_700)
|
||||||
|
{
|
||||||
|
// Check if Current Master key is enabled.
|
||||||
|
u8 key_idx = kb - KB_FIRMWARE_VERSION_700;
|
||||||
|
if (h_cfg.eks->enabled & (1 << key_idx))
|
||||||
|
{
|
||||||
|
// Disable current Master key version.
|
||||||
|
h_cfg.eks->enabled &= ~(1 << key_idx);
|
||||||
|
|
||||||
|
// Encrypt EKS.
|
||||||
|
u8 *eks = calloc(512 , 1);
|
||||||
|
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||||
|
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||||
|
|
||||||
|
// Write EKS to SD.
|
||||||
|
u8 *mbr = calloc(512 , 1);
|
||||||
|
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||||
|
memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t));
|
||||||
|
sdmmc_storage_write(&sd_storage, 0, 1, mbr);
|
||||||
|
|
||||||
|
free(eks);
|
||||||
|
free(mbr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt)
|
||||||
{
|
{
|
||||||
u8 tmp[0x20];
|
u8 tmp[0x20];
|
||||||
u32 retries = 0;
|
u32 retries = 0;
|
||||||
|
@ -226,7 +333,27 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kb >= KB_FIRMWARE_VERSION_700)
|
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)))
|
||||||
|
{
|
||||||
|
// Set Device keygen key to slot 10.
|
||||||
|
se_aes_key_set(10, h_cfg.eks->keys[key_idx].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_clear(8);
|
||||||
se_aes_unwrap_key(8, 12, package2_keyseed);
|
se_aes_unwrap_key(8, 12, package2_keyseed);
|
||||||
|
}
|
||||||
else if (kb == KB_FIRMWARE_VERSION_620)
|
else if (kb == KB_FIRMWARE_VERSION_620)
|
||||||
{
|
{
|
||||||
// Set TSEC key.
|
// Set TSEC key.
|
||||||
|
@ -538,7 +665,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!keygen(ctxt.keyblob, ctxt.pkg1_id->kb, &tsec_ctxt, &ctxt))
|
if (!hos_keygen(ctxt.keyblob, ctxt.pkg1_id->kb, &tsec_ctxt, &ctxt))
|
||||||
return 0;
|
return 0;
|
||||||
gfx_printf("Generated keys\n");
|
gfx_printf("Generated keys\n");
|
||||||
if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
|
if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
|
||||||
|
@ -610,9 +737,16 @@ int hos_launch(ini_sec_t *cfg)
|
||||||
{
|
{
|
||||||
_hos_crit_error("Pkg2 decryption failed!");
|
_hos_crit_error("Pkg2 decryption failed!");
|
||||||
if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
|
if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
|
||||||
|
{
|
||||||
EPRINTF("Is Sept updated?");
|
EPRINTF("Is Sept updated?");
|
||||||
|
|
||||||
|
// Clear EKS slot, in case something went wrong with sept keygen.
|
||||||
|
hos_eks_clear(ctxt.pkg1_id->kb);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
|
||||||
|
hos_eks_save(ctxt.pkg1_id->kb); // Save EKS slot if it doesn't exist.
|
||||||
|
|
||||||
LIST_INIT(kip1_info);
|
LIST_INIT(kip1_info);
|
||||||
if (!pkg2_parse_kips(&kip1_info, pkg2_hdr, &ctxt.new_pkg2))
|
if (!pkg2_parse_kips(&kip1_info, pkg2_hdr, &ctxt.new_pkg2))
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include "../config/ini.h"
|
#include "../config/ini.h"
|
||||||
#include "../sec/tsec.h"
|
#include "../sec/tsec.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#define KB_FIRMWARE_VERSION_100_200 0
|
#define KB_FIRMWARE_VERSION_100_200 0
|
||||||
#define KB_FIRMWARE_VERSION_300 1
|
#define KB_FIRMWARE_VERSION_300 1
|
||||||
#define KB_FIRMWARE_VERSION_301 2
|
#define KB_FIRMWARE_VERSION_301 2
|
||||||
|
@ -38,6 +40,35 @@
|
||||||
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_910
|
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_910
|
||||||
|
|
||||||
#define HOS_PKG11_MAGIC 0x31314B50
|
#define HOS_PKG11_MAGIC 0x31314B50
|
||||||
|
#define HOS_EKS_MAGIC 0x30534B45
|
||||||
|
|
||||||
|
typedef struct _exo_ctxt_t
|
||||||
|
{
|
||||||
|
bool no_user_exceptions;
|
||||||
|
bool user_pmu;
|
||||||
|
bool *cal0_blank;
|
||||||
|
bool *cal0_allow_writes_sys;
|
||||||
|
} 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_mbr_t
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 enabled;
|
||||||
|
u32 sbk_low[2];
|
||||||
|
hos_eks_keys_t keys[6];
|
||||||
|
u32 magic2;
|
||||||
|
u32 rsvd2[3];
|
||||||
|
} hos_eks_mbr_t;
|
||||||
|
|
||||||
|
static_assert(sizeof(hos_eks_mbr_t) < 424, "HOS EKS storage bigger than MBR!");
|
||||||
|
|
||||||
typedef struct _launch_ctxt_t
|
typedef struct _launch_ctxt_t
|
||||||
{
|
{
|
||||||
|
@ -80,7 +111,10 @@ typedef struct _merge_kip_t
|
||||||
link_t link;
|
link_t link;
|
||||||
} merge_kip_t;
|
} merge_kip_t;
|
||||||
|
|
||||||
int hos_launch(ini_sec_t *cfg);
|
void hos_eks_get();
|
||||||
int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt);
|
void hos_eks_save(u32 kb);
|
||||||
|
void hos_eks_clear(u32 kb);
|
||||||
|
int hos_launch(ini_sec_t *cfg);
|
||||||
|
int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -71,6 +71,8 @@ extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size);
|
||||||
|
|
||||||
void check_sept(ini_sec_t *cfg_sec)
|
void check_sept(ini_sec_t *cfg_sec)
|
||||||
{
|
{
|
||||||
|
hos_eks_get();
|
||||||
|
|
||||||
// Check if non-hekate payload is used for sept and restore it.
|
// Check if non-hekate payload is used for sept and restore it.
|
||||||
if (h_cfg.sept_run)
|
if (h_cfg.sept_run)
|
||||||
{
|
{
|
||||||
|
@ -112,6 +114,14 @@ void check_sept(ini_sec_t *cfg_sec)
|
||||||
|
|
||||||
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
|
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)))
|
||||||
|
{
|
||||||
|
h_cfg.sept_run = true;
|
||||||
|
EMC(EMC_SCRATCH0) |= EMC_SEPT_RUN;
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
sdmmc_storage_end(&storage);
|
sdmmc_storage_end(&storage);
|
||||||
reboot_to_sept((u8 *)pkg1 + pkg1_id->tsec_off, pkg1_id->kb, cfg_sec);
|
reboot_to_sept((u8 *)pkg1 + pkg1_id->tsec_off, pkg1_id->kb, cfg_sec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ void set_default_configuration()
|
||||||
h_cfg.autoboot = 0;
|
h_cfg.autoboot = 0;
|
||||||
h_cfg.autoboot_list = 0;
|
h_cfg.autoboot_list = 0;
|
||||||
h_cfg.bootwait = 3;
|
h_cfg.bootwait = 3;
|
||||||
h_cfg.verification = 1;
|
|
||||||
h_cfg.se_keygen_done = 0;
|
h_cfg.se_keygen_done = 0;
|
||||||
h_cfg.sbar_time_keeping = 0;
|
h_cfg.sbar_time_keeping = 0;
|
||||||
h_cfg.backlight = 100;
|
h_cfg.backlight = 100;
|
||||||
|
@ -47,6 +46,7 @@ void set_default_configuration()
|
||||||
h_cfg.brand = NULL;
|
h_cfg.brand = NULL;
|
||||||
h_cfg.tagline = NULL;
|
h_cfg.tagline = NULL;
|
||||||
h_cfg.errors = 0;
|
h_cfg.errors = 0;
|
||||||
|
h_cfg.eks = NULL;
|
||||||
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
||||||
h_cfg.rcm_patched = fuse_check_patched_rcm();
|
h_cfg.rcm_patched = fuse_check_patched_rcm();
|
||||||
h_cfg.emummc_force_disable = false;
|
h_cfg.emummc_force_disable = false;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#ifndef _CONFIG_H_
|
#ifndef _CONFIG_H_
|
||||||
#define _CONFIG_H_
|
#define _CONFIG_H_
|
||||||
|
|
||||||
|
#include "../hos/hos.h"
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
typedef struct _hekate_config
|
typedef struct _hekate_config
|
||||||
|
@ -38,6 +39,7 @@ typedef struct _hekate_config
|
||||||
bool rcm_patched;
|
bool rcm_patched;
|
||||||
u32 sbar_time_keeping;
|
u32 sbar_time_keeping;
|
||||||
u32 errors;
|
u32 errors;
|
||||||
|
hos_eks_mbr_t *eks;
|
||||||
} hekate_config;
|
} hekate_config;
|
||||||
|
|
||||||
typedef struct _nyx_config
|
typedef struct _nyx_config
|
||||||
|
|
|
@ -510,8 +510,13 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||||
lv_label_set_text(lb_desc, txt_buf);
|
lv_label_set_text(lb_desc, txt_buf);
|
||||||
manual_system_maintenance(true);
|
manual_system_maintenance(true);
|
||||||
|
|
||||||
|
// Clear EKS slot, in case something went wrong with sept keygen.
|
||||||
|
hos_eks_clear(kb);
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
else if (kb >= KB_FIRMWARE_VERSION_700)
|
||||||
|
hos_eks_save(kb); // Save EKS slot if it doesn't exist.
|
||||||
|
|
||||||
// Display info.
|
// Display info.
|
||||||
s_printf(txt_buf + strlen(txt_buf),
|
s_printf(txt_buf + strlen(txt_buf),
|
||||||
|
|
|
@ -90,7 +90,113 @@ static const u8 master_keyseed_620[0x10] =
|
||||||
static const u8 console_keyseed_4xx_5xx[0x10] =
|
static const u8 console_keyseed_4xx_5xx[0x10] =
|
||||||
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
|
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
|
||||||
|
|
||||||
int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
void hos_eks_get()
|
||||||
|
{
|
||||||
|
// Check if EKS already found and parsed.
|
||||||
|
if (!h_cfg.eks)
|
||||||
|
{
|
||||||
|
u8 *mbr = calloc(512 , 1);
|
||||||
|
|
||||||
|
// Read EKS blob.
|
||||||
|
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||||
|
|
||||||
|
// Decrypt EKS blob.
|
||||||
|
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x10);
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
h_cfg.eks = eks;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(mbr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (!h_cfg.eks)
|
||||||
|
h_cfg.eks = calloc(512 , 1);
|
||||||
|
|
||||||
|
// If matching blob doesn't exist, create it.
|
||||||
|
if (!(h_cfg.eks->enabled & (1 << key_idx)))
|
||||||
|
{
|
||||||
|
// Get keys.
|
||||||
|
u8 *keys = (u8 *)calloc(0x1000, 1);
|
||||||
|
se_get_aes_keys(keys + 0x800, keys, 0x10);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Copy new keys.
|
||||||
|
memcpy(h_cfg.eks->keys[key_idx].dkg, keys + 10 * 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.
|
||||||
|
u8 *eks = calloc(512 , 1);
|
||||||
|
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||||
|
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||||
|
|
||||||
|
// Write EKS to SD.
|
||||||
|
u8 *mbr = calloc(512 , 1);
|
||||||
|
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||||
|
memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t));
|
||||||
|
sdmmc_storage_write(&sd_storage, 0, 1, mbr);
|
||||||
|
|
||||||
|
free(eks);
|
||||||
|
free(mbr);
|
||||||
|
free(keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hos_eks_clear(u32 kb)
|
||||||
|
{
|
||||||
|
if (h_cfg.eks && kb >= KB_FIRMWARE_VERSION_700)
|
||||||
|
{
|
||||||
|
// Check if Current Master key is enabled.
|
||||||
|
u8 key_idx = kb - KB_FIRMWARE_VERSION_700;
|
||||||
|
if (h_cfg.eks->enabled & (1 << key_idx))
|
||||||
|
{
|
||||||
|
// Disable current Master key version.
|
||||||
|
h_cfg.eks->enabled &= ~(1 << key_idx);
|
||||||
|
|
||||||
|
// Encrypt EKS.
|
||||||
|
u8 *eks = calloc(512 , 1);
|
||||||
|
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||||
|
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||||
|
|
||||||
|
// Write EKS to SD.
|
||||||
|
u8 *mbr = calloc(512 , 1);
|
||||||
|
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||||
|
memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t));
|
||||||
|
sdmmc_storage_write(&sd_storage, 0, 1, mbr);
|
||||||
|
|
||||||
|
free(eks);
|
||||||
|
free(mbr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||||
{
|
{
|
||||||
u8 tmp[0x20];
|
u8 tmp[0x20];
|
||||||
u32 retries = 0;
|
u32 retries = 0;
|
||||||
|
@ -133,7 +239,27 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kb >= KB_FIRMWARE_VERSION_700)
|
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)))
|
||||||
|
{
|
||||||
|
// Set Device keygen key to slot 10.
|
||||||
|
se_aes_key_set(10, h_cfg.eks->keys[key_idx].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_clear(8);
|
||||||
se_aes_unwrap_key(8, 12, package2_keyseed);
|
se_aes_unwrap_key(8, 12, package2_keyseed);
|
||||||
|
}
|
||||||
else if (kb == KB_FIRMWARE_VERSION_620)
|
else if (kb == KB_FIRMWARE_VERSION_620)
|
||||||
{
|
{
|
||||||
// Set TSEC key.
|
// Set TSEC key.
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include "../config/ini.h"
|
#include "../config/ini.h"
|
||||||
#include "../sec/tsec.h"
|
#include "../sec/tsec.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#define KB_FIRMWARE_VERSION_100_200 0
|
#define KB_FIRMWARE_VERSION_100_200 0
|
||||||
#define KB_FIRMWARE_VERSION_300 1
|
#define KB_FIRMWARE_VERSION_300 1
|
||||||
#define KB_FIRMWARE_VERSION_301 2
|
#define KB_FIRMWARE_VERSION_301 2
|
||||||
|
@ -38,6 +40,35 @@
|
||||||
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_910
|
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_910
|
||||||
|
|
||||||
#define HOS_PKG11_MAGIC 0x31314B50
|
#define HOS_PKG11_MAGIC 0x31314B50
|
||||||
|
#define HOS_EKS_MAGIC 0x30534B45
|
||||||
|
|
||||||
|
typedef struct _exo_ctxt_t
|
||||||
|
{
|
||||||
|
bool no_user_exceptions;
|
||||||
|
bool user_pmu;
|
||||||
|
bool *cal0_blank;
|
||||||
|
bool *cal0_allow_writes_sys;
|
||||||
|
} 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_mbr_t
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 enabled;
|
||||||
|
u32 sbk_low[2];
|
||||||
|
hos_eks_keys_t keys[6];
|
||||||
|
u32 magic2;
|
||||||
|
u32 rsvd2[3];
|
||||||
|
} hos_eks_mbr_t;
|
||||||
|
|
||||||
|
static_assert(sizeof(hos_eks_mbr_t) < 424, "HOS EKS storage bigger than MBR!");
|
||||||
|
|
||||||
typedef struct _launch_ctxt_t
|
typedef struct _launch_ctxt_t
|
||||||
{
|
{
|
||||||
|
@ -53,23 +84,19 @@ typedef struct _launch_ctxt_t
|
||||||
|
|
||||||
void *pkg2;
|
void *pkg2;
|
||||||
u32 pkg2_size;
|
u32 pkg2_size;
|
||||||
|
bool new_pkg2;
|
||||||
|
|
||||||
bool new_pkg2;
|
|
||||||
void *kernel;
|
void *kernel;
|
||||||
u32 kernel_size;
|
u32 kernel_size;
|
||||||
link_t kip1_list;
|
link_t kip1_list;
|
||||||
char* kip1_patches;
|
char* kip1_patches;
|
||||||
|
|
||||||
bool svcperm;
|
|
||||||
bool debugmode;
|
|
||||||
bool stock;
|
|
||||||
bool atmosphere;
|
|
||||||
bool exo_no_user_exceptions;
|
|
||||||
bool emuMMC;
|
|
||||||
|
|
||||||
ini_sec_t *cfg;
|
ini_sec_t *cfg;
|
||||||
} launch_ctxt_t;
|
} launch_ctxt_t;
|
||||||
|
|
||||||
int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt);
|
void hos_eks_get();
|
||||||
|
void hos_eks_save(u32 kb);
|
||||||
|
void hos_eks_clear(u32 kb);
|
||||||
|
int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -70,6 +70,8 @@ extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size);
|
||||||
|
|
||||||
void check_sept()
|
void check_sept()
|
||||||
{
|
{
|
||||||
|
hos_eks_get();
|
||||||
|
|
||||||
// Check if non-hekate payload is used for sept and restore it.
|
// Check if non-hekate payload is used for sept and restore it.
|
||||||
if (h_cfg.sept_run)
|
if (h_cfg.sept_run)
|
||||||
{
|
{
|
||||||
|
@ -107,6 +109,14 @@ void check_sept()
|
||||||
|
|
||||||
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
|
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)))
|
||||||
|
{
|
||||||
|
h_cfg.sept_run = true;
|
||||||
|
EMC(EMC_SCRATCH0) |= EMC_SEPT_RUN;
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
sdmmc_storage_end(&storage);
|
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue