Reorganise emmc.c/h and rename main menu c file
This commit is contained in:
223
source/tegraexplorer/emmc/emmc.c
Normal file
223
source/tegraexplorer/emmc/emmc.c
Normal file
@@ -0,0 +1,223 @@
|
||||
#include <string.h>
|
||||
#include "emmc.h"
|
||||
#include "../../mem/heap.h"
|
||||
#include "../../utils/types.h"
|
||||
#include "../../libs/fatfs/ff.h"
|
||||
#include "../../utils/sprintf.h"
|
||||
#include "../../utils/btn.h"
|
||||
#include "../../gfx/gfx.h"
|
||||
#include "../../utils/util.h"
|
||||
#include "../../hos/pkg1.h"
|
||||
#include "../../storage/sdmmc.h"
|
||||
#include "../../storage/nx_emmc.h"
|
||||
#include "../../sec/tsec.h"
|
||||
#include "../../soc/t210.h"
|
||||
#include "../../soc/fuse.h"
|
||||
#include "../../mem/mc.h"
|
||||
#include "../../sec/se.h"
|
||||
#include "../../soc/hw_init.h"
|
||||
#include "../../mem/emc.h"
|
||||
#include "../../mem/sdram.h"
|
||||
#include "../../storage/emummc.h"
|
||||
#include "../../config/config.h"
|
||||
#include "../common/common.h"
|
||||
|
||||
sdmmc_storage_t storage;
|
||||
emmc_part_t *system_part;
|
||||
sdmmc_t sdmmc;
|
||||
extern hekate_config h_cfg;
|
||||
__attribute__ ((aligned (16))) FATFS emmc;
|
||||
LIST_INIT(gpt);
|
||||
|
||||
u8 bis_key[4][32];
|
||||
pkg1_info pkg1inf = {-1, ""};
|
||||
short currentlyMounted = -1;
|
||||
|
||||
|
||||
static bool _key_exists(const void *data) { return memcmp(data, zeros, 0x10); };
|
||||
|
||||
static void _generate_kek(u32 ks, const void *key_source, void *master_key, const void *kek_seed, const void *key_seed) {
|
||||
if (!_key_exists(key_source) || !_key_exists(master_key) || !_key_exists(kek_seed))
|
||||
return;
|
||||
|
||||
se_aes_key_set(ks, master_key, 0x10);
|
||||
se_aes_unwrap_key(ks, ks, kek_seed);
|
||||
se_aes_unwrap_key(ks, ks, key_source);
|
||||
if (key_seed && _key_exists(key_seed))
|
||||
se_aes_unwrap_key(ks, ks, key_seed);
|
||||
}
|
||||
|
||||
void print_biskeys(){
|
||||
gfx_printf("Bis_Key_00\n");
|
||||
gfx_hexdump(0, bis_key[0], 32);
|
||||
gfx_printf("Bis_Key_01\n");
|
||||
gfx_hexdump(0, bis_key[1], 32);
|
||||
gfx_printf("Bis_Key_02 & 03\n");
|
||||
gfx_hexdump(0, bis_key[2], 32);
|
||||
}
|
||||
|
||||
pkg1_info returnpkg1info(){
|
||||
return pkg1inf;
|
||||
}
|
||||
|
||||
int connect_part(const char *partition){
|
||||
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||
|
||||
system_part = nx_emmc_part_find(&gpt, partition);
|
||||
if (!system_part) {
|
||||
gfx_printf("Failed to locate %s partition.", partition);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mount_mmc(const char *partition, const int biskeynumb){
|
||||
f_unmount("emmc:");
|
||||
|
||||
se_aes_key_set(8, bis_key[biskeynumb] + 0x00, 0x10);
|
||||
se_aes_key_set(9, bis_key[biskeynumb] + 0x10, 0x10);
|
||||
|
||||
if (connect_part(partition))
|
||||
return -1;
|
||||
|
||||
if (f_mount(&emmc, "emmc:", 1)) {
|
||||
gfx_printf("Mount failed of %s.", partition);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void connect_mmc(short mmctype){
|
||||
if (mmctype != currentlyMounted){
|
||||
disconnect_mmc();
|
||||
h_cfg.emummc_force_disable = 0;
|
||||
switch (mmctype){
|
||||
case SYSMMC:
|
||||
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
|
||||
h_cfg.emummc_force_disable = 1;
|
||||
currentlyMounted = SYSMMC;
|
||||
break;
|
||||
case EMUMMC:
|
||||
if (emummc_storage_init_mmc(&storage, &sdmmc)){
|
||||
h_cfg.emummc_force_disable = 0;
|
||||
currentlyMounted = EMUMMC;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void disconnect_mmc(){
|
||||
f_unmount("emmc:");
|
||||
switch (currentlyMounted){
|
||||
case SYSMMC:
|
||||
sdmmc_storage_end(&storage);
|
||||
break;
|
||||
case EMUMMC:
|
||||
emummc_storage_end(&storage);
|
||||
break;
|
||||
}
|
||||
currentlyMounted = -1;
|
||||
}
|
||||
|
||||
int dump_biskeys(){
|
||||
u8 temp_key[0x10], device_key[0x10] = {0};
|
||||
tsec_ctxt_t tsec_ctxt;
|
||||
|
||||
int retries = 0;
|
||||
|
||||
connect_mmc(SYSMMC);
|
||||
|
||||
// Read package1.
|
||||
u8 *pkg1 = (u8 *)malloc(0x40000);
|
||||
sdmmc_storage_set_mmc_partition(&storage, 1);
|
||||
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
|
||||
if (!pkg1_id) {
|
||||
EPRINTF("Unknown pkg1 version.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool found_tsec_fw = false;
|
||||
for (const u32 *pos = (const u32 *)pkg1; (u8 *)pos < pkg1 + 0x40000; pos += 0x100 / sizeof(u32)) {
|
||||
if (*pos == 0xCF42004D) {
|
||||
tsec_ctxt.fw = (u8 *)pos;
|
||||
found_tsec_fw = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found_tsec_fw) {
|
||||
EPRINTF("Failed to locate TSEC firmware.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
u8 tsec_keys[0x10] = {0};
|
||||
|
||||
tsec_key_data_t *key_data = (tsec_key_data_t *)(tsec_ctxt.fw + TSEC_KEY_DATA_ADDR);
|
||||
tsec_ctxt.pkg1 = pkg1;
|
||||
tsec_ctxt.size = 0x100 + key_data->blob0_size + key_data->blob1_size + key_data->blob2_size + key_data->blob3_size + key_data->blob4_size;
|
||||
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700) {
|
||||
// Exit after TSEC key generation.
|
||||
*((vu16 *)((u32)tsec_ctxt.fw + 0x2DB5)) = 0x02F8;
|
||||
}
|
||||
|
||||
int res = 0;
|
||||
|
||||
mc_disable_ahb_redirect();
|
||||
|
||||
while (tsec_query(tsec_keys, 0, &tsec_ctxt) < 0) {
|
||||
memset(tsec_keys, 0x00, 0x10);
|
||||
retries++;
|
||||
if (retries > 15) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(pkg1);
|
||||
|
||||
mc_enable_ahb_redirect();
|
||||
|
||||
if (res < 0) {
|
||||
gfx_printf("ERROR %x dumping TSEC.\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
u32 sbk[4] = {FUSE(FUSE_PRIVATE_KEY0), FUSE(FUSE_PRIVATE_KEY1),
|
||||
FUSE(FUSE_PRIVATE_KEY2), FUSE(FUSE_PRIVATE_KEY3)};
|
||||
se_aes_key_set(8, tsec_keys, 0x10);
|
||||
se_aes_key_set(9, sbk, 0x10);
|
||||
se_aes_crypt_block_ecb(8, 0, temp_key, keyblob_key_source);
|
||||
se_aes_crypt_block_ecb(9, 0, temp_key, temp_key);
|
||||
se_aes_key_set(7, temp_key, 0x10);
|
||||
se_aes_crypt_block_ecb(7, 0, device_key, per_console_key_source);
|
||||
|
||||
/* key = unwrap(source, wrapped_key):
|
||||
key_set(ks, wrapped_key), block_ecb(ks, 0, key, source) -> final key in key
|
||||
*/
|
||||
if (_key_exists(device_key)) {
|
||||
se_aes_key_set(8, device_key, 0x10);
|
||||
se_aes_unwrap_key(8, 8, retail_specific_aes_key_source); // kek = unwrap(rsaks, devkey)
|
||||
se_aes_crypt_block_ecb(8, 0, bis_key[0] + 0x00, bis_key_source[0] + 0x00); // bkey = unwrap(bkeys, kek)
|
||||
se_aes_crypt_block_ecb(8, 0, bis_key[0] + 0x10, bis_key_source[0] + 0x10);
|
||||
// kek = generate_kek(bkeks, devkey, aeskek, aeskey)
|
||||
_generate_kek(8, bis_kek_source, device_key, aes_kek_generation_source, aes_key_generation_source);
|
||||
se_aes_crypt_block_ecb(8, 0, bis_key[1] + 0x00, bis_key_source[1] + 0x00); // bkey = unwrap(bkeys, kek)
|
||||
se_aes_crypt_block_ecb(8, 0, bis_key[1] + 0x10, bis_key_source[1] + 0x10);
|
||||
se_aes_crypt_block_ecb(8, 0, bis_key[2] + 0x00, bis_key_source[2] + 0x00);
|
||||
se_aes_crypt_block_ecb(8, 0, bis_key[2] + 0x10, bis_key_source[2] + 0x10);
|
||||
memcpy(bis_key[3], bis_key[2], 0x20);
|
||||
}
|
||||
|
||||
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||
// Parse eMMC GPT.
|
||||
nx_emmc_gpt_parse(&gpt, &storage);
|
||||
|
||||
se_aes_key_set(8, bis_key[2] + 0x00, 0x10);
|
||||
se_aes_key_set(9, bis_key[2] + 0x10, 0x10);
|
||||
|
||||
pkg1inf.ver = pkg1_id->kb;
|
||||
strcpy(pkg1inf.id, pkg1_id->id);
|
||||
return 0;
|
||||
}
|
||||
59
source/tegraexplorer/emmc/emmc.h
Normal file
59
source/tegraexplorer/emmc/emmc.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
#include "../../utils/types.h"
|
||||
|
||||
typedef struct _pkg1_info {
|
||||
short ver;
|
||||
char id[16];
|
||||
} pkg1_info;
|
||||
|
||||
//int mount_emmc_partition(const char *part, int logicnumb);
|
||||
int dump_biskeys();
|
||||
void print_biskeys();
|
||||
pkg1_info returnpkg1info();
|
||||
|
||||
int mount_mmc(const char *partition, const int biskeynumb);
|
||||
void connect_mmc(short mmctype);
|
||||
void disconnect_mmc();
|
||||
int connect_part(const char *partition);
|
||||
|
||||
static const u8 zeros[0x10] = {0};
|
||||
|
||||
static const u8 keyblob_key_source[0x10] = {
|
||||
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3};
|
||||
|
||||
//======================================Keys======================================//
|
||||
// from Package1 -> Secure_Monitor
|
||||
static const u8 aes_kek_generation_source[0x10] = {
|
||||
0x4D, 0x87, 0x09, 0x86, 0xC4, 0x5D, 0x20, 0x72, 0x2F, 0xBA, 0x10, 0x53, 0xDA, 0x92, 0xE8, 0xA9};
|
||||
static const u8 retail_specific_aes_key_source[0x10] = {
|
||||
0xE2, 0xD6, 0xB8, 0x7A, 0x11, 0x9C, 0xB8, 0x80, 0xE8, 0x22, 0x88, 0x8A, 0x46, 0xFB, 0xA1, 0x95};
|
||||
|
||||
// from Package1ldr (or Secure_Monitor on 6.2.0)
|
||||
static const u8 per_console_key_source[0x10] = {
|
||||
0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78};
|
||||
|
||||
// from SPL
|
||||
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 FS
|
||||
static const u8 bis_kek_source[0x10] = {
|
||||
0x34, 0xC1, 0xA0, 0xC4, 0x82, 0x58, 0xF8, 0xB4, 0xFA, 0x9E, 0x5E, 0x6A, 0xDA, 0xFC, 0x7E, 0x4F};
|
||||
static const u8 bis_key_source[3][0x20] = {
|
||||
{
|
||||
0xF8, 0x3F, 0x38, 0x6E, 0x2C, 0xD2, 0xCA, 0x32, 0xA8, 0x9A, 0xB9, 0xAA, 0x29, 0xBF, 0xC7, 0x48,
|
||||
0x7D, 0x92, 0xB0, 0x3A, 0xA8, 0xBF, 0xDE, 0xE1, 0xA7, 0x4C, 0x3B, 0x6E, 0x35, 0xCB, 0x71, 0x06},
|
||||
{
|
||||
0x41, 0x00, 0x30, 0x49, 0xDD, 0xCC, 0xC0, 0x65, 0x64, 0x7A, 0x7E, 0xB4, 0x1E, 0xED, 0x9C, 0x5F,
|
||||
0x44, 0x42, 0x4E, 0xDA, 0xB4, 0x9D, 0xFC, 0xD9, 0x87, 0x77, 0x24, 0x9A, 0xDC, 0x9F, 0x7C, 0xA4},
|
||||
{
|
||||
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}
|
||||
};
|
||||
|
||||
/*
|
||||
enum mmc_types {
|
||||
SYSMMC = 0,
|
||||
EMUMMC
|
||||
};
|
||||
*/
|
||||
Reference in New Issue
Block a user