hos: Support pkg2 encrypted with newer mkeys

This commit is contained in:
CTCaer 2019-09-12 23:39:47 +03:00
parent 658c3c112f
commit 40afcfd686
8 changed files with 76 additions and 13 deletions

View file

@ -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");

View file

@ -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!");

View file

@ -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;
} }

View file

@ -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

View file

@ -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!#");

View file

@ -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] =

View file

@ -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;
} }

View file

@ -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