hos: Add Mariko PK11 decryption and unpacking
This commit is contained in:
@@ -297,6 +297,7 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
|
||||
|
||||
u8 kb = 0;
|
||||
u32 bootloader_offset = BOOTLOADER_MAIN_OFFSET;
|
||||
u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header.
|
||||
u8 *pkg1 = (u8 *)malloc(BOOTLOADER_SIZE);
|
||||
sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400);
|
||||
sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0);
|
||||
@@ -305,7 +306,7 @@ try_load:
|
||||
sdmmc_storage_read(&emmc_storage, bootloader_offset / NX_EMMC_BLOCKSIZE, BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
|
||||
char *build_date = malloc(32);
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date);
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1 + pk1_offset, build_date);
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "#00DDFF Found pkg1 ('%s')#\n", build_date);
|
||||
free(build_date);
|
||||
|
||||
@@ -21,11 +21,14 @@
|
||||
|
||||
#include "hos.h"
|
||||
#include "pkg1.h"
|
||||
#include "../config.h"
|
||||
#include <gfx_utils.h>
|
||||
#include <mem/heap.h>
|
||||
#include <sec/se.h>
|
||||
#include <utils/aarch64_util.h>
|
||||
|
||||
extern hekate_config h_cfg;
|
||||
|
||||
/*
|
||||
* package1.1 header: <wb, ldr, sm>
|
||||
* package1.1 layout:
|
||||
@@ -66,17 +69,36 @@ const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date)
|
||||
}
|
||||
|
||||
for (u32 i = 0; _pkg1_ids[i].id; i++)
|
||||
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 12))
|
||||
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 8))
|
||||
return &_pkg1_ids[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1)
|
||||
int pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1)
|
||||
{
|
||||
// Decrypt package1.
|
||||
pk11_hdr_t *hdr;
|
||||
u8 *pkg11 = pkg1 + id->pkg11_off;
|
||||
u32 pkg11_size = *(u32 *)pkg11;
|
||||
se_aes_crypt_ctr(11, pkg11 + 0x20, pkg11_size, pkg11 + 0x20, pkg11_size, pkg11 + 0x10);
|
||||
|
||||
if (!h_cfg.t210b01)
|
||||
{
|
||||
hdr = (pk11_hdr_t *)(pkg11 + 0x20);
|
||||
se_aes_crypt_ctr(11, hdr, pkg11_size, hdr, pkg11_size, pkg11 + 0x10);
|
||||
}
|
||||
else
|
||||
{
|
||||
bl_hdr_t210b01_t *oem_hdr = (bl_hdr_t210b01_t *)pkg1;
|
||||
pkg1 += sizeof(bl_hdr_t210b01_t);
|
||||
hdr = (pk11_hdr_t *)(pkg1 + id->pkg11_off + 0x20);
|
||||
|
||||
// Use BEK for T210B01.
|
||||
se_aes_iv_clear(13);
|
||||
se_aes_crypt_cbc(13, 0, pkg1 + 0x20, oem_hdr->size, pkg1 + 0x20, oem_hdr->size);
|
||||
}
|
||||
|
||||
// Return if header is valid.
|
||||
return (hdr->magic == PKG1_MAGIC);
|
||||
}
|
||||
|
||||
const u8 *pkg1_unpack(void *wm_dst, void *sm_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1)
|
||||
|
||||
@@ -19,10 +19,25 @@
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define PKG1_MAGIC 0x31314B50
|
||||
|
||||
#define PK11_SECTION_WB 0
|
||||
#define PK11_SECTION_LD 1
|
||||
#define PK11_SECTION_SM 2
|
||||
|
||||
typedef struct _bl_hdr_t210b01_t
|
||||
{
|
||||
u8 aes_mac[0x10];
|
||||
u8 rsa_sig[0x100];
|
||||
u8 salt[0x20];
|
||||
u8 sha256[0x20];
|
||||
u32 version;
|
||||
u32 size;
|
||||
u32 load_addr;
|
||||
u32 entrypoint;
|
||||
u8 rsvd[0x10];
|
||||
} bl_hdr_t210b01_t;
|
||||
|
||||
typedef struct _pkg1_id_t
|
||||
{
|
||||
const char *id;
|
||||
@@ -46,7 +61,7 @@ typedef struct _pk11_hdr_t
|
||||
} pk11_hdr_t;
|
||||
|
||||
const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date);
|
||||
void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1);
|
||||
int pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1);
|
||||
const u8 *pkg1_unpack(void *wm_dst, void *sm_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user