Feature/4x (#10)

* Dump sm, added JanV work
* add Ac_K patches, fix boot, keygen is wrong, need more work
* cleanup keygen, correct key for 4xx
* remove unused code, cleanup code
This commit is contained in:
Ced2911 2018-05-13 03:13:17 +02:00 committed by nwert
parent 764231b418
commit 4d7f016e3a
8 changed files with 236 additions and 176 deletions

249
ipl/hos.c
View file

@ -32,11 +32,20 @@
#include "pkg2.h" #include "pkg2.h"
#include "ff.h" #include "ff.h"
/*#include "gfx.h" #include "gfx.h"
extern gfx_ctxt_t gfx_ctxt; extern gfx_ctxt_t gfx_ctxt;
extern gfx_con_t gfx_con; extern gfx_con_t gfx_con;
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)*/ #define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
#define DPRINTF(...) //#define DPRINTF(...)
enum KB_FIRMWARE_VERSION {
KB_FIRMWARE_VERSION_100_200 = 0,
KB_FIRMWARE_VERSION_300 = 1,
KB_FIRMWARE_VERSION_301 = 2,
KB_FIRMWARE_VERSION_400 = 3,
KB_FIRMWARE_VERSION_500 = 4,
KB_FIRMWARE_VERSION_MAX
};
#define NUM_KEYBLOB_KEYS 5 #define NUM_KEYBLOB_KEYS 5
static const u8 keyblob_keyseeds[NUM_KEYBLOB_KEYS][0x10] = { static const u8 keyblob_keyseeds[NUM_KEYBLOB_KEYS][0x10] = {
@ -50,19 +59,19 @@ static const u8 keyblob_keyseeds[NUM_KEYBLOB_KEYS][0x10] = {
static const u8 cmac_keyseed[0x10] = static const u8 cmac_keyseed[0x10] =
{ 0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5 }; { 0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5 };
static const u8 mkey_keyseed_retail[0x10] = static const u8 master_keyseed_retail[0x10] =
{ 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C }; { 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C };
static const u8 ckey_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 key8_keyseed[] = static const u8 key8_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 new_masterkey_seed[0x10] = static const u8 master_keyseed_4xx[0x10] =
{ 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 }; { 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 };
static const u8 new_per_console_key[0x10] = static const u8 console_keyseed_4xx[0x10] =
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 }; { 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
@ -94,18 +103,27 @@ static void _se_lock()
} }
// <-- key derivation algorithm // <-- key derivation algorithm
static int keygen(u8 *keyblob, u32 kb, void *tsec_fw) int keygen(u8 *keyblob, u32 kb, void *tsec_fw)
{ {
u8 *tmp = (u8 *)malloc(0x10); u8 tmp[0x10];
se_key_acc_ctrl(12, 0x15); se_key_acc_ctrl(0x0D, 0x15);
se_key_acc_ctrl(13, 0x15); se_key_acc_ctrl(0x0E, 0x15);
//Get TSEC key. //Get TSEC key.
if (tsec_query(tmp, 1, tsec_fw) < 0) if (tsec_query(tmp, 1, tsec_fw) < 0)
return 0; return 0;
se_aes_key_set(13, tmp, 0x10); se_aes_key_set(0x0D, tmp, 0x10);
//Derive keyblob keys from TSEC+SBK.
se_aes_crypt_block_ecb(0x0D, 0x00, tmp, keyblob_keyseeds[0]);
se_aes_unwrap_key(0x0F, 0x0E, tmp);
se_aes_crypt_block_ecb(0xD, 0x00, tmp, keyblob_keyseeds[kb]);
se_aes_unwrap_key(0x0D, 0x0E, tmp);
// Clear SBK
se_aes_key_clear(0x0E);
//TODO: verify keyblob CMAC. //TODO: verify keyblob CMAC.
//se_aes_unwrap_key(11, 13, cmac_keyseed); //se_aes_unwrap_key(11, 13, cmac_keyseed);
@ -113,131 +131,43 @@ static int keygen(u8 *keyblob, u32 kb, void *tsec_fw)
//if (!memcmp(keyblob, tmp, 0x10)) //if (!memcmp(keyblob, tmp, 0x10))
// return 0; // return 0;
switch(kb) { se_aes_crypt_block_ecb(0x0D, 0, tmp, cmac_keyseed);
// 1.0.0~2.0.0 FW se_aes_unwrap_key(0x0B, 0x0D, cmac_keyseed);
case 0: {
//Derive keyblob key from TSEC+SBK. //Decrypt keyblob and set keyslots.
memcpy(tmp, keyblob_keyseeds[kb], 0x10); se_aes_crypt_ctr(0x0D, keyblob + 0x20, 0x90, keyblob + 0x20, 0x90, keyblob + 0x10);
se_aes_crypt_block_ecb(13, 0, tmp, tmp); se_aes_key_set(0x0B, keyblob + 0x20 + 0x80, 0x10); // package1 key
se_aes_unwrap_key(13, 14, tmp); se_aes_key_set(0x0C, keyblob + 0x20, 0x10);
se_aes_key_clear(14); se_aes_key_set(0x0D, keyblob + 0x20, 0x10);
se_aes_crypt_ctr(13, keyblob + 0x20, 0x90, keyblob + 0x20, 0x90, keyblob + 0x10); se_aes_crypt_block_ecb(0x0C, 0, tmp, master_keyseed_retail);
se_aes_key_set(11, keyblob + 0x20 + 0x80, 0x10);
se_aes_key_set(12, keyblob + 0x20, 0x10);
//TODO: for some reason SE likes to hang if we don't execute an operation here. switch (kb) {
memcpy(tmp, mkey_keyseed_retail, 0x10); case KB_FIRMWARE_VERSION_100_200:
se_aes_crypt_block_ecb(12, 0, tmp, tmp); case KB_FIRMWARE_VERSION_300:
se_aes_unwrap_key(0x0D, 0x0F, console_keyseed);
//Generate retail master key. se_aes_unwrap_key(0x0C, 0x0C, master_keyseed_retail);
memcpy(tmp, mkey_keyseed_retail, 0x10);
se_aes_unwrap_key(12, 12, tmp);
//Generate console specific key.
memcpy(tmp, ckey_keyseed, 0x10);
se_aes_unwrap_key(13, 13, tmp);
memcpy(tmp, key8_keyseed, 0x10);
se_key_acc_ctrl(8, 0x15);
se_aes_unwrap_key(8, 12, tmp);
se_key_acc_ctrl(12, 0xFF);
se_key_acc_ctrl(13, 0xFF);
}
break;
// 3.0.0~3.0.1 FW
case 1:
case 2: {
// keyslot 10
memcpy(tmp, keyblob_keyseeds[0], 0x10);
se_aes_crypt_block_ecb(13, 0, tmp, tmp);
se_aes_unwrap_key(10, 14, tmp);
// keyslot 13
memcpy(tmp, keyblob_keyseeds[kb], 0x10);
se_aes_crypt_block_ecb(13, 0, tmp, tmp);
se_aes_unwrap_key(13, 14, tmp);
se_aes_key_clear(14);
se_aes_key_clear(15);
se_aes_crypt_ctr(13, keyblob + 0x20, 0x90, keyblob + 0x20, 0x90, keyblob + 0x10);
se_aes_key_set(11, keyblob + 0x20 + 0x80, 0x10);
se_aes_key_set(12, keyblob + 0x20, 0x10);
//TODO: for some reason SE likes to hang if we don't execute an operation here.
memcpy(tmp, mkey_keyseed_retail, 0x10);
se_aes_crypt_block_ecb(12, 0, tmp, tmp);
//Generate retail master key.
memcpy(tmp, mkey_keyseed_retail, 0x10);
se_aes_unwrap_key(12, 12, tmp);
//Generate console specific key.
memcpy(tmp, ckey_keyseed, 0x10);
se_aes_unwrap_key(13, 10, tmp);
se_aes_key_clear(10);
memcpy(tmp, key8_keyseed, 0x10);
se_key_acc_ctrl(8, 0x15);
se_aes_unwrap_key(8, 12, tmp);
se_key_acc_ctrl(12, 0xFF);
se_key_acc_ctrl(13, 0xFF);
}
break; break;
// 4.0.0~5.0.1 FW case KB_FIRMWARE_VERSION_400:
case 3: se_aes_unwrap_key(0x0D, 0x0F, console_keyseed_4xx);
case 4: { se_aes_unwrap_key(0x0F, 0x0F, console_keyseed);
se_key_acc_ctrl(14, 0x15); se_aes_unwrap_key(0x0E, 0x0C, master_keyseed_4xx);
se_key_acc_ctrl(15, 0x15); se_aes_unwrap_key(0x0C, 0x0C, master_keyseed_retail);
break;
// keyslot 15 case KB_FIRMWARE_VERSION_500:
memcpy(tmp, keyblob_keyseeds[0], 0x10); default:
se_aes_crypt_block_ecb(13, 0, tmp, tmp); se_aes_unwrap_key(0x0A, 0x0F, console_keyseed_4xx);
se_aes_unwrap_key(15, 14, tmp); se_aes_unwrap_key(0x0F, 0x0F, console_keyseed);
se_aes_unwrap_key(0x0E, 0x0C, master_keyseed_4xx);
// keyslot 13 se_aes_unwrap_key(0x0C, 0x0C, master_keyseed_retail);
memcpy(tmp, keyblob_keyseeds[kb], 0x10);
se_aes_crypt_block_ecb(13, 0, tmp, tmp);
se_aes_unwrap_key(13, 14, tmp);
se_aes_key_clear(14);
se_aes_crypt_ctr(13, keyblob + 0x20, 0x90, keyblob + 0x20, 0x90, keyblob + 0x10);
se_aes_key_set(11, keyblob + 0x20 + 0x80, 0x10);
se_aes_key_set(12, keyblob + 0x20, 0x10);
//TODO: for some reason SE likes to hang if we don't execute an operation here.
memcpy(tmp, mkey_keyseed_retail, 0x10);
se_aes_crypt_block_ecb(12, 0, tmp, tmp);
// keyslot 14
memcpy(tmp, new_masterkey_seed, 0x10);
se_aes_unwrap_key(14, 12, tmp);
// keyslot 12
memcpy(tmp, mkey_keyseed_retail, 0x10);
se_aes_unwrap_key(12, 12, tmp);
// keyslot 13
memcpy(tmp, new_per_console_key, 0x10);
se_aes_unwrap_key(13, 15, tmp);
// keyslot 15
memcpy(tmp, ckey_keyseed, 0x10);
se_aes_unwrap_key(15, 13, tmp);
se_key_acc_ctrl(12, 0xFF);
se_key_acc_ctrl(15, 0xFF);
}
break; break;
} }
free(tmp);
// Package2 key
se_key_acc_ctrl(0x08, 0x15);
se_aes_unwrap_key(0x08, 0x0C, key8_keyseed);
} }
@ -457,38 +387,39 @@ DPRINTF("decrypted and unpacked pkg1\n");
{ {
//Else we patch it to allow for an unsigned package2. //Else we patch it to allow for an unsigned package2.
patch_t *secmon_patchset = ctxt.pkg1_id->secmon_patchset; patch_t *secmon_patchset = ctxt.pkg1_id->secmon_patchset;
if (secmon_patchset != NULL) { if (secmon_patchset != NULL) {
for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++) for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++)
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val; *(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
DPRINTF("loaded warmboot.bin and secmon\n"); DPRINTF("loaded warmboot.bin and secmon\n");
//Read package2. //Read package2.
if (!_read_emmc_pkg2(&ctxt)) if (!_read_emmc_pkg2(&ctxt))
return 0; return 0;
DPRINTF("read pkg2\n"); DPRINTF("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);
LIST_INIT(kip1_info); LIST_INIT(kip1_info);
pkg2_parse_kips(&kip1_info, pkg2_hdr); pkg2_parse_kips(&kip1_info, pkg2_hdr);
DPRINTF("parsed ini1\n"); DPRINTF("parsed ini1\n");
//Use the kernel included in package2 in case we didn't load one already. //Use the kernel included in package2 in case we didn't load one already.
if (!ctxt.kernel) if (!ctxt.kernel)
{ {
ctxt.kernel = pkg2_hdr->data; ctxt.kernel = pkg2_hdr->data;
ctxt.kernel_size = pkg2_hdr->sec_size[PKG2_SEC_KERNEL]; ctxt.kernel_size = pkg2_hdr->sec_size[PKG2_SEC_KERNEL];
} }
//Merge extra KIP1s into loaded ones. //Merge extra KIP1s into loaded ones.
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link) LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1); pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
//Rebuild and encrypt package2. //Rebuild and encrypt package2.
pkg2_build_encrypt((void *)0xA9800000, ctxt.kernel, ctxt.kernel_size, &kip1_info); pkg2_build_encrypt((void *)0xA9800000, ctxt.kernel, ctxt.kernel_size, &kip1_info);
DPRINTF("rebuilt pkg2\n"); DPRINTF("rebuilt pkg2\n");
} else { } else {
//Read package2. //Read package2.
@ -500,6 +431,14 @@ DPRINTF("decrypted and unpacked pkg1\n");
} }
} }
se_aes_key_clear(8);
se_aes_key_clear(11);
//se_aes_key_clear(13);
//se_key_acc_ctrl(10, 0xFF);
se_key_acc_ctrl(12, 0xFF);
//se_key_acc_ctrl(13, 0xFF);
//se_key_acc_ctrl(14, 0xFF);
se_key_acc_ctrl(15, 0xFF);
//Clear 'BootConfig'. //Clear 'BootConfig'.
memset((void *)0x4003D000, 0, 0x3000); memset((void *)0x4003D000, 0, 0x3000);
@ -530,6 +469,10 @@ DPRINTF("decrypted and unpacked pkg1\n");
//Signal package2 available. //Signal package2 available.
*mb_in = 2; *mb_in = 2;
sleep(100); sleep(100);
*mb_in = 3;
sleep(100);
/*PMC(0x4) = 0x7FFFF3; /*PMC(0x4) = 0x7FFFF3;
PMC(0x2C4) = 0xFFFFFFFF; PMC(0x2C4) = 0xFFFFFFFF;
@ -544,7 +487,7 @@ DPRINTF("decrypted and unpacked pkg1\n");
//display_end(); //display_end();
//Signal to continue boot. //Signal to continue boot.
*mb_in = 3; *mb_in = 4;
sleep(100); sleep(100);
//Halt ourselves in waitevent state. //Halt ourselves in waitevent state.

View file

@ -21,5 +21,6 @@
#include "ini.h" #include "ini.h"
int hos_launch(ini_sec_t *cfg); int hos_launch(ini_sec_t *cfg);
int keygen(u8 *keyblob, u32 kb, void *tsec_fw);
#endif #endif

View file

@ -730,6 +730,103 @@ void dump_emmc_user() { dump_emmc_selected(DUMP_USER); }
void dump_emmc_boot() { dump_emmc_selected(DUMP_BOOT); } void dump_emmc_boot() { dump_emmc_selected(DUMP_BOOT); }
void dump_emmc_rawnand() { dump_emmc_selected(DUMP_RAW); } void dump_emmc_rawnand() { dump_emmc_selected(DUMP_RAW); }
u32 save_to_file(void * buf, u32 size, const char * filename)
{
FIL fp;
if (f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) {
return -1;
}
f_sync(&fp);
f_write(&fp, buf, size, NULL);
f_close(&fp);
return 0;
}
void dump_package1()
{
u8 * pkg1 = (u8 *)malloc(0x40000);
u8 * warmboot = (u8 *)malloc(0x40000);
u8 * secmon = (u8 *)malloc(0x40000);
gfx_clear(&gfx_ctxt, 0xFF000000);
gfx_con_setpos(&gfx_con, 0, 0);
if (!sd_mount())
{
gfx_printf(&gfx_con, "%kFailed to mount SD card (make sure that it is inserted).%k\n", 0xFF0000FF, 0xFFFFFFFF);
goto out;
}
sdmmc_storage_t storage;
sdmmc_t sdmmc;
if(!sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4))
{
gfx_printf(&gfx_con, "%kFailed to init eMMC.%k\n", 0xFF0000FF, 0xFFFFFFFF);
goto out;
}
sdmmc_storage_set_mmc_partition(&storage, 1);
//Read package1.
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
const pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + pkg1_id->pkg11_off + 0x20);
if (!pkg1_id)
{
gfx_printf(&gfx_con, "%kCould not identify package 1 version to read TSEC firmware (= '%s').%k\n", 0xFF0000FF, (char *)pkg1 + 0x10, 0xFFFFFFFF);
goto out;
}
// Read keyblob
u8 * keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + pkg1_id->kb, 1, keyblob);
// decrypt
keygen(keyblob, pkg1_id->kb, (u8 *)pkg1 + pkg1_id->tsec_off);
pkg1_decrypt(pkg1_id, pkg1);
pkg1_unpack(warmboot, secmon, pkg1_id, pkg1);
// display info
gfx_printf(&gfx_con, "%kSecure monitor addr: %08X\n", 0xFF0000FF, pkg1_id->secmon_base);
gfx_printf(&gfx_con, "%kSecure monitor size: %08X\n", 0xFF0000FF, hdr->sm_size);
gfx_printf(&gfx_con, "%kSecure monitor off: %08X\n", 0xFF0000FF, hdr->sm_off);
// dump package1
if (save_to_file(pkg1, 0x40000, "pkg_decr.bin") == -1) {
gfx_printf(&gfx_con, "Failed to create pkg_decr.bin\n");
goto out;
}
gfx_puts(&gfx_con, "%kPackage1 dumped to pkg_decr.bin\n");
// dump sm
if (save_to_file(secmon, 0x40000, "sm.bin") == -1) {
gfx_puts(&gfx_con, "Failed to create sm.bin\n");
goto out;
}
gfx_puts(&gfx_con, "Secure Monitor dumped to sm.bin\n");
// dump warmboot
if (save_to_file(warmboot, 0x40000, "warmboot.bin") == -1) {
gfx_puts(&gfx_con, "Failed to create warmboot.bin\n");
goto out;
}
gfx_puts(&gfx_con, "Warmboot dumped to warmboot.bin\n");
sdmmc_storage_end(&storage);
gfx_puts(&gfx_con, "Done. Press any key.\n");
out:;
free(pkg1);
free(secmon);
free(warmboot);
sleep(100000);
btn_wait();
}
void launch_firmware() void launch_firmware()
{ {
ini_sec_t *cfg_sec = NULL; ini_sec_t *cfg_sec = NULL;
@ -845,6 +942,7 @@ ment_t ment_tools[] = {
MDEF_HANDLER("Dump eMMC SYS", dump_emmc_system), MDEF_HANDLER("Dump eMMC SYS", dump_emmc_system),
MDEF_HANDLER("Dump eMMC USER", dump_emmc_user), MDEF_HANDLER("Dump eMMC USER", dump_emmc_user),
MDEF_HANDLER("Dump eMMC BOOT", dump_emmc_boot), MDEF_HANDLER("Dump eMMC BOOT", dump_emmc_boot),
MDEF_HANDLER("Dump Package1", dump_package1),
MDEF_END() MDEF_END()
}; };
menu_t menu_tools = { menu_t menu_tools = {

View file

@ -47,6 +47,22 @@ PATCHSET_DEF(_secmon_3_patchset,
{ 0xAC8 + 0xADC, _NOP() } //Sections SHA2. { 0xAC8 + 0xADC, _NOP() } //Sections SHA2.
); );
PATCHSET_DEF(_secmon_5_patchset,
//Patch package2 decryption and signature/hash checks.
{ 0x1218 + 0x6E68, _NOP() }, //Header signature.
{ 0x1218 + 0x6E74, _NOP() }, //Version.
{ 0x1218 + 0x6FE4, _NOP() }, //Sections SHA2.
{ 0x1218 + 0x2DC, _NOP() } //Unknown.
);
PATCHSET_DEF(_secmon_6_patchset,
{ 0x12b0 + 0x4d0, _NOP() },
{ 0x12b0 + 0x4dc, _NOP() },
{ 0x12b0 + 0x794, _NOP() },
{ 0x12b0 + 0xb30, _NOP() }//,
//{ 0x12b0 + 0xa18 , _NOP() } // BootConfig Retail Check
);
/* /*
* package1.1 header: <wb, ldr, sm> * package1.1 header: <wb, ldr, sm>
* package1.1 layout: * package1.1 layout:
@ -62,23 +78,12 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, _secmon_1_patchset }, //1.0.0 { "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, _secmon_1_patchset }, //1.0.0
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_2_patchset }, //2.0.0 { "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_2_patchset }, //2.0.0
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, NULL }, //3.0.0 { "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, NULL }, //3.0.0
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, NULL }, //3.0.1 { "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, NULL }, //3.0.1
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, NULL }, //4.0.0 { "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, _secmon_5_patchset }, //4.0.0
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, NULL }, //5.0.0 { "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, _secmon_6_patchset }, //5.0.0
{ NULL, 0, 0, 0, 0 } //End. { NULL, 0, 0, 0, 0 } //End.
}; };
typedef struct _pk11_hdr_t
{
u32 magic;
u32 wb_size;
u32 wb_off;
u32 pad;
u32 ldr_size;
u32 ldr_off;
u32 sm_size;
u32 sm_off;
} pk11_hdr_t;
const pkg1_id_t *pkg1_identify(u8 *pkg1) const pkg1_id_t *pkg1_identify(u8 *pkg1)
{ {

View file

@ -42,6 +42,19 @@ typedef struct _pkg1_id_t
patch_t *secmon_patchset; patch_t *secmon_patchset;
} pkg1_id_t; } pkg1_id_t;
typedef struct _pk11_hdr_t
{
u32 magic;
u32 wb_size;
u32 wb_off;
u32 pad;
u32 ldr_size;
u32 ldr_off;
u32 sm_size;
u32 sm_off;
} pk11_hdr_t;
const pkg1_id_t *pkg1_identify(u8 *pkg1); const pkg1_id_t *pkg1_identify(u8 *pkg1);
void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1); void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1);
void pkg1_unpack(void *warmboot_dst, void *secmon_dst, const pkg1_id_t *id, u8 *pkg1); void pkg1_unpack(void *warmboot_dst, void *secmon_dst, const pkg1_id_t *id, u8 *pkg1);

View file

@ -172,3 +172,4 @@ DPRINTF("INI1 encrypted\n");
memset(hdr->ctr, 0 , 0x10); memset(hdr->ctr, 0 , 0x10);
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size; *(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
} }

View file

@ -67,7 +67,7 @@ static int _se_wait()
return 1; return 1;
} }
static int _se_execute(u32 op, void *dst, u32 dst_size, void *src, u32 src_size) static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
{ {
se_ll_t *ll_dst = NULL, *ll_src = NULL; se_ll_t *ll_dst = NULL, *ll_src = NULL;
@ -99,7 +99,7 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, void *src, u32 src_size)
return res; return res;
} }
static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, void *src, u32 src_size) static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
{ {
u8 *block = (u8 *)malloc(0x10); u8 *block = (u8 *)malloc(0x10);
memset(block, 0, 0x10); memset(block, 0, 0x10);
@ -156,7 +156,7 @@ void se_aes_key_clear(u32 ks)
} }
} }
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, void *input) int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
{ {
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTAB); SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTAB);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
@ -164,7 +164,7 @@ int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, void *input)
return _se_execute(OP_START, NULL, 0, input, 0x10); return _se_execute(OP_START, NULL, 0, input, 0x10);
} }
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, void *src) int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src)
{ {
if (enc) if (enc)
{ {
@ -180,7 +180,7 @@ int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, void *src)
return _se_execute(OP_START, dst, 0x10, src, 0x10); return _se_execute(OP_START, dst, 0x10, src, 0x10);
} }
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, void *src, u32 src_size, void *ctr) int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr)
{ {
SE(SE_SPARE_0_REG_OFFSET) = 1; SE(SE_SPARE_0_REG_OFFSET) = 1;
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);

View file

@ -23,8 +23,7 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags);
void se_key_acc_ctrl(u32 ks, u32 flags); void se_key_acc_ctrl(u32 ks, u32 flags);
void se_aes_key_set(u32 ks, void *key, u32 size); void se_aes_key_set(u32 ks, void *key, u32 size);
void se_aes_key_clear(u32 ks); void se_aes_key_clear(u32 ks);
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, void *input); int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, void *src); int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, void *src, u32 src_size, void *ctr); int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
#endif #endif