Add support for 9.0.0, new Sept, and master_key_09

This commit is contained in:
shchmue 2019-09-14 21:37:43 -06:00
parent ffc4c4281f
commit 34890f0025
7 changed files with 418 additions and 341 deletions

View file

@ -1,47 +1,48 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk * Copyright (c) 2018 st4rk
* Copyright (c) 2018-2019 CTCaer * Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation. * version 2, as published by the Free Software Foundation.
* *
* This program is distributed in the hope it will be useful, but WITHOUT * This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. * more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h> #include <string.h>
#include "pkg1.h" #include "pkg1.h"
#include "../sec/se.h" #include "../sec/se.h"
static const pkg1_id_t _pkg1_ids[] = { static const pkg1_id_t _pkg1_ids[] = {
{ "20161121183008", 0 }, //1.0.0 { "20161121183008", 0 }, //1.0.0
{ "20170210155124", 0 }, //2.0.0 - 2.3.0 { "20170210155124", 0 }, //2.0.0 - 2.3.0
{ "20170519101410", 1 }, //3.0.0 { "20170519101410", 1 }, //3.0.0
{ "20170710161758", 2 }, //3.0.1 - 3.0.2 { "20170710161758", 2 }, //3.0.1 - 3.0.2
{ "20170921172629", 3 }, //4.0.0 - 4.1.0 { "20170921172629", 3 }, //4.0.0 - 4.1.0
{ "20180220163747", 4 }, //5.0.0 - 5.1.0 { "20180220163747", 4 }, //5.0.0 - 5.1.0
{ "20180802162753", 5 }, //6.0.0 - 6.1.0 { "20180802162753", 5 }, //6.0.0 - 6.1.0
{ "20181107105733", 6 }, //6.2.0 { "20181107105733", 6 }, //6.2.0
{ "20181218175730", 7 }, //7.0.0 { "20181218175730", 7 }, //7.0.0
{ "20190208150037", 7 }, //7.0.1 { "20190208150037", 7 }, //7.0.1
{ "20190314172056", 7 }, //8.0.0 { "20190314172056", 7 }, //8.0.0
{ "20190531152432", 8 }, //8.1.0 { "20190531152432", 8 }, //8.1.0
{ NULL } //End. { "20190809135709", 9 }, //9.0.0
}; { NULL } //End.
};
const pkg1_id_t *pkg1_identify(u8 *pkg1)
{ const pkg1_id_t *pkg1_identify(u8 *pkg1)
for (u32 i = 0; _pkg1_ids[i].id; i++) {
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 12)) for (u32 i = 0; _pkg1_ids[i].id; i++)
return &_pkg1_ids[i]; if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 12))
return NULL; return &_pkg1_ids[i];
} return NULL;
}

View file

@ -39,14 +39,25 @@ static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
return size; return size;
} }
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2) void pkg2_get_newkern_info(u8 *kern_data)
{
u32 info_op = *(u32 *)(kern_data + PKG2_NEWKERN_GET_INI1);
pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + PKG2_NEWKERN_GET_INI1; // Parse ADR and PC.
pkg2_newkern_ini1_start = *(u32 *)(kern_data + pkg2_newkern_ini1_val);
pkg2_newkern_ini1_end = *(u32 *)(kern_data + pkg2_newkern_ini1_val + 0x8);
}
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
{ {
u8 *ptr; u8 *ptr;
// Check for new pkg2 type. // Check for new pkg2 type.
if (!pkg2->sec_size[PKG2_SEC_INI1]) if (!pkg2->sec_size[PKG2_SEC_INI1])
{ {
u32 kernel_ini1_off = *(u32 *)(pkg2->data + PKG2_NEWKERN_INI1_START); pkg2_get_newkern_info(pkg2->data);
ptr = pkg2->data + kernel_ini1_off;
ptr = pkg2->data + pkg2_newkern_ini1_start;
*new_pkg2 = true;
} }
else else
ptr = pkg2->data + pkg2->sec_size[PKG2_SEC_KERNEL]; ptr = pkg2->data + pkg2->sec_size[PKG2_SEC_KERNEL];

View file

@ -26,7 +26,11 @@
#define PKG2_SEC_KERNEL 0 #define PKG2_SEC_KERNEL 0
#define PKG2_SEC_INI1 1 #define PKG2_SEC_INI1 1
#define PKG2_NEWKERN_INI1_START 0x168 #define PKG2_NEWKERN_GET_INI1 0x44
u32 pkg2_newkern_ini1_val;
u32 pkg2_newkern_ini1_start;
u32 pkg2_newkern_ini1_end;
typedef struct _pkg2_hdr_t typedef struct _pkg2_hdr_t
{ {
@ -83,7 +87,7 @@ typedef struct _pkg2_kip1_info_t
link_t link; link_t link;
} pkg2_kip1_info_t; } pkg2_kip1_info_t;
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2); void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2);
int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp); int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp);
pkg2_hdr_t *pkg2_decrypt(void *data); pkg2_hdr_t *pkg2_decrypt(void *data);

View file

@ -1,137 +1,145 @@
/* /*
* Copyright (c) 2019 CTCaer * Copyright (c) 2019 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation. * version 2, as published by the Free Software Foundation.
* *
* This program is distributed in the hope it will be useful, but WITHOUT * This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. * more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h> #include <string.h>
#include "sept.h" #include "sept.h"
#include "../gfx/di.h" #include "../gfx/di.h"
#include "../libs/fatfs/ff.h" #include "../libs/fatfs/ff.h"
#include "../mem/heap.h" #include "../mem/heap.h"
#include "../soc/pmc.h" #include "../soc/hw_init.h"
#include "../soc/t210.h" #include "../soc/pmc.h"
#include "../storage/nx_emmc.h" #include "../soc/t210.h"
#include "../storage/sdmmc.h" #include "../storage/nx_emmc.h"
#include "../utils/btn.h" #include "../storage/sdmmc.h"
#include "../utils/types.h" #include "../utils/btn.h"
#include "../utils/types.h"
#include "../gfx/gfx.h"
#include "../gfx/gfx.h"
#define PATCHED_RELOC_SZ 0x94
#define PATCHED_RELOC_SZ 0x94
#define WB_RST_ADDR 0x40010ED0
#define WB_RST_SIZE 0x30 #define WB_RST_ADDR 0x40010ED0
#define WB_RST_SIZE 0x30
u8 warmboot_reboot[] = {
0x14, 0x00, 0x9F, 0xE5, // LDR R0, =0x7000E450 u8 warmboot_reboot[] = {
0x01, 0x10, 0xB0, 0xE3, // MOVS R1, #1 0x14, 0x00, 0x9F, 0xE5, // LDR R0, =0x7000E450
0x00, 0x10, 0x80, 0xE5, // STR R1, [R0] 0x01, 0x10, 0xB0, 0xE3, // MOVS R1, #1
0x0C, 0x00, 0x9F, 0xE5, // LDR R0, =0x7000E400 0x00, 0x10, 0x80, 0xE5, // STR R1, [R0]
0x10, 0x10, 0xB0, 0xE3, // MOVS R1, #0x10 0x0C, 0x00, 0x9F, 0xE5, // LDR R0, =0x7000E400
0x00, 0x10, 0x80, 0xE5, // STR R1, [R0] 0x10, 0x10, 0xB0, 0xE3, // MOVS R1, #0x10
0xFE, 0xFF, 0xFF, 0xEA, // LOOP 0x00, 0x10, 0x80, 0xE5, // STR R1, [R0]
0x50, 0xE4, 0x00, 0x70, // #0x7000E450 0xFE, 0xFF, 0xFF, 0xEA, // LOOP
0x00, 0xE4, 0x00, 0x70 // #0x7000E400 0x50, 0xE4, 0x00, 0x70, // #0x7000E450
}; 0x00, 0xE4, 0x00, 0x70 // #0x7000E400
};
#define SEPT_PRI_ADDR 0x4003F000
#define SEPT_PRI_ADDR 0x4003F000
#define SEPT_PK1T_ADDR 0xC0400000
#define SEPT_PK1T_STACK 0x40008000 #define SEPT_PK1T_ADDR 0xC0400000
#define SEPT_TCSZ_ADDR (SEPT_PK1T_ADDR - 0x4) #define SEPT_PK1T_STACK 0x40008000
#define SEPT_STG1_ADDR (SEPT_PK1T_ADDR + 0x2E100) #define SEPT_TCSZ_ADDR (SEPT_PK1T_ADDR - 0x4)
#define SEPT_STG2_ADDR (SEPT_PK1T_ADDR + 0x60E0) #define SEPT_STG1_ADDR (SEPT_PK1T_ADDR + 0x2E100)
#define SEPT_PKG_SZ (0x2F100 + WB_RST_SIZE) #define SEPT_STG2_ADDR (SEPT_PK1T_ADDR + 0x60E0)
#define SEPT_PKG_SZ (0x2F100 + WB_RST_SIZE)
extern boot_cfg_t b_cfg;
extern void sd_unmount(); extern boot_cfg_t b_cfg;
extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size); extern void sd_unmount();
extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size);
int reboot_to_sept(const u8 *tsec_fw, const u32 tsec_size, const u32 kb)
{ int reboot_to_sept(const u8 *tsec_fw, const u32 tsec_size, const u32 kb)
FIL fp; {
FIL fp;
// Copy warmboot reboot code and TSEC fw.
memcpy((u8 *)(SEPT_PK1T_ADDR - WB_RST_SIZE), (u8 *)warmboot_reboot, sizeof(warmboot_reboot)); // Copy warmboot reboot code and TSEC fw.
memcpy((void *)SEPT_PK1T_ADDR, tsec_fw, tsec_size); memcpy((u8 *)(SEPT_PK1T_ADDR - WB_RST_SIZE), (u8 *)warmboot_reboot, sizeof(warmboot_reboot));
*(vu32 *)SEPT_TCSZ_ADDR = tsec_size; memcpy((void *)SEPT_PK1T_ADDR, tsec_fw, tsec_size);
*(vu32 *)SEPT_TCSZ_ADDR = tsec_size;
// Copy sept-primary.
if (f_open(&fp, "sd:/sept/sept-primary.bin", FA_READ)) // Copy sept-primary.
goto error; if (f_open(&fp, "sd:/sept/sept-primary.bin", FA_READ))
goto error;
if (f_read(&fp, (u8 *)SEPT_STG1_ADDR, f_size(&fp), NULL))
{ if (f_read(&fp, (u8 *)SEPT_STG1_ADDR, f_size(&fp), NULL))
f_close(&fp); {
goto error; f_close(&fp);
} goto error;
f_close(&fp); }
f_close(&fp);
// Copy sept-secondary.
if ((kb == 7) && f_open(&fp, "sd:/sept/sept-secondary.enc", FA_READ) && f_open(&fp, "sd:/sept/sept-secondary_00.enc", FA_READ)) // Copy sept-secondary.
goto error; if (kb < KB_FIRMWARE_VERSION_810)
else if ((kb == 8) && f_open(&fp, "sd:/sept/sept-secondary_01.enc", FA_READ)) {
goto error; if (f_open(&fp, "sd:/sept/sept-secondary_00.enc", FA_READ))
if (f_open(&fp, "sd:/sept/sept-secondary.enc", FA_READ)) // Try the deprecated version.
if (f_read(&fp, (u8 *)SEPT_STG2_ADDR, f_size(&fp), NULL)) goto error;
{ }
f_close(&fp); else
goto error; {
} if (f_open(&fp, "sd:/sept/sept-secondary_01.enc", FA_READ))
f_close(&fp); goto error;
}
// Save auto boot config to sept payload, if any.
boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t)); if (f_read(&fp, (u8 *)SEPT_STG2_ADDR, f_size(&fp), NULL))
memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t)); {
f_close(&fp);
tmp_cfg->boot_cfg |= BOOT_CFG_SEPT_RUN; goto error;
}
if (f_open(&fp, "sd:/sept/payload.bin", FA_READ | FA_WRITE)) f_close(&fp);
goto error;
// Save auto boot config to sept payload, if any.
f_lseek(&fp, PATCHED_RELOC_SZ); boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL); memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t));
f_close(&fp); tmp_cfg->boot_cfg |= BOOT_CFG_SEPT_RUN;
sd_unmount(); if (f_open(&fp, "sd:/sept/payload.bin", FA_READ | FA_WRITE))
gfx_printf("\n%kPress Power or Vol +/-\n%k to Reboot to Sept...", COLOR_BLUE, COLOR_VIOLET); goto error;
btn_wait();
f_lseek(&fp, PATCHED_RELOC_SZ);
u32 pk1t_sept = SEPT_PK1T_ADDR - (ALIGN(PATCHED_RELOC_SZ, 0x10) + WB_RST_SIZE); f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
void (*sept)() = (void *)pk1t_sept; f_close(&fp);
reloc_patcher(WB_RST_ADDR, pk1t_sept, SEPT_PKG_SZ); sd_unmount();
gfx_printf("\n%kPress Power or Vol +/-\n%k to Reboot to Sept...", COLOR_BLUE, COLOR_VIOLET);
// Patch SDRAM init to perform an SVC immediately after second write. btn_wait();
PMC(APBDEV_PMC_SCRATCH45) = 0x2E38DFFF;
PMC(APBDEV_PMC_SCRATCH46) = 0x6001DC28; u32 pk1t_sept = SEPT_PK1T_ADDR - (ALIGN(PATCHED_RELOC_SZ, 0x10) + WB_RST_SIZE);
// Set SVC handler to jump to sept-primary in IRAM.
PMC(APBDEV_PMC_SCRATCH33) = SEPT_PRI_ADDR; void (*sept)() = (void *)pk1t_sept;
PMC(APBDEV_PMC_SCRATCH40) = 0x6000F208;
reloc_patcher(WB_RST_ADDR, pk1t_sept, SEPT_PKG_SZ);
display_end();
// Patch SDRAM init to perform an SVC immediately after second write.
(*sept)(); PMC(APBDEV_PMC_SCRATCH45) = 0x2E38DFFF;
PMC(APBDEV_PMC_SCRATCH46) = 0x6001DC28;
error: // Set SVC handler to jump to sept-primary in IRAM.
EPRINTF("Sept files not found in sd:/sept!\nPlace appropriate files and try again."); PMC(APBDEV_PMC_SCRATCH33) = SEPT_PRI_ADDR;
display_backlight_brightness(100, 1000); PMC(APBDEV_PMC_SCRATCH40) = 0x6000F208;
btn_wait(); reconfig_hw_workaround(false, 0);
return 0; (*sept)();
error:
EPRINTF("\nSept files not found in sd:/sept!\nPlace appropriate files and try again.");
display_backlight_brightness(100, 1000);
btn_wait();
return 0;
} }

View file

@ -1,141 +1,143 @@
/* /*
* Copyright (c) 2019 shchmue * Copyright (c) 2019 shchmue
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation. * version 2, as published by the Free Software Foundation.
* *
* This program is distributed in the hope it will be useful, but WITHOUT * This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. * more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
static const u8 zeros[0x10] = {0}; static const u8 zeros[0x10] = {0};
static const u8 keyblob_key_source[][0x10] = { static const u8 keyblob_key_source[][0x10] = {
{0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3}, //1.0.0 {0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3}, //1.0.0
{0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC}, //3.0.0 {0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC}, //3.0.0
{0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B}, //3.0.1 {0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B}, //3.0.1
{0x2D, 0x1F, 0x48, 0x80, 0xED, 0xEC, 0xED, 0x3E, 0x3C, 0xF2, 0x48, 0xB5, 0x65, 0x7D, 0xF7, 0xBE}, //4.0.0 {0x2D, 0x1F, 0x48, 0x80, 0xED, 0xEC, 0xED, 0x3E, 0x3C, 0xF2, 0x48, 0xB5, 0x65, 0x7D, 0xF7, 0xBE}, //4.0.0
{0xBB, 0x5A, 0x01, 0xF9, 0x88, 0xAF, 0xF5, 0xFC, 0x6C, 0xFF, 0x07, 0x9E, 0x13, 0x3C, 0x39, 0x80}, //5.0.0 {0xBB, 0x5A, 0x01, 0xF9, 0x88, 0xAF, 0xF5, 0xFC, 0x6C, 0xFF, 0x07, 0x9E, 0x13, 0x3C, 0x39, 0x80}, //5.0.0
{0xD8, 0xCC, 0xE1, 0x26, 0x6A, 0x35, 0x3F, 0xCC, 0x20, 0xF3, 0x2D, 0x3B, 0x51, 0x7D, 0xE9, 0xC0} //6.0.0 {0xD8, 0xCC, 0xE1, 0x26, 0x6A, 0x35, 0x3F, 0xCC, 0x20, 0xF3, 0x2D, 0x3B, 0x51, 0x7D, 0xE9, 0xC0} //6.0.0
}; };
static const u8 master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_600][0x10] = { static const u8 master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_600][0x10] = {
{0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, //6.2.0 {0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, //6.2.0
{0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, //7.0.0 {0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, //7.0.0
{0xDE, 0xDC, 0xE3, 0x39, 0x30, 0x88, 0x16, 0xF8, 0xAE, 0x97, 0xAD, 0xEC, 0x64, 0x2D, 0x41, 0x41}, //8.1.0 {0xDE, 0xDC, 0xE3, 0x39, 0x30, 0x88, 0x16, 0xF8, 0xAE, 0x97, 0xAD, 0xEC, 0x64, 0x2D, 0x41, 0x41}, //8.1.0
}; {0x1A, 0xEC, 0x11, 0x82, 0x2B, 0x32, 0x38, 0x7A, 0x2B, 0xED, 0xBA, 0x01, 0x47, 0x7E, 0x3B, 0x67}, //9.0.0
};
static const u8 mkey_vectors[KB_FIRMWARE_VERSION_MAX+1][0x10] =
{ static const u8 mkey_vectors[KB_FIRMWARE_VERSION_MAX+1][0x10] =
{0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D}, /* Zeroes encrypted with Master Key 00. */ {
{0x29, 0x4C, 0x04, 0xC8, 0xEB, 0x10, 0xED, 0x9D, 0x51, 0x64, 0x97, 0xFB, 0xF3, 0x4D, 0x50, 0xDD}, /* Master key 00 encrypted with Master key 01. */ {0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D}, /* Zeroes encrypted with Master Key 00. */
{0xDE, 0xCF, 0xEB, 0xEB, 0x10, 0xAE, 0x74, 0xD8, 0xAD, 0x7C, 0xF4, 0x9E, 0x62, 0xE0, 0xE8, 0x72}, /* Master key 01 encrypted with Master key 02. */ {0x29, 0x4C, 0x04, 0xC8, 0xEB, 0x10, 0xED, 0x9D, 0x51, 0x64, 0x97, 0xFB, 0xF3, 0x4D, 0x50, 0xDD}, /* Master key 00 encrypted with Master key 01. */
{0x0A, 0x0D, 0xDF, 0x34, 0x22, 0x06, 0x6C, 0xA4, 0xE6, 0xB1, 0xEC, 0x71, 0x85, 0xCA, 0x4E, 0x07}, /* Master key 02 encrypted with Master key 03. */ {0xDE, 0xCF, 0xEB, 0xEB, 0x10, 0xAE, 0x74, 0xD8, 0xAD, 0x7C, 0xF4, 0x9E, 0x62, 0xE0, 0xE8, 0x72}, /* Master key 01 encrypted with Master key 02. */
{0x6E, 0x7D, 0x2D, 0xC3, 0x0F, 0x59, 0xC8, 0xFA, 0x87, 0xA8, 0x2E, 0xD5, 0x89, 0x5E, 0xF3, 0xE9}, /* Master key 03 encrypted with Master key 04. */ {0x0A, 0x0D, 0xDF, 0x34, 0x22, 0x06, 0x6C, 0xA4, 0xE6, 0xB1, 0xEC, 0x71, 0x85, 0xCA, 0x4E, 0x07}, /* Master key 02 encrypted with Master key 03. */
{0xEB, 0xF5, 0x6F, 0x83, 0x61, 0x9E, 0xF8, 0xFA, 0xE0, 0x87, 0xD7, 0xA1, 0x4E, 0x25, 0x36, 0xEE}, /* Master key 04 encrypted with Master key 05. */ {0x6E, 0x7D, 0x2D, 0xC3, 0x0F, 0x59, 0xC8, 0xFA, 0x87, 0xA8, 0x2E, 0xD5, 0x89, 0x5E, 0xF3, 0xE9}, /* Master key 03 encrypted with Master key 04. */
{0x1E, 0x1E, 0x22, 0xC0, 0x5A, 0x33, 0x3C, 0xB9, 0x0B, 0xA9, 0x03, 0x04, 0xBA, 0xDB, 0x07, 0x57}, /* Master key 05 encrypted with Master key 06. */ {0xEB, 0xF5, 0x6F, 0x83, 0x61, 0x9E, 0xF8, 0xFA, 0xE0, 0x87, 0xD7, 0xA1, 0x4E, 0x25, 0x36, 0xEE}, /* Master key 04 encrypted with Master key 05. */
{0xA4, 0xD4, 0x52, 0x6F, 0xD1, 0xE4, 0x36, 0xAA, 0x9F, 0xCB, 0x61, 0x27, 0x1C, 0x67, 0x65, 0x1F}, /* Master key 06 encrypted with Master key 07. */ {0x1E, 0x1E, 0x22, 0xC0, 0x5A, 0x33, 0x3C, 0xB9, 0x0B, 0xA9, 0x03, 0x04, 0xBA, 0xDB, 0x07, 0x57}, /* Master key 05 encrypted with Master key 06. */
{0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */ {0xA4, 0xD4, 0x52, 0x6F, 0xD1, 0xE4, 0x36, 0xAA, 0x9F, 0xCB, 0x61, 0x27, 0x1C, 0x67, 0x65, 0x1F}, /* Master key 06 encrypted with Master key 07. */
}; {0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */
{0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80}, /* Master key 08 encrypted with Master key 09. */
//======================================Keys======================================// };
// from Package1 -> Secure_Monitor
static const u8 aes_kek_generation_source[0x10] = { //======================================Keys======================================//
0x4D, 0x87, 0x09, 0x86, 0xC4, 0x5D, 0x20, 0x72, 0x2F, 0xBA, 0x10, 0x53, 0xDA, 0x92, 0xE8, 0xA9}; // from Package1 -> Secure_Monitor
static const u8 aes_kek_seed_01[0x10] = { static const u8 aes_kek_generation_source[0x10] = {
0xA2, 0xAB, 0xBF, 0x9C, 0x92, 0x2F, 0xBB, 0xE3, 0x78, 0x79, 0x9B, 0xC0, 0xCC, 0xEA, 0xA5, 0x74}; 0x4D, 0x87, 0x09, 0x86, 0xC4, 0x5D, 0x20, 0x72, 0x2F, 0xBA, 0x10, 0x53, 0xDA, 0x92, 0xE8, 0xA9};
static const u8 aes_kek_seed_03[0x10] = { static const u8 aes_kek_seed_01[0x10] = {
0xE5, 0x4D, 0x9A, 0x02, 0xF0, 0x4F, 0x5F, 0xA8, 0xAD, 0x76, 0x0A, 0xF6, 0x32, 0x95, 0x59, 0xBB}; 0xA2, 0xAB, 0xBF, 0x9C, 0x92, 0x2F, 0xBB, 0xE3, 0x78, 0x79, 0x9B, 0xC0, 0xCC, 0xEA, 0xA5, 0x74};
static const u8 package2_key_source[0x10] = { static const u8 aes_kek_seed_03[0x10] = {
0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7}; 0xE5, 0x4D, 0x9A, 0x02, 0xF0, 0x4F, 0x5F, 0xA8, 0xAD, 0x76, 0x0A, 0xF6, 0x32, 0x95, 0x59, 0xBB};
static const u8 titlekek_source[0x10] = { static const u8 package2_key_source[0x10] = {
0x1E, 0xDC, 0x7B, 0x3B, 0x60, 0xE6, 0xB4, 0xD8, 0x78, 0xB8, 0x17, 0x15, 0x98, 0x5E, 0x62, 0x9B}; 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7};
static const u8 retail_specific_aes_key_source[0x10] = { static const u8 titlekek_source[0x10] = {
0xE2, 0xD6, 0xB8, 0x7A, 0x11, 0x9C, 0xB8, 0x80, 0xE8, 0x22, 0x88, 0x8A, 0x46, 0xFB, 0xA1, 0x95}; 0x1E, 0xDC, 0x7B, 0x3B, 0x60, 0xE6, 0xB4, 0xD8, 0x78, 0xB8, 0x17, 0x15, 0x98, 0x5E, 0x62, 0x9B};
static const u8 retail_specific_aes_key_source[0x10] = {
// from Package1ldr (or Secure_Monitor on 6.2.0) 0xE2, 0xD6, 0xB8, 0x7A, 0x11, 0x9C, 0xB8, 0x80, 0xE8, 0x22, 0x88, 0x8A, 0x46, 0xFB, 0xA1, 0x95};
static const u8 keyblob_mac_key_source[0x10] = {
0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5}; // from Package1ldr (or Secure_Monitor on 6.2.0)
static const u8 master_key_source[0x10] = { static const u8 keyblob_mac_key_source[0x10] = {
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C}; 0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5};
static const u8 per_console_key_source[0x10] = { static const u8 master_key_source[0x10] = {
0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78}; 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C};
static const u8 per_console_key_source[0x10] = {
// from SPL 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78};
static const u8 aes_key_generation_source[0x10] = {
0x89, 0x61, 0x5E, 0xE0, 0x5C, 0x31, 0xB6, 0x80, 0x5F, 0xE5, 0x8F, 0x3D, 0xA2, 0x4F, 0x7A, 0xA8}; // from SPL
static const u8 aes_key_generation_source[0x10] = {
// from FS 0x89, 0x61, 0x5E, 0xE0, 0x5C, 0x31, 0xB6, 0x80, 0x5F, 0xE5, 0x8F, 0x3D, 0xA2, 0x4F, 0x7A, 0xA8};
static const u8 bis_kek_source[0x10] = {
0x34, 0xC1, 0xA0, 0xC4, 0x82, 0x58, 0xF8, 0xB4, 0xFA, 0x9E, 0x5E, 0x6A, 0xDA, 0xFC, 0x7E, 0x4F}; // from FS
static const u8 bis_key_source[3][0x20] = { static const u8 bis_kek_source[0x10] = {
{ 0x34, 0xC1, 0xA0, 0xC4, 0x82, 0x58, 0xF8, 0xB4, 0xFA, 0x9E, 0x5E, 0x6A, 0xDA, 0xFC, 0x7E, 0x4F};
0xF8, 0x3F, 0x38, 0x6E, 0x2C, 0xD2, 0xCA, 0x32, 0xA8, 0x9A, 0xB9, 0xAA, 0x29, 0xBF, 0xC7, 0x48, static const u8 bis_key_source[3][0x20] = {
0x7D, 0x92, 0xB0, 0x3A, 0xA8, 0xBF, 0xDE, 0xE1, 0xA7, 0x4C, 0x3B, 0x6E, 0x35, 0xCB, 0x71, 0x06}, {
{ 0xF8, 0x3F, 0x38, 0x6E, 0x2C, 0xD2, 0xCA, 0x32, 0xA8, 0x9A, 0xB9, 0xAA, 0x29, 0xBF, 0xC7, 0x48,
0x41, 0x00, 0x30, 0x49, 0xDD, 0xCC, 0xC0, 0x65, 0x64, 0x7A, 0x7E, 0xB4, 0x1E, 0xED, 0x9C, 0x5F, 0x7D, 0x92, 0xB0, 0x3A, 0xA8, 0xBF, 0xDE, 0xE1, 0xA7, 0x4C, 0x3B, 0x6E, 0x35, 0xCB, 0x71, 0x06},
0x44, 0x42, 0x4E, 0xDA, 0xB4, 0x9D, 0xFC, 0xD9, 0x87, 0x77, 0x24, 0x9A, 0xDC, 0x9F, 0x7C, 0xA4}, {
{ 0x41, 0x00, 0x30, 0x49, 0xDD, 0xCC, 0xC0, 0x65, 0x64, 0x7A, 0x7E, 0xB4, 0x1E, 0xED, 0x9C, 0x5F,
0x52, 0xC2, 0xE9, 0xEB, 0x09, 0xE3, 0xEE, 0x29, 0x32, 0xA1, 0x0C, 0x1F, 0xB6, 0xA0, 0x92, 0x6C, 0x44, 0x42, 0x4E, 0xDA, 0xB4, 0x9D, 0xFC, 0xD9, 0x87, 0x77, 0x24, 0x9A, 0xDC, 0x9F, 0x7C, 0xA4},
0x4D, 0x12, 0xE1, 0x4B, 0x2A, 0x47, 0x4C, 0x1C, 0x09, 0xCB, 0x03, 0x59, 0xF0, 0x15, 0xF4, 0xE4} {
}; 0x52, 0xC2, 0xE9, 0xEB, 0x09, 0xE3, 0xEE, 0x29, 0x32, 0xA1, 0x0C, 0x1F, 0xB6, 0xA0, 0x92, 0x6C,
0x4D, 0x12, 0xE1, 0x4B, 0x2A, 0x47, 0x4C, 0x1C, 0x09, 0xCB, 0x03, 0x59, 0xF0, 0x15, 0xF4, 0xE4}
static const u8 fs_hashes_sha256[10][0x20] = { };
{ // header_kek_source
0x18, 0x88, 0xca, 0xed, 0x55, 0x51, 0xb3, 0xed, 0xe0, 0x14, 0x99, 0xe8, 0x7c, 0xe0, 0xd8, 0x68, static const u8 fs_hashes_sha256[10][0x20] = {
0x27, 0xf8, 0x08, 0x20, 0xef, 0xb2, 0x75, 0x92, 0x10, 0x55, 0xaa, 0x4e, 0x2a, 0xbd, 0xff, 0xc2}, { // header_kek_source
{ // header_key_source 0x18, 0x88, 0xca, 0xed, 0x55, 0x51, 0xb3, 0xed, 0xe0, 0x14, 0x99, 0xe8, 0x7c, 0xe0, 0xd8, 0x68,
0x8f, 0x78, 0x3e, 0x46, 0x85, 0x2d, 0xf6, 0xbe, 0x0b, 0xa4, 0xe1, 0x92, 0x73, 0xc4, 0xad, 0xba, 0x27, 0xf8, 0x08, 0x20, 0xef, 0xb2, 0x75, 0x92, 0x10, 0x55, 0xaa, 0x4e, 0x2a, 0xbd, 0xff, 0xc2},
0xee, 0x16, 0x38, 0x00, 0x43, 0xe1, 0xb8, 0xc4, 0x18, 0xc4, 0x08, 0x9a, 0x8b, 0xd6, 0x4a, 0xa6}, { // header_key_source
{ // key_area_key_application_source 0x8f, 0x78, 0x3e, 0x46, 0x85, 0x2d, 0xf6, 0xbe, 0x0b, 0xa4, 0xe1, 0x92, 0x73, 0xc4, 0xad, 0xba,
0x04, 0xad, 0x66, 0x14, 0x3c, 0x72, 0x6b, 0x2a, 0x13, 0x9f, 0xb6, 0xb2, 0x11, 0x28, 0xb4, 0x6f, 0xee, 0x16, 0x38, 0x00, 0x43, 0xe1, 0xb8, 0xc4, 0x18, 0xc4, 0x08, 0x9a, 0x8b, 0xd6, 0x4a, 0xa6},
0x56, 0xc5, 0x53, 0xb2, 0xb3, 0x88, 0x71, 0x10, 0x30, 0x42, 0x98, 0xd8, 0xd0, 0x09, 0x2d, 0x9e}, { // key_area_key_application_source
{ // key_area_key_ocean_source 0x04, 0xad, 0x66, 0x14, 0x3c, 0x72, 0x6b, 0x2a, 0x13, 0x9f, 0xb6, 0xb2, 0x11, 0x28, 0xb4, 0x6f,
0xfd, 0x43, 0x40, 0x00, 0xc8, 0xff, 0x2b, 0x26, 0xf8, 0xe9, 0xa9, 0xd2, 0xd2, 0xc1, 0x2f, 0x6b, 0x56, 0xc5, 0x53, 0xb2, 0xb3, 0x88, 0x71, 0x10, 0x30, 0x42, 0x98, 0xd8, 0xd0, 0x09, 0x2d, 0x9e},
0xe5, 0x77, 0x3c, 0xbb, 0x9d, 0xc8, 0x63, 0x00, 0xe1, 0xbd, 0x99, 0xf8, 0xea, 0x33, 0xa4, 0x17}, { // key_area_key_ocean_source
{ // key_area_key_system_source 0xfd, 0x43, 0x40, 0x00, 0xc8, 0xff, 0x2b, 0x26, 0xf8, 0xe9, 0xa9, 0xd2, 0xd2, 0xc1, 0x2f, 0x6b,
0x1f, 0x17, 0xb1, 0xfd, 0x51, 0xad, 0x1c, 0x23, 0x79, 0xb5, 0x8f, 0x15, 0x2c, 0xa4, 0x91, 0x2e, 0xe5, 0x77, 0x3c, 0xbb, 0x9d, 0xc8, 0x63, 0x00, 0xe1, 0xbd, 0x99, 0xf8, 0xea, 0x33, 0xa4, 0x17},
0xc2, 0x10, 0x64, 0x41, 0xe5, 0x17, 0x22, 0xf3, 0x87, 0x00, 0xd5, 0x93, 0x7a, 0x11, 0x62, 0xf7}, { // key_area_key_system_source
{ // save_mac_kek_source 0x1f, 0x17, 0xb1, 0xfd, 0x51, 0xad, 0x1c, 0x23, 0x79, 0xb5, 0x8f, 0x15, 0x2c, 0xa4, 0x91, 0x2e,
0x3D, 0xCB, 0xA1, 0x00, 0xAD, 0x4D, 0xF1, 0x54, 0x7F, 0xE3, 0xC4, 0x79, 0x5C, 0x4B, 0x22, 0x8A, 0xc2, 0x10, 0x64, 0x41, 0xe5, 0x17, 0x22, 0xf3, 0x87, 0x00, 0xd5, 0x93, 0x7a, 0x11, 0x62, 0xf7},
0xA9, 0x80, 0x38, 0xF0, 0x7A, 0x36, 0xF1, 0xBC, 0x14, 0x8E, 0xEA, 0xF3, 0xDC, 0xD7, 0x50, 0xF4}, { // save_mac_kek_source
{ // save_mac_key_source 0x3D, 0xCB, 0xA1, 0x00, 0xAD, 0x4D, 0xF1, 0x54, 0x7F, 0xE3, 0xC4, 0x79, 0x5C, 0x4B, 0x22, 0x8A,
0xB4, 0x7B, 0x60, 0x0B, 0x1A, 0xD3, 0x14, 0xF9, 0x41, 0x14, 0x7D, 0x8B, 0x39, 0x1D, 0x4B, 0x19, 0xA9, 0x80, 0x38, 0xF0, 0x7A, 0x36, 0xF1, 0xBC, 0x14, 0x8E, 0xEA, 0xF3, 0xDC, 0xD7, 0x50, 0xF4},
0x87, 0xCC, 0x8C, 0x88, 0x4A, 0xC8, 0x9F, 0xFC, 0x91, 0xCA, 0xE2, 0x21, 0xC5, 0x24, 0x51, 0xF7}, { // save_mac_key_source
{ // sd_card_kek_source 0xB4, 0x7B, 0x60, 0x0B, 0x1A, 0xD3, 0x14, 0xF9, 0x41, 0x14, 0x7D, 0x8B, 0x39, 0x1D, 0x4B, 0x19,
0x6B, 0x2E, 0xD8, 0x77, 0xC2, 0xC5, 0x23, 0x34, 0xAC, 0x51, 0xE5, 0x9A, 0xBF, 0xA7, 0xEC, 0x45, 0x87, 0xCC, 0x8C, 0x88, 0x4A, 0xC8, 0x9F, 0xFC, 0x91, 0xCA, 0xE2, 0x21, 0xC5, 0x24, 0x51, 0xF7},
0x7F, 0x4A, 0x7D, 0x01, 0xE4, 0x62, 0x91, 0xE9, 0xF2, 0xEA, 0xA4, 0x5F, 0x01, 0x1D, 0x24, 0xB7}, { // sd_card_kek_source
{ // sd_card_nca_key_source 0x6B, 0x2E, 0xD8, 0x77, 0xC2, 0xC5, 0x23, 0x34, 0xAC, 0x51, 0xE5, 0x9A, 0xBF, 0xA7, 0xEC, 0x45,
0x2E, 0x75, 0x1C, 0xEC, 0xF7, 0xD9, 0x3A, 0x2B, 0x95, 0x7B, 0xD5, 0xFF, 0xCB, 0x08, 0x2F, 0xD0, 0x7F, 0x4A, 0x7D, 0x01, 0xE4, 0x62, 0x91, 0xE9, 0xF2, 0xEA, 0xA4, 0x5F, 0x01, 0x1D, 0x24, 0xB7},
0x38, 0xCC, 0x28, 0x53, 0x21, 0x9D, 0xD3, 0x09, 0x2C, 0x6D, 0xAB, 0x98, 0x38, 0xF5, 0xA7, 0xCC}, { // sd_card_nca_key_source
{ // sd_card_save_key_source 0x2E, 0x75, 0x1C, 0xEC, 0xF7, 0xD9, 0x3A, 0x2B, 0x95, 0x7B, 0xD5, 0xFF, 0xCB, 0x08, 0x2F, 0xD0,
0xD4, 0x82, 0x74, 0x35, 0x63, 0xD3, 0xEA, 0x5D, 0xCD, 0xC3, 0xB7, 0x4E, 0x97, 0xC9, 0xAC, 0x8A, 0x38, 0xCC, 0x28, 0x53, 0x21, 0x9D, 0xD3, 0x09, 0x2C, 0x6D, 0xAB, 0x98, 0x38, 0xF5, 0xA7, 0xCC},
0x34, 0x21, 0x64, 0xFA, 0x04, 0x1A, 0x1D, 0xC8, 0x0F, 0x17, 0xF6, 0xD3, 0x1E, 0x4B, 0xC0, 0x1C} { // sd_card_save_key_source
}; 0xD4, 0x82, 0x74, 0x35, 0x63, 0xD3, 0xEA, 0x5D, 0xCD, 0xC3, 0xB7, 0x4E, 0x97, 0xC9, 0xAC, 0x8A,
0x34, 0x21, 0x64, 0xFA, 0x04, 0x1A, 0x1D, 0xC8, 0x0F, 0x17, 0xF6, 0xD3, 0x1E, 0x4B, 0xC0, 0x1C}
static const u8 es_hashes_sha256[3][0x20] = { };
{ // eticket_rsa_kek
0xB7, 0x1D, 0xB2, 0x71, 0xDC, 0x33, 0x8D, 0xF3, 0x80, 0xAA, 0x2C, 0x43, 0x35, 0xEF, 0x88, 0x73, static const u8 es_hashes_sha256[3][0x20] = {
0xB1, 0xAF, 0xD4, 0x08, 0xE8, 0x0B, 0x35, 0x82, 0xD8, 0x71, 0x9F, 0xC8, 0x1C, 0x5E, 0x51, 0x1C}, { // eticket_rsa_kek
{ // eticket_rsa_kekek 0xB7, 0x1D, 0xB2, 0x71, 0xDC, 0x33, 0x8D, 0xF3, 0x80, 0xAA, 0x2C, 0x43, 0x35, 0xEF, 0x88, 0x73,
0xE8, 0x96, 0x5A, 0x18, 0x7D, 0x30, 0xE5, 0x78, 0x69, 0xF5, 0x62, 0xD0, 0x43, 0x83, 0xC9, 0x96, 0xB1, 0xAF, 0xD4, 0x08, 0xE8, 0x0B, 0x35, 0x82, 0xD8, 0x71, 0x9F, 0xC8, 0x1C, 0x5E, 0x51, 0x1C},
0xDE, 0x48, 0x7B, 0xBA, 0x57, 0x61, 0x36, 0x3D, 0x2D, 0x4D, 0x32, 0x39, 0x18, 0x66, 0xA8, 0x5C}, { // eticket_rsa_kekek
{ // ssl_rsa_kek_source_x 0xE8, 0x96, 0x5A, 0x18, 0x7D, 0x30, 0xE5, 0x78, 0x69, 0xF5, 0x62, 0xD0, 0x43, 0x83, 0xC9, 0x96,
0x69, 0xA0, 0x8E, 0x62, 0xE0, 0xAE, 0x50, 0x7B, 0xB5, 0xDA, 0x0E, 0x65, 0x17, 0x9A, 0xE3, 0xBE, 0xDE, 0x48, 0x7B, 0xBA, 0x57, 0x61, 0x36, 0x3D, 0x2D, 0x4D, 0x32, 0x39, 0x18, 0x66, 0xA8, 0x5C},
0x05, 0x1F, 0xED, 0x3C, 0x49, 0x94, 0x1D, 0xF4, 0xEF, 0x29, 0x56, 0xD3, 0x6D, 0x30, 0x11, 0x0C} { // ssl_rsa_kek_source_x
}; 0x69, 0xA0, 0x8E, 0x62, 0xE0, 0xAE, 0x50, 0x7B, 0xB5, 0xDA, 0x0E, 0x65, 0x17, 0x9A, 0xE3, 0xBE,
0x05, 0x1F, 0xED, 0x3C, 0x49, 0x94, 0x1D, 0xF4, 0xEF, 0x29, 0x56, 0xD3, 0x6D, 0x30, 0x11, 0x0C}
static const u8 ssl_hashes_sha256[2][0x20] = { };
{ // ssl_rsa_kek_source_x
0x69, 0xA0, 0x8E, 0x62, 0xE0, 0xAE, 0x50, 0x7B, 0xB5, 0xDA, 0x0E, 0x65, 0x17, 0x9A, 0xE3, 0xBE, static const u8 ssl_hashes_sha256[2][0x20] = {
0x05, 0x1F, 0xED, 0x3C, 0x49, 0x94, 0x1D, 0xF4, 0xEF, 0x29, 0x56, 0xD3, 0x6D, 0x30, 0x11, 0x0C}, { // ssl_rsa_kek_source_x
{ // ssl_rsa_kek_source_y 0x69, 0xA0, 0x8E, 0x62, 0xE0, 0xAE, 0x50, 0x7B, 0xB5, 0xDA, 0x0E, 0x65, 0x17, 0x9A, 0xE3, 0xBE,
0x1C, 0x86, 0xF3, 0x63, 0x26, 0x54, 0x17, 0xD4, 0x99, 0x22, 0x9E, 0xB1, 0xC4, 0xAD, 0xC7, 0x47, 0x05, 0x1F, 0xED, 0x3C, 0x49, 0x94, 0x1D, 0xF4, 0xEF, 0x29, 0x56, 0xD3, 0x6D, 0x30, 0x11, 0x0C},
0x9B, 0x2A, 0x15, 0xF9, 0x31, 0x26, 0x1F, 0x31, 0xEE, 0x67, 0x76, 0xAE, 0xB4, 0xC7, 0x65, 0x42} { // ssl_rsa_kek_source_y
0x1C, 0x86, 0xF3, 0x63, 0x26, 0x54, 0x17, 0xD4, 0x99, 0x22, 0x9E, 0xB1, 0xC4, 0xAD, 0xC7, 0x47,
0x9B, 0x2A, 0x15, 0xF9, 0x31, 0x26, 0x1F, 0x31, 0xEE, 0x67, 0x76, 0xAE, 0xB4, 0xC7, 0x65, 0x42}
}; };

View file

@ -100,7 +100,7 @@ void dump_keys() {
gfx_clear_grey(0x1B); gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0); gfx_con_setpos(0, 0);
gfx_printf("[%kLo%kck%kpi%kck%k-R%kCM%k v%d.%d.%d%k]\n\n", gfx_printf("[%kLo%kck%kpi%kck%k_R%kCM%k v%d.%d.%d%k]\n\n",
colors[0], colors[1], colors[2], colors[3], colors[4], colors[5], 0xFFFF00FF, LP_VER_MJ, LP_VER_MN, LP_VER_BF, 0xFFCCCCCC); colors[0], colors[1], colors[2], colors[3], colors[4], colors[5], 0xFFFF00FF, LP_VER_MJ, LP_VER_MN, LP_VER_BF, 0xFFCCCCCC);
u32 start_time = get_tmr_ms(), u32 start_time = get_tmr_ms(),
@ -140,8 +140,9 @@ void dump_keys() {
tsec_ctxt.size = 0x100 + key_data->blob0_size + key_data->blob1_size + key_data->blob2_size + key_data->blob3_size + key_data->blob4_size; tsec_ctxt.size = 0x100 + key_data->blob0_size + key_data->blob1_size + key_data->blob2_size + key_data->blob3_size + key_data->blob4_size;
u32 MAX_KEY = 6; u32 MAX_KEY = 6;
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_620) if (pkg1_id->kb >= KB_FIRMWARE_VERSION_620) {
MAX_KEY = pkg1_id->kb + 1; MAX_KEY = pkg1_id->kb + 1;
}
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700) { if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700) {
if (!f_stat("sd:/sept/payload.bak", NULL)) { if (!f_stat("sd:/sept/payload.bak", NULL)) {
@ -171,7 +172,7 @@ void dump_keys() {
if (!reboot_to_sept((u8 *)tsec_ctxt.fw, tsec_ctxt.size, pkg1_id->kb)) if (!reboot_to_sept((u8 *)tsec_ctxt.fw, tsec_ctxt.size, pkg1_id->kb))
goto out_wait; goto out_wait;
} else { } else {
se_aes_key_read(12, master_key[pkg1_id->kb], 0x10); se_aes_key_read(12, master_key[KB_FIRMWARE_VERSION_MAX], 0x10);
} }
} }
@ -215,11 +216,36 @@ get_tsec: ;
se_aes_crypt_block_ecb(8, 0, master_key[6], master_key_source); se_aes_crypt_block_ecb(8, 0, master_key[6], master_key_source);
} }
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_620 && _key_exists(master_key[pkg1_id->kb])) { if (pkg1_id->kb >= KB_FIRMWARE_VERSION_620) {
// derive all lower master keys in the event keyblobs are bad // derive all lower master keys in case keyblobs are bad
for (u32 i = pkg1_id->kb; i > 0; i--) { if (_key_exists(master_key[pkg1_id->kb])) {
se_aes_key_set(8, master_key[i], 0x10); for (u32 i = pkg1_id->kb; i > 0; i--) {
se_aes_crypt_block_ecb(8, 0, master_key[i-1], mkey_vectors[i]); se_aes_key_set(8, master_key[i], 0x10);
se_aes_crypt_block_ecb(8, 0, master_key[i-1], mkey_vectors[i]);
}
se_aes_key_set(8, master_key[0], 0x10);
se_aes_crypt_block_ecb(8, 0, temp_key, mkey_vectors[0]);
if (_key_exists(temp_key)) {
EPRINTFARGS("Failed to derive master key. kb = %d", pkg1_id->kb);
}
} else if (_key_exists(master_key[KB_FIRMWARE_VERSION_MAX])) {
// handle sept version differences
for (u32 kb = KB_FIRMWARE_VERSION_MAX; kb >= KB_FIRMWARE_VERSION_620; kb--) {
for (u32 i = kb; i > 0; i--) {
se_aes_key_set(8, master_key[i], 0x10);
se_aes_crypt_block_ecb(8, 0, master_key[i-1], mkey_vectors[i]);
}
se_aes_key_set(8, master_key[0], 0x10);
se_aes_crypt_block_ecb(8, 0, temp_key, mkey_vectors[0]);
if (!_key_exists(temp_key)) {
break;
}
memcpy(master_key[kb-1], master_key[kb], 0x10);
memcpy(master_key[kb], zeros, 0x10);
}
if (_key_exists(temp_key)) {
EPRINTF("Failed to derive master key.");
}
} }
} }
@ -323,16 +349,22 @@ get_tsec: ;
break; break;
} }
if (pkg2_kb == MAX_KEY) { if (pkg2_kb == MAX_KEY) {
EPRINTF("Failed to decrypt Package2."); EPRINTF("Failed to derive Package2 key.");
goto pkg2_done; goto pkg2_done;
} else if (pkg2_kb != pkg1_id->kb) } else if (pkg2_kb != pkg1_id->kb)
EPRINTF("Warning: Package1-Package2 mismatch."); EPRINTF("Warning: Package1-Package2 mismatch.");
pkg2_hdr = pkg2_decrypt(pkg2); pkg2_hdr = pkg2_decrypt(pkg2);
if (!pkg2_hdr) {
EPRINTF("Failed to decrypt Package2.");
goto pkg2_done;
}
TPRINTFARGS("%kDecrypt pkg2... ", colors[2]); TPRINTFARGS("%kDecrypt pkg2... ", colors[2]);
LIST_INIT(kip1_info); LIST_INIT(kip1_info);
pkg2_parse_kips(&kip1_info, pkg2_hdr); bool new_pkg2;
pkg2_parse_kips(&kip1_info, pkg2_hdr, &new_pkg2);
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki_tmp, &kip1_info, link) { LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki_tmp, &kip1_info, link) {
if(ki_tmp->kip1->tid == 0x0100000000000000ULL) { if(ki_tmp->kip1->tid == 0x0100000000000000ULL) {
ki = malloc(sizeof(pkg2_kip1_info_t)); ki = malloc(sizeof(pkg2_kip1_info_t));
@ -405,6 +437,11 @@ get_tsec: ;
hks_offset_from_end -= 0x6a73; hks_offset_from_end -= 0x6a73;
alignment = 8; alignment = 8;
break; break;
case KB_FIRMWARE_VERSION_900:
start_offset = 0x2ec10;
hks_offset_from_end -= 0x5573;
alignment = 1; // RIP
break;
} }
if (pkg1_id->kb <= KB_FIRMWARE_VERSION_500) { if (pkg1_id->kb <= KB_FIRMWARE_VERSION_500) {
@ -455,6 +492,9 @@ pkg2_done:
se_aes_crypt_block_ecb(8, 0, save_mac_key, fs_keys[6]); se_aes_crypt_block_ecb(8, 0, save_mac_key, fs_keys[6]);
} }
if (_key_exists(master_key[MAX_KEY])) {
MAX_KEY = KB_FIRMWARE_VERSION_MAX + 1;
}
for (u32 i = 0; i < MAX_KEY; i++) { for (u32 i = 0; i < MAX_KEY; i++) {
if (!_key_exists(master_key[i])) if (!_key_exists(master_key[i]))
continue; continue;
@ -471,7 +511,10 @@ pkg2_done:
if (!_key_exists(header_key) || !_key_exists(bis_key[2])) if (!_key_exists(header_key) || !_key_exists(bis_key[2]))
{
EPRINTF("Missing FS keys. Skipping ES/SSL keys.");
goto key_output; goto key_output;
}
se_aes_key_set(4, header_key + 0x00, 0x10); se_aes_key_set(4, header_key + 0x00, 0x10);
se_aes_key_set(5, header_key + 0x10, 0x10); se_aes_key_set(5, header_key + 0x10, 0x10);
@ -494,7 +537,7 @@ pkg2_done:
FIL fp; FIL fp;
// sysmodule NCAs only ever have one section (exefs) so 0x600 is sufficient // sysmodule NCAs only ever have one section (exefs) so 0x600 is sufficient
u8 *dec_header = (u8*)malloc(0x600); u8 *dec_header = (u8*)malloc(0x600);
char path[100] = "emmc:/Contents/registered"; char path[100] = "sd:/test/nca1111111111111";//"emmc:/Contents/registered";
u32 titles_found = 0, title_limit = 2, read_bytes = 0; u32 titles_found = 0, title_limit = 2, read_bytes = 0;
if (!memcmp(pkg1_id->id, "2016", 4)) if (!memcmp(pkg1_id->id, "2016", 4))
title_limit = 1; title_limit = 1;
@ -553,6 +596,9 @@ pkg2_done:
case KB_FIRMWARE_VERSION_810: case KB_FIRMWARE_VERSION_810:
start_offset = 0x5563; start_offset = 0x5563;
break; break;
case KB_FIRMWARE_VERSION_900:
start_offset = 0x6495;
break;
} }
hash_order[2] = 2; hash_order[2] = 2;
if (pkg1_id->kb < KB_FIRMWARE_VERSION_500) { if (pkg1_id->kb < KB_FIRMWARE_VERSION_500) {
@ -604,6 +650,9 @@ pkg2_done:
case KB_FIRMWARE_VERSION_810: case KB_FIRMWARE_VERSION_810:
start_offset = 0x1d437; start_offset = 0x1d437;
break; break;
case KB_FIRMWARE_VERSION_900:
start_offset = 0x1d807;
break;
} }
if (!memcmp(pkg1_id->id, "2016", 4)) if (!memcmp(pkg1_id->id, "2016", 4))
start_offset = 0x449dc; start_offset = 0x449dc;
@ -651,7 +700,7 @@ pkg2_done:
// locate sd seed // locate sd seed
u8 read_buf[0x20] = {0}; u8 read_buf[0x20] = {0};
for (u32 i = 0; i < f_size(&fp); i += 0x4000) { for (u32 i = 0x8000; i < f_size(&fp); i += 0x4000) {
if (f_lseek(&fp, i) || f_read(&fp, read_buf, 0x20, &read_bytes) || read_bytes != 0x20) if (f_lseek(&fp, i) || f_read(&fp, read_buf, 0x20, &read_bytes) || read_bytes != 0x20)
break; break;
if (!memcmp(temp_key, read_buf, 0x10)) { if (!memcmp(temp_key, read_buf, 0x10)) {
@ -716,6 +765,7 @@ key_output: ;
SAVE_KEY("master_kek_source_06", master_kek_sources[0], 0x10); SAVE_KEY("master_kek_source_06", master_kek_sources[0], 0x10);
SAVE_KEY("master_kek_source_07", master_kek_sources[1], 0x10); SAVE_KEY("master_kek_source_07", master_kek_sources[1], 0x10);
SAVE_KEY("master_kek_source_08", master_kek_sources[2], 0x10); SAVE_KEY("master_kek_source_08", master_kek_sources[2], 0x10);
SAVE_KEY("master_kek_source_09", master_kek_sources[3], 0x10);
SAVE_KEY_FAMILY("master_key", master_key, MAX_KEY, 0x10); SAVE_KEY_FAMILY("master_key", master_key, MAX_KEY, 0x10);
SAVE_KEY("master_key_source", master_key_source, 0x10); SAVE_KEY("master_key_source", master_key_source, 0x10);
SAVE_KEY_FAMILY("package1_key", package1_key, 6, 0x10); SAVE_KEY_FAMILY("package1_key", package1_key, 6, 0x10);

View file

@ -35,7 +35,8 @@
#define KB_FIRMWARE_VERSION_620 6 #define KB_FIRMWARE_VERSION_620 6
#define KB_FIRMWARE_VERSION_700 7 #define KB_FIRMWARE_VERSION_700 7
#define KB_FIRMWARE_VERSION_810 8 #define KB_FIRMWARE_VERSION_810 8
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_810 #define KB_FIRMWARE_VERSION_900 9
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_900
#define HOS_PKG11_MAGIC 0x31314B50 #define HOS_PKG11_MAGIC 0x31314B50