hos: pkg1: explicitly which type pkg1 is wrongly flashed

This commit is contained in:
CTCaer 2021-10-15 16:42:39 +03:00
parent 8d3700b76b
commit 65b3b87c99
5 changed files with 67 additions and 43 deletions

View file

@ -623,35 +623,35 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock, bool i
static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
{
const u32 BOOTLOADER_SIZE = SZ_256K;
const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
const u32 BOOTLOADER_BACKUP_OFFSET = 0x140000;
const u32 HOS_KEYBLOBS_OFFSET = 0x180000;
const u32 ERISTA_PKG1_ON_MARIKO_MAGIC = 0x20014770; // For 8.0.0 Erista and up.
u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header.
u32 bootloader_offset = BOOTLOADER_MAIN_OFFSET;
ctxt->pkg1 = (void *)malloc(BOOTLOADER_SIZE);
const u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header.
u32 bootloader_offset = PKG1_BOOTLOADER_MAIN_OFFSET;
ctxt->pkg1 = (void *)malloc(PKG1_BOOTLOADER_SIZE);
try_load:
// Read package1.
emummc_storage_set_mmc_partition(EMMC_BOOT0);
emummc_storage_read(bootloader_offset / NX_EMMC_BLOCKSIZE, BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, ctxt->pkg1);
emummc_storage_read(bootloader_offset / NX_EMMC_BLOCKSIZE, PKG1_BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, ctxt->pkg1);
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1 + pk1_offset);
if (!ctxt->pkg1_id)
{
// Check if wrong pkg1 was flashed.
bool wrong_pkg1;
u32 pkg1_build_check = *(u32 *)(ctxt->pkg1 + pk1_offset + 0x10);
if (!h_cfg.t210b01) // For Erista check if start is 0 and build offset is not 0.
wrong_pkg1 = *(u32 *)ctxt->pkg1 == 0 && pkg1_build_check != 0;
else // For Mariko works for 8.0.0 Erista pkg1 and up.
wrong_pkg1 = pkg1_build_check == ERISTA_PKG1_ON_MARIKO_MAGIC;
const u32 pkg1_erista_check = ((bl_hdr_t210b01_t *)ctxt->pkg1)->entrypoint;
const u32 pkg1_mariko_check = *(u32 *)(ctxt->pkg1 + sizeof(pk1_hdr_t) * 2);
if (!h_cfg.t210b01) // For Erista check if start is 0 and entrypoint matches Mariko.
wrong_pkg1 = *(u32 *)ctxt->pkg1 == 0 && pkg1_erista_check == PKG1_MARIKO_ON_ERISTA_MAGIC;
else // For Mariko check if start is not 0 and build id. It works for 8.0.0 Erista pkg1 and up.
wrong_pkg1 = *(u32 *)ctxt->pkg1 != 0 && pkg1_mariko_check == PKG1_ERISTA_ON_MARIKO_MAGIC;
if (wrong_pkg1)
_hos_crit_error("Wrong pkg1 flashed!");
{
_hos_crit_error("Wrong pkg1 flashed:");
EPRINTFARGS("%s pkg1 on %s!",
!h_cfg.t210b01 ? "Mariko" : "Erista", !h_cfg.t210b01 ? "Erista" : "Mariko");
}
else
{
_hos_crit_error("Unknown pkg1 version.");
@ -660,10 +660,10 @@ try_load:
}
// Try backup bootloader.
if (bootloader_offset != BOOTLOADER_BACKUP_OFFSET)
if (bootloader_offset != PKG1_BOOTLOADER_BACKUP_OFFSET)
{
EPRINTF("\nTrying backup bootloader...");
bootloader_offset = BOOTLOADER_BACKUP_OFFSET;
bootloader_offset = PKG1_BOOTLOADER_BACKUP_OFFSET;
goto try_load;
}
@ -675,7 +675,7 @@ try_load:
if (ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
{
ctxt->keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
emummc_storage_read(HOS_KEYBLOBS_OFFSET / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
emummc_storage_read(PKG1_HOS_KEYBLOBS_OFFSET / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
}
return 1;

View file

@ -182,13 +182,16 @@ const pkg1_id_t *pkg1_get_latest()
const pkg1_id_t *pkg1_identify(u8 *pkg1)
{
char build_date[15];
memcpy(build_date, (char *)(pkg1 + 0x10), 14);
pk1_hdr_t *hdr = (pk1_hdr_t *)pkg1;
memcpy(build_date, hdr->timestamp, 14);
build_date[14] = 0;
gfx_printf("Found pkg1 ('%s').\n\n", build_date);
for (u32 i = 0; i < ARRAY_SIZE(_pkg1_ids); i++)
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 8))
for (int i = ARRAY_SIZE(_pkg1_ids) - 1; i >= 0; i--)
if (!memcmp(hdr->timestamp, _pkg1_ids[i].id, 8))
return &_pkg1_ids[i];
return NULL;
}

View file

@ -25,6 +25,14 @@
#define PK11_SECTION_LD 1
#define PK11_SECTION_SM 2
#define PKG1_BOOTLOADER_SIZE SZ_256K
#define PKG1_BOOTLOADER_MAIN_OFFSET 0x100000
#define PKG1_BOOTLOADER_BACKUP_OFFSET 0x140000
#define PKG1_HOS_KEYBLOBS_OFFSET 0x180000
#define PKG1_ERISTA_ON_MARIKO_MAGIC 0xE59FD00C // For 4.0.0 Erista and up.
#define PKG1_MARIKO_ON_ERISTA_MAGIC 0x40010040 // Mariko pkg1 entrypoint.
typedef struct _patch_t
{
u32 off;
@ -39,17 +47,28 @@ typedef struct _patch_t
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];
/* 0x000 */ u8 aes_mac[0x10];
/* 0x010 */ u8 rsa_sig[0x100];
/* 0x110 */ u8 salt[0x20];
/* 0x130 */ u8 sha256[0x20];
/* 0x150 */ u32 version;
/* 0x154 */ u32 size;
/* 0x158 */ u32 load_addr;
/* 0x15C */ u32 entrypoint;
/* 0x160 */ u8 rsvd[0x10];
} bl_hdr_t210b01_t;
typedef struct _pk1_hdr_t
{
/* 0x00 */ u32 si_sha256; // Secure Init.
/* 0x04 */ u32 sm_sha256; // Secure Monitor.
/* 0x08 */ u32 sl_sha256; // Secure Loader.
/* 0x0C */ u32 unk; // what's this? It's not warmboot.
/* 0x10 */ char timestamp[14];
/* 0x1E */ u8 keygen;
/* 0x1F */ u8 version;
} pk1_hdr_t;
typedef struct _pkg1_id_t
{
const char *id;

View file

@ -648,6 +648,7 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
}
currPatchset++;
}
if (emummc_patch_selected && !strncmp(_kip_id_sets[currKipIdx].name, "FS", sizeof(ki->kip1->name)))
{
emummc_patch_selected = false;
@ -715,6 +716,7 @@ pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb, bool is_exo)
if (hdr->magic != PKG2_MAGIC)
return NULL;
// Decrypt sections.
for (u32 i = 0; i < 4; i++)
{
DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]);

View file

@ -99,17 +99,17 @@ typedef struct _pkg2_kip1_sec_t
typedef struct _pkg2_kip1_t
{
u32 magic;
u8 name[12];
u64 tid;
u32 proc_cat;
u8 main_thrd_prio;
u8 def_cpu_core;
u8 res;
u8 flags;
pkg2_kip1_sec_t sections[KIP1_NUM_SECTIONS];
u32 caps[0x20];
u8 data[];
/* 0x000 */ u32 magic;
/* 0x004*/ u8 name[12];
/* 0x010 */ u64 tid;
/* 0x018 */ u32 proc_cat;
/* 0x01C */ u8 main_thrd_prio;
/* 0x01D */ u8 def_cpu_core;
/* 0x01E */ u8 res;
/* 0x01F */ u8 flags;
/* 0x020 */ pkg2_kip1_sec_t sections[KIP1_NUM_SECTIONS];
/* 0x080 */ u32 caps[0x20];
/* 0x100 */ u8 data[];
} pkg2_kip1_t;
typedef struct _pkg2_kip1_info_t