mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 19:31:12 +00:00
hos: Support pkg2 encrypted with newer mkeys
This commit is contained in:
parent
658c3c112f
commit
40afcfd686
8 changed files with 76 additions and 13 deletions
|
@ -190,7 +190,7 @@ void dump_packages12()
|
||||||
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE,
|
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE,
|
||||||
pkg2_size_aligned / NX_EMMC_BLOCKSIZE, pkg2);
|
pkg2_size_aligned / NX_EMMC_BLOCKSIZE, pkg2);
|
||||||
// Decrypt package2 and parse KIP1 blobs in INI1 section.
|
// Decrypt package2 and parse KIP1 blobs in INI1 section.
|
||||||
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(pkg2);
|
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(pkg2, kb);
|
||||||
if (!pkg2_hdr)
|
if (!pkg2_hdr)
|
||||||
{
|
{
|
||||||
gfx_printf("Pkg2 decryption failed!\n");
|
gfx_printf("Pkg2 decryption failed!\n");
|
||||||
|
|
|
@ -89,7 +89,7 @@ static const u8 master_keyseed_retail[0x10] =
|
||||||
static const u8 console_keyseed[0x10] =
|
static const u8 console_keyseed[0x10] =
|
||||||
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
||||||
|
|
||||||
static const u8 package2_keyseed[] =
|
const u8 package2_keyseed[] =
|
||||||
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
|
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
|
||||||
|
|
||||||
static const u8 master_keyseed_4xx_5xx_610[0x10] =
|
static const u8 master_keyseed_4xx_5xx_610[0x10] =
|
||||||
|
@ -544,7 +544,7 @@ DPRINTF("Generated keys\n");
|
||||||
gfx_printf("Read pkg2\n");
|
gfx_printf("Read pkg2\n");
|
||||||
|
|
||||||
// Decrypt package2 and parse KIP1 blobs in INI1 section.
|
// Decrypt package2 and parse KIP1 blobs in INI1 section.
|
||||||
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(ctxt.pkg2);
|
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(ctxt.pkg2, ctxt.pkg1_id->kb);
|
||||||
if (!pkg2_hdr)
|
if (!pkg2_hdr)
|
||||||
{
|
{
|
||||||
_hos_crit_error("Pkg2 decryption failed!");
|
_hos_crit_error("Pkg2 decryption failed!");
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hos.h"
|
||||||
#include "pkg2.h"
|
#include "pkg2.h"
|
||||||
#include "pkg2_ini_kippatch.h"
|
#include "pkg2_ini_kippatch.h"
|
||||||
|
|
||||||
|
@ -32,6 +33,8 @@
|
||||||
#include "../gfx/gfx.h"
|
#include "../gfx/gfx.h"
|
||||||
|
|
||||||
extern hekate_config h_cfg;
|
extern hekate_config h_cfg;
|
||||||
|
extern const u8 package2_keyseed[];
|
||||||
|
|
||||||
extern void *sd_file_read(const char *path, u32 *fsize);
|
extern void *sd_file_read(const char *path, u32 *fsize);
|
||||||
|
|
||||||
#ifdef KIP1_PATCH_DEBUG
|
#ifdef KIP1_PATCH_DEBUG
|
||||||
|
@ -1039,9 +1042,16 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkg2_hdr_t *pkg2_decrypt(void *data)
|
static const uint8_t mkey_keyseed_8xx[][0x10] =
|
||||||
{
|
{
|
||||||
|
{0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80} // Master key 8 encrypted with 9.
|
||||||
|
};
|
||||||
|
|
||||||
|
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb)
|
||||||
|
{
|
||||||
|
pkg2_hdr_t mkey_test;
|
||||||
u8 *pdata = (u8 *)data;
|
u8 *pdata = (u8 *)data;
|
||||||
|
u8 keyslot = 8;
|
||||||
|
|
||||||
// Skip signature.
|
// Skip signature.
|
||||||
pdata += 0x100;
|
pdata += 0x100;
|
||||||
|
@ -1051,8 +1061,27 @@ pkg2_hdr_t *pkg2_decrypt(void *data)
|
||||||
// Skip header.
|
// Skip header.
|
||||||
pdata += sizeof(pkg2_hdr_t);
|
pdata += sizeof(pkg2_hdr_t);
|
||||||
|
|
||||||
|
//! Check if we need to decrypt with newer mkeys. Valid for 8.1.0 and up.
|
||||||
|
if ((kb >= KB_FIRMWARE_VERSION_810) && (kb < KB_FIRMWARE_VERSION_MAX))
|
||||||
|
{
|
||||||
|
u8 tmp_mkey[0x10];
|
||||||
|
// Decrypt older encrypted mkey.
|
||||||
|
se_aes_crypt_ecb(12, 0, tmp_mkey, 0x10, mkey_keyseed_8xx[KB_FIRMWARE_VERSION_MAX - kb - 1], 0x10);
|
||||||
|
// Set and unwrap pkg2 key.
|
||||||
|
se_aes_key_set(9, tmp_mkey, 0x10);
|
||||||
|
se_aes_unwrap_key(9, 9, package2_keyseed);
|
||||||
|
|
||||||
|
// Decrypt header and test if it's valid.
|
||||||
|
se_aes_crypt_ctr(9, &mkey_test, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||||
|
|
||||||
|
if (mkey_test.magic == PKG2_MAGIC)
|
||||||
|
keyslot = 9;
|
||||||
|
else
|
||||||
|
se_aes_key_clear(9);
|
||||||
|
}
|
||||||
|
|
||||||
// Decrypt header.
|
// Decrypt header.
|
||||||
se_aes_crypt_ctr(8, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
se_aes_crypt_ctr(keyslot, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||||
//gfx_hexdump((u32)hdr, hdr, 0x100);
|
//gfx_hexdump((u32)hdr, hdr, 0x100);
|
||||||
|
|
||||||
if (hdr->magic != PKG2_MAGIC)
|
if (hdr->magic != PKG2_MAGIC)
|
||||||
|
@ -1064,12 +1093,15 @@ DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]);
|
||||||
if (!hdr->sec_size[i])
|
if (!hdr->sec_size[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
se_aes_crypt_ctr(8, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]);
|
se_aes_crypt_ctr(keyslot, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]);
|
||||||
//gfx_hexdump((u32)pdata, pdata, 0x100);
|
//gfx_hexdump((u32)pdata, pdata, 0x100);
|
||||||
|
|
||||||
pdata += hdr->sec_size[i];
|
pdata += hdr->sec_size[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keyslot != 8)
|
||||||
|
se_aes_key_clear(9);
|
||||||
|
|
||||||
return hdr;
|
return hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1);
|
||||||
const char* pkg2_patch_kips(link_t *info, char* patchNames);
|
const char* pkg2_patch_kips(link_t *info, char* patchNames);
|
||||||
|
|
||||||
const pkg2_kernel_id_t *pkg2_identify(u8 *hash);
|
const pkg2_kernel_id_t *pkg2_identify(u8 *hash);
|
||||||
pkg2_hdr_t *pkg2_decrypt(void *data);
|
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb);
|
||||||
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info, bool new_pkg2);
|
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info, bool new_pkg2);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -506,7 +506,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Decrypt package2 and parse KIP1 blobs in INI1 section.
|
// Decrypt package2 and parse KIP1 blobs in INI1 section.
|
||||||
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(pkg2);
|
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(pkg2, kb);
|
||||||
if (!pkg2_hdr)
|
if (!pkg2_hdr)
|
||||||
{
|
{
|
||||||
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Pkg2 decryption failed!#");
|
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Pkg2 decryption failed!#");
|
||||||
|
|
|
@ -79,7 +79,7 @@ static const u8 master_keyseed_retail[0x10] =
|
||||||
static const u8 console_keyseed[0x10] =
|
static const u8 console_keyseed[0x10] =
|
||||||
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
||||||
|
|
||||||
static const u8 package2_keyseed[] =
|
const u8 package2_keyseed[] =
|
||||||
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
|
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
|
||||||
|
|
||||||
static const u8 master_keyseed_4xx_5xx_610[0x10] =
|
static const u8 master_keyseed_4xx_5xx_610[0x10] =
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#include "../gfx/gfx.h"
|
#include "../gfx/gfx.h"
|
||||||
|
|
||||||
|
extern const u8 package2_keyseed[];
|
||||||
|
|
||||||
/*#include "util.h"
|
/*#include "util.h"
|
||||||
#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||||
#define DEBUG_PRINTING*/
|
#define DEBUG_PRINTING*/
|
||||||
|
@ -79,9 +81,16 @@ DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pkg2_hdr_t *pkg2_decrypt(void *data)
|
static const uint8_t mkey_keyseed_8xx[][0x10] =
|
||||||
{
|
{
|
||||||
|
{0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80} // Master key 8 encrypted with 9.
|
||||||
|
};
|
||||||
|
|
||||||
|
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb)
|
||||||
|
{
|
||||||
|
pkg2_hdr_t mkey_test;
|
||||||
u8 *pdata = (u8 *)data;
|
u8 *pdata = (u8 *)data;
|
||||||
|
u8 keyslot = 8;
|
||||||
|
|
||||||
// Skip signature.
|
// Skip signature.
|
||||||
pdata += 0x100;
|
pdata += 0x100;
|
||||||
|
@ -91,8 +100,27 @@ pkg2_hdr_t *pkg2_decrypt(void *data)
|
||||||
// Skip header.
|
// Skip header.
|
||||||
pdata += sizeof(pkg2_hdr_t);
|
pdata += sizeof(pkg2_hdr_t);
|
||||||
|
|
||||||
|
//! Check if we need to decrypt with newer mkeys. Valid for 8.1.0 and up.
|
||||||
|
if ((kb >= KB_FIRMWARE_VERSION_810) && (kb < KB_FIRMWARE_VERSION_MAX))
|
||||||
|
{
|
||||||
|
u8 tmp_mkey[0x10];
|
||||||
|
// Decrypt older encrypted mkey.
|
||||||
|
se_aes_crypt_ecb(12, 0, tmp_mkey, 0x10, mkey_keyseed_8xx[KB_FIRMWARE_VERSION_MAX - kb - 1], 0x10);
|
||||||
|
// Set and unwrap pkg2 key.
|
||||||
|
se_aes_key_set(9, tmp_mkey, 0x10);
|
||||||
|
se_aes_unwrap_key(9, 9, package2_keyseed);
|
||||||
|
|
||||||
|
// Decrypt header and test if it's valid.
|
||||||
|
se_aes_crypt_ctr(9, &mkey_test, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||||
|
|
||||||
|
if (mkey_test.magic == PKG2_MAGIC)
|
||||||
|
keyslot = 9;
|
||||||
|
else
|
||||||
|
se_aes_key_clear(9);
|
||||||
|
}
|
||||||
|
|
||||||
// Decrypt header.
|
// Decrypt header.
|
||||||
se_aes_crypt_ctr(8, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
se_aes_crypt_ctr(keyslot, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||||
//gfx_hexdump((u32)hdr, hdr, 0x100);
|
//gfx_hexdump((u32)hdr, hdr, 0x100);
|
||||||
|
|
||||||
if (hdr->magic != PKG2_MAGIC)
|
if (hdr->magic != PKG2_MAGIC)
|
||||||
|
@ -104,11 +132,14 @@ DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]);
|
||||||
if (!hdr->sec_size[i])
|
if (!hdr->sec_size[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
se_aes_crypt_ctr(8, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]);
|
se_aes_crypt_ctr(keyslot, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]);
|
||||||
//gfx_hexdump((u32)pdata, pdata, 0x100);
|
//gfx_hexdump((u32)pdata, pdata, 0x100);
|
||||||
|
|
||||||
pdata += hdr->sec_size[i];
|
pdata += hdr->sec_size[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keyslot != 8)
|
||||||
|
se_aes_key_clear(9);
|
||||||
|
|
||||||
return hdr;
|
return hdr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,6 @@ void pkg2_get_newkern_info(u8 *kern_data);
|
||||||
u32 pkg2_calc_kip1_size(pkg2_kip1_t *kip1);
|
u32 pkg2_calc_kip1_size(pkg2_kip1_t *kip1);
|
||||||
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2);
|
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2);
|
||||||
|
|
||||||
pkg2_hdr_t *pkg2_decrypt(void *data);
|
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue