mirror of
https://github.com/Scandal-UK/Incognito_RCM.git
synced 2024-11-22 20:06:42 +00:00
Add 8.0.0 support, move stack to IRAM for faster exec
This commit is contained in:
parent
8425a001ed
commit
04d989a345
14 changed files with 126 additions and 135 deletions
7
Makefile
7
Makefile
|
@ -4,11 +4,11 @@ endif
|
||||||
|
|
||||||
include $(DEVKITARM)/base_rules
|
include $(DEVKITARM)/base_rules
|
||||||
|
|
||||||
IPL_LOAD_ADDR := 0x40008000
|
IPL_LOAD_ADDR := 0x40003000
|
||||||
|
|
||||||
TARGET := Lockpick_RCM
|
TARGET := Lockpick_RCM
|
||||||
BLVERSION_MAJOR := 1
|
LPVERSION_MAJOR := 1
|
||||||
BLVERSION_MINOR := 0
|
LPVERSION_MINOR := 1
|
||||||
BUILD := build
|
BUILD := build
|
||||||
OUTPUT := output
|
OUTPUT := output
|
||||||
SOURCEDIR = source
|
SOURCEDIR = source
|
||||||
|
@ -53,6 +53,7 @@ OBJS += $(addprefix $(BUILD)/$(TARGET)/, \
|
||||||
)
|
)
|
||||||
|
|
||||||
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||||
|
CUSTOMDEFINES += -DLP_VER_MJ=$(LPVERSION_MAJOR) -DLP_VER_MN=$(LPVERSION_MINOR)
|
||||||
|
|
||||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
|
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
|
||||||
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 -Wall $(CUSTOMDEFINES)
|
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 -Wall $(CUSTOMDEFINES)
|
||||||
|
|
|
@ -21,6 +21,11 @@
|
||||||
|
|
||||||
#include "../../common/common_gfx.h"
|
#include "../../common/common_gfx.h"
|
||||||
|
|
||||||
|
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
||||||
|
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
||||||
|
#define WPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFDD00, 0xFFCCCCCC)
|
||||||
|
#define WPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFDD00, args, 0xFFCCCCCC)
|
||||||
|
|
||||||
void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride);
|
void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride);
|
||||||
void gfx_clear_grey(gfx_ctxt_t *ctxt, u8 color);
|
void gfx_clear_grey(gfx_ctxt_t *ctxt, u8 color);
|
||||||
void gfx_clear_partial_grey(gfx_ctxt_t *ctxt, u8 color, u32 pos_x, u32 height);
|
void gfx_clear_partial_grey(gfx_ctxt_t *ctxt, u8 color, u32 pos_x, u32 height);
|
||||||
|
@ -43,4 +48,8 @@ void gfx_set_rect_rgb(gfx_ctxt_t *ctxt, const u8 *buf, u32 size_x, u32 size_y, u
|
||||||
void gfx_set_rect_argb(gfx_ctxt_t *ctxt, const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
void gfx_set_rect_argb(gfx_ctxt_t *ctxt, const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||||
void gfx_render_bmp_argb(gfx_ctxt_t *ctxt, const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
void gfx_render_bmp_argb(gfx_ctxt_t *ctxt, const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||||
|
|
||||||
|
// Global gfx console and context.
|
||||||
|
gfx_ctxt_t gfx_ctxt;
|
||||||
|
gfx_con_t gfx_con;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const pkg1_id_t _pkg1_ids[] = {
|
static const pkg1_id_t _pkg1_ids[] = {
|
||||||
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, true, NULL, NULL }, //1.0.0 (Patched relocator)
|
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, true, NULL, NULL }, //1.0.0
|
||||||
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, NULL, NULL }, //2.0.0 - 2.3.0
|
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, NULL, NULL }, //2.0.0 - 2.3.0
|
||||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, NULL, NULL }, //3.0.0
|
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, NULL, NULL }, //3.0.0
|
||||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, NULL, NULL }, //3.0.1 - 3.0.2
|
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, NULL, NULL }, //3.0.1 - 3.0.2
|
||||||
|
@ -49,6 +49,7 @@ static const pkg1_id_t _pkg1_ids[] = {
|
||||||
{ "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, NULL, NULL }, //6.2.0
|
{ "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, NULL, NULL }, //6.2.0
|
||||||
{ "20181218175730", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.0
|
{ "20181218175730", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.0
|
||||||
{ "20190208150037", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.1
|
{ "20190208150037", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.1
|
||||||
|
{ "20190314172056", 7, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.0.0
|
||||||
{ NULL } //End.
|
{ NULL } //End.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,6 @@
|
||||||
|
|
||||||
#include "../gfx/gfx.h"
|
#include "../gfx/gfx.h"
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC optimize ("Os")
|
|
||||||
|
|
||||||
extern gfx_con_t gfx_con;
|
|
||||||
|
|
||||||
/*#include "util.h"
|
/*#include "util.h"
|
||||||
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
||||||
#define DEBUG_PRINTING*/
|
#define DEBUG_PRINTING*/
|
||||||
|
@ -46,7 +41,12 @@ static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
|
||||||
|
|
||||||
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2)
|
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2)
|
||||||
{
|
{
|
||||||
u8 *ptr = pkg2->data + pkg2->sec_size[PKG2_SEC_KERNEL];
|
u8 *ptr = pkg2->data;
|
||||||
|
if (pkg2->sec_size[PKG2_SEC_INI1] == 0)
|
||||||
|
ptr += *(u32 *)(ptr + 0x168);
|
||||||
|
else
|
||||||
|
ptr += pkg2->sec_size[PKG2_SEC_KERNEL];
|
||||||
|
|
||||||
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)ptr;
|
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)ptr;
|
||||||
ptr += sizeof(pkg2_ini1_t);
|
ptr += sizeof(pkg2_ini1_t);
|
||||||
|
|
||||||
|
@ -164,5 +164,3 @@ DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]);
|
||||||
|
|
||||||
return hdr;
|
return hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|
|
@ -28,9 +28,6 @@
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
#include "../gfx/gfx.h"
|
#include "../gfx/gfx.h"
|
||||||
extern gfx_con_t gfx_con;
|
|
||||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
|
||||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
|
||||||
|
|
||||||
#define PATCHED_RELOC_SZ 0x94
|
#define PATCHED_RELOC_SZ 0x94
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "../hos/sept.h"
|
#include "../hos/sept.h"
|
||||||
#include "../libs/fatfs/ff.h"
|
#include "../libs/fatfs/ff.h"
|
||||||
#include "../mem/heap.h"
|
#include "../mem/heap.h"
|
||||||
#include "../rtc/max77620-rtc.h"
|
#include "../mem/sdram.h"
|
||||||
#include "../sec/se.h"
|
#include "../sec/se.h"
|
||||||
#include "../sec/se_t210.h"
|
#include "../sec/se_t210.h"
|
||||||
#include "../sec/tsec.h"
|
#include "../sec/tsec.h"
|
||||||
|
@ -38,9 +38,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
extern gfx_ctxt_t gfx_ctxt;
|
|
||||||
extern gfx_con_t gfx_con;
|
|
||||||
|
|
||||||
extern bool sd_mount();
|
extern bool sd_mount();
|
||||||
extern void sd_unmount();
|
extern void sd_unmount();
|
||||||
extern void *sd_file_read(char *path);
|
extern void *sd_file_read(char *path);
|
||||||
|
@ -53,8 +50,6 @@ u32 _key_count = 0;
|
||||||
sdmmc_storage_t storage;
|
sdmmc_storage_t storage;
|
||||||
emmc_part_t *system_part;
|
emmc_part_t *system_part;
|
||||||
|
|
||||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFCCCCCC, 0xFFCCCCCC)
|
|
||||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFCCCCCC, args, 0xFFCCCCCC)
|
|
||||||
#define TPRINTF(text) \
|
#define TPRINTF(text) \
|
||||||
end_time = get_tmr_ms(); \
|
end_time = get_tmr_ms(); \
|
||||||
gfx_printf(&gfx_con, text" done @ %d.%03ds\n", (end_time - start_time) / 1000, (end_time - start_time) % 1000)
|
gfx_printf(&gfx_con, text" done @ %d.%03ds\n", (end_time - start_time) / 1000, (end_time - start_time) % 1000)
|
||||||
|
@ -232,11 +227,11 @@ static u32 _sprintf(char *buffer, const char *fmt, ...);
|
||||||
|
|
||||||
void dump_keys() {
|
void dump_keys() {
|
||||||
display_backlight_brightness(100, 1000);
|
display_backlight_brightness(100, 1000);
|
||||||
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
|
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1280);
|
||||||
gfx_con_setpos(&gfx_con, 0, 0);
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
|
||||||
gfx_printf(&gfx_con, "[%kLo%kck%kpi%kck%k-R%kCM%k]\n\n",
|
gfx_printf(&gfx_con, "[%kLo%kck%kpi%kck%k-R%kCM%k v%d.%d%k]\n\n",
|
||||||
colors[0], colors[1], colors[2], colors[3], colors[4], colors[5], 0xFFCCCCCC);
|
colors[0], colors[1], colors[2], colors[3], colors[4], colors[5], 0xFFFF00FF, LP_VER_MJ, LP_VER_MN, 0xFFCCCCCC);
|
||||||
|
|
||||||
u32 start_time = get_tmr_ms(),
|
u32 start_time = get_tmr_ms(),
|
||||||
end_time,
|
end_time,
|
||||||
|
@ -251,12 +246,25 @@ void dump_keys() {
|
||||||
u8 *pkg1 = (u8 *)malloc(0x40000);
|
u8 *pkg1 = (u8 *)malloc(0x40000);
|
||||||
sdmmc_storage_set_mmc_partition(&storage, 1);
|
sdmmc_storage_set_mmc_partition(&storage, 1);
|
||||||
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
|
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
|
||||||
|
/*FIL pk1fp;
|
||||||
|
FRESULT fres = FR_OK;
|
||||||
|
fres += f_open(&pk1fp, "sd:/test/package1", FA_READ | FA_OPEN_EXISTING);
|
||||||
|
fres += f_read(&pk1fp, pkg1, f_size(&pk1fp), NULL);
|
||||||
|
fres += f_close(&pk1fp);
|
||||||
|
if (fres != FR_OK) {
|
||||||
|
EPRINTF("failed to read pkg1 from sd");
|
||||||
|
goto out_wait;
|
||||||
|
}*/
|
||||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
|
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
|
||||||
if (!pkg1_id) {
|
if (!pkg1_id) {
|
||||||
EPRINTF("Unknown pkg1 version.");
|
EPRINTF("Unknown pkg1 version.");
|
||||||
goto out_wait;
|
goto out_wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 MAX_KEY = 6;
|
||||||
|
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_620)
|
||||||
|
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)) {
|
||||||
f_unlink("sd:/sept/payload.bin");
|
f_unlink("sd:/sept/payload.bin");
|
||||||
|
@ -264,9 +272,11 @@ void dump_keys() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(EMC(EMC_SCRATCH0) & EMC_SEPT_RUN)) {
|
if (!(EMC(EMC_SCRATCH0) & EMC_SEPT_RUN)) {
|
||||||
|
// bundle lp0 fw for sept instead of loading it from SD as hekate does
|
||||||
|
sdram_lp0_save_params(sdram_get_params_patched());
|
||||||
FIL fp;
|
FIL fp;
|
||||||
if (f_stat("sd:/sept/sept-primary.bin", NULL) || f_stat("sd:/sept/sept-secondary.enc", NULL)) {
|
if (f_stat("sd:/sept/sept-primary.bin", NULL) || f_stat("sd:/sept/sept-secondary.enc", NULL)) {
|
||||||
EPRINTF("On firmware 7.x but no sept payload present\nSkipping new key derivation...");
|
EPRINTF("On firmware 7.x or higher but no sept payload present\nSkipping new key derivation...");
|
||||||
goto get_tsec;
|
goto get_tsec;
|
||||||
}
|
}
|
||||||
// backup post-reboot payload
|
// backup post-reboot payload
|
||||||
|
@ -277,7 +287,7 @@ void dump_keys() {
|
||||||
u32 payload_size = *(u32 *)(IPL_LOAD_ADDR + 0x84) - IPL_LOAD_ADDR;
|
u32 payload_size = *(u32 *)(IPL_LOAD_ADDR + 0x84) - IPL_LOAD_ADDR;
|
||||||
f_write(&fp, (u8 *)IPL_LOAD_ADDR, payload_size, NULL);
|
f_write(&fp, (u8 *)IPL_LOAD_ADDR, payload_size, NULL);
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
gfx_printf(&gfx_con, "%kFirmware 7.x detected.\n%kRenamed /sept/payload.bin", colors[0], colors[1]);
|
gfx_printf(&gfx_con, "%kFirmware 7.x or higher detected.\n%kRenamed /sept/payload.bin", colors[0], colors[1]);
|
||||||
gfx_printf(&gfx_con, "\n%k to /sept/payload.bak\n%kCopied self to /sept/payload.bin",colors[2], colors[3]);
|
gfx_printf(&gfx_con, "\n%k to /sept/payload.bak\n%kCopied self to /sept/payload.bin",colors[2], colors[3]);
|
||||||
sdmmc_storage_end(&storage);
|
sdmmc_storage_end(&storage);
|
||||||
if (!reboot_to_sept((u8 *)pkg1 + pkg1_id->tsec_off))
|
if (!reboot_to_sept((u8 *)pkg1 + pkg1_id->tsec_off))
|
||||||
|
@ -423,6 +433,10 @@ get_tsec: ;
|
||||||
|
|
||||||
// Read in package2 header and get package2 real size.
|
// Read in package2 header and get package2 real size.
|
||||||
u8 *tmp = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
|
u8 *tmp = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
|
||||||
|
/*FIL pkg2fp;
|
||||||
|
fres = FR_OK;
|
||||||
|
fres += f_open(&pkg2fp, "sd:/test/package2", FA_READ | FA_OPEN_EXISTING);
|
||||||
|
fres += f_read(&pkg2fp, tmp, NX_EMMC_BLOCKSIZE, NULL);*/
|
||||||
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE, 1, tmp);
|
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE, 1, tmp);
|
||||||
u32 *hdr_pkg2_raw = (u32 *)(tmp + 0x100);
|
u32 *hdr_pkg2_raw = (u32 *)(tmp + 0x100);
|
||||||
u32 pkg2_size = hdr_pkg2_raw[0] ^ hdr_pkg2_raw[2] ^ hdr_pkg2_raw[3];
|
u32 pkg2_size = hdr_pkg2_raw[0] ^ hdr_pkg2_raw[2] ^ hdr_pkg2_raw[3];
|
||||||
|
@ -435,12 +449,23 @@ get_tsec: ;
|
||||||
// Read in package2.
|
// Read in package2.
|
||||||
u32 pkg2_size_aligned = ALIGN(pkg2_size, NX_EMMC_BLOCKSIZE);
|
u32 pkg2_size_aligned = ALIGN(pkg2_size, NX_EMMC_BLOCKSIZE);
|
||||||
pkg2 = malloc(pkg2_size_aligned);
|
pkg2 = malloc(pkg2_size_aligned);
|
||||||
|
/*fres += f_lseek(&pkg2fp, 0);
|
||||||
|
fres += f_read(&pkg2fp, pkg2, f_size(&pkg2fp), NULL);
|
||||||
|
fres += f_close(&pkg2fp);
|
||||||
|
if (fres != FR_OK) {
|
||||||
|
EPRINTF("failed to read pkg2 from sd");
|
||||||
|
goto pkg2_done;
|
||||||
|
}*/
|
||||||
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE, pkg2_size_aligned / NX_EMMC_BLOCKSIZE, pkg2);
|
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE, pkg2_size_aligned / NX_EMMC_BLOCKSIZE, pkg2);
|
||||||
|
|
||||||
// Decrypt package2 and parse KIP1 blobs in INI1 section.
|
// Decrypt package2 and parse KIP1 blobs in INI1 section.
|
||||||
se_aes_key_set(8, master_key[pkg1_id->kb], 0x10);
|
se_aes_key_set(8, master_key[pkg1_id->kb], 0x10);
|
||||||
se_aes_unwrap_key(8, 8, package2_key_source);
|
se_aes_unwrap_key(8, 8, package2_key_source);
|
||||||
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(pkg2);
|
pkg2_hdr_t *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]);
|
||||||
|
|
||||||
|
@ -481,7 +506,7 @@ get_tsec: ;
|
||||||
u8 temp[7] = {2, 3, 4, 0, 5, 6, 1};
|
u8 temp[7] = {2, 3, 4, 0, 5, 6, 1};
|
||||||
memcpy(hash_order, temp, 7);
|
memcpy(hash_order, temp, 7);
|
||||||
} else {
|
} else {
|
||||||
// 2.0.0 - 7.0.1
|
// 2.0.0 - 8.0.0
|
||||||
alignment = 0x40;
|
alignment = 0x40;
|
||||||
switch (pkg1_id->kb) {
|
switch (pkg1_id->kb) {
|
||||||
case KB_FIRMWARE_VERSION_100_200:
|
case KB_FIRMWARE_VERSION_100_200:
|
||||||
|
@ -514,7 +539,7 @@ get_tsec: ;
|
||||||
break;
|
break;
|
||||||
case KB_FIRMWARE_VERSION_700:
|
case KB_FIRMWARE_VERSION_700:
|
||||||
start_offset = 0x29c50;
|
start_offset = 0x29c50;
|
||||||
hks_offset_from_end = 0x18bf5;
|
hks_offset_from_end -= 0x6a73;
|
||||||
alignment = 8;
|
alignment = 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -567,8 +592,6 @@ 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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 MAX_KEY = pkg1_id->kb < KB_FIRMWARE_VERSION_620 ? 6 : pkg1_id->kb + 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;
|
||||||
|
@ -584,10 +607,6 @@ pkg2_done:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (memcmp(pkg1_id->id, "2016", 4))
|
|
||||||
gfx_printf(&gfx_con, "%kES & SSL keys... ", colors[5]);
|
|
||||||
else
|
|
||||||
gfx_printf(&gfx_con, "%kSSL keys... ", colors[5]);
|
|
||||||
if (!_key_exists(header_key) || !_key_exists(bis_key[2]))
|
if (!_key_exists(header_key) || !_key_exists(bis_key[2]))
|
||||||
goto key_output;
|
goto key_output;
|
||||||
|
|
||||||
|
@ -618,24 +637,13 @@ pkg2_done:
|
||||||
title_limit = 1;
|
title_limit = 1;
|
||||||
u8 *temp_file = NULL;
|
u8 *temp_file = NULL;
|
||||||
|
|
||||||
u32 x, y, spinner_time = get_tmr_ms(), spinner_idx = 0, color_idx = 0;
|
|
||||||
char spinner[4] = {'/', '-', '\\', '|'};
|
|
||||||
gfx_con_getpos(&gfx_con, &x, &y);
|
|
||||||
|
|
||||||
if (f_opendir(&dir, path)) {
|
if (f_opendir(&dir, path)) {
|
||||||
EPRINTF("Failed to open System:/Contents/registered.");
|
EPRINTF("Failed to open System:/Contents/registered.");
|
||||||
goto dismount;
|
goto dismount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepopulate /Contents/registered in decrypted sector cache
|
// prepopulate /Contents/registered in decrypted sector cache
|
||||||
while (!f_readdir(&dir, &fno) && fno.fname[0]) {
|
while (!f_readdir(&dir, &fno) && fno.fname[0]) {}
|
||||||
if (get_tmr_ms() - spinner_time > 75) {
|
|
||||||
spinner_time = get_tmr_ms();
|
|
||||||
gfx_con_setpos(&gfx_con, x, y);
|
|
||||||
gfx_con_setcol(&gfx_con, colors[color_idx++ % 6], 1, 0xFF1B1B1B);
|
|
||||||
gfx_putc(&gfx_con, spinner[spinner_idx++ % 4]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f_closedir(&dir);
|
f_closedir(&dir);
|
||||||
|
|
||||||
if (f_opendir(&dir, path)) {
|
if (f_opendir(&dir, path)) {
|
||||||
|
@ -647,12 +655,6 @@ pkg2_done:
|
||||||
start_offset = 0;
|
start_offset = 0;
|
||||||
|
|
||||||
while (!f_readdir(&dir, &fno) && fno.fname[0] && titles_found < title_limit) {
|
while (!f_readdir(&dir, &fno) && fno.fname[0] && titles_found < title_limit) {
|
||||||
if (get_tmr_ms() - spinner_time > 75) {
|
|
||||||
spinner_time = get_tmr_ms();
|
|
||||||
gfx_con_setpos(&gfx_con, x, y);
|
|
||||||
gfx_con_setcol(&gfx_con, colors[color_idx++ % 6], 1, 0xFF1B1B1B);
|
|
||||||
gfx_putc(&gfx_con, spinner[spinner_idx++ % 4]);
|
|
||||||
}
|
|
||||||
memcpy(path + 26, fno.fname, 36);
|
memcpy(path + 26, fno.fname, 36);
|
||||||
path[62] = 0;
|
path[62] = 0;
|
||||||
if (fno.fattrib & AM_DIR)
|
if (fno.fattrib & AM_DIR)
|
||||||
|
@ -698,8 +700,8 @@ pkg2_done:
|
||||||
}
|
}
|
||||||
hash_index = 0;
|
hash_index = 0;
|
||||||
// decrypt only what is needed to locate needed keys
|
// decrypt only what is needed to locate needed keys
|
||||||
temp_file = (u8*)_nca_process(5, 4, &fp, start_offset, 0x50);
|
temp_file = (u8*)_nca_process(5, 4, &fp, start_offset, 0xc0);
|
||||||
for (u32 i = 0; i <= 0x40; ) {
|
for (u32 i = 0; i <= 0xb0; ) {
|
||||||
se_calc_sha256(temp_hash, temp_file + i, 0x10);
|
se_calc_sha256(temp_hash, temp_file + i, 0x10);
|
||||||
if (!memcmp(temp_hash, es_hashes_sha256[hash_order[hash_index]], 0x10)) {
|
if (!memcmp(temp_hash, es_hashes_sha256[hash_order[hash_index]], 0x10)) {
|
||||||
memcpy(es_keys[hash_order[hash_index]], temp_file + i, 0x10);
|
memcpy(es_keys[hash_order[hash_index]], temp_file + i, 0x10);
|
||||||
|
@ -740,8 +742,8 @@ pkg2_done:
|
||||||
}
|
}
|
||||||
if (!memcmp(pkg1_id->id, "2016", 4))
|
if (!memcmp(pkg1_id->id, "2016", 4))
|
||||||
start_offset = 0x449dc;
|
start_offset = 0x449dc;
|
||||||
temp_file = (u8*)_nca_process(5, 4, &fp, start_offset, 0x50);
|
temp_file = (u8*)_nca_process(5, 4, &fp, start_offset, 0x70);
|
||||||
for (u32 i = 0; i <= 0x40; i++) {
|
for (u32 i = 0; i <= 0x60; i++) {
|
||||||
se_calc_sha256(temp_hash, temp_file + i, 0x10);
|
se_calc_sha256(temp_hash, temp_file + i, 0x10);
|
||||||
if (!memcmp(temp_hash, ssl_hashes_sha256[1], 0x10)) {
|
if (!memcmp(temp_hash, ssl_hashes_sha256[1], 0x10)) {
|
||||||
memcpy(ssl_keys[1], temp_file + i, 0x10);
|
memcpy(ssl_keys[1], temp_file + i, 0x10);
|
||||||
|
@ -794,6 +796,17 @@ pkg2_done:
|
||||||
}
|
}
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
|
|
||||||
|
dismount:
|
||||||
|
f_mount(NULL, "emmc:", 1);
|
||||||
|
nx_emmc_gpt_free(&gpt);
|
||||||
|
sdmmc_storage_end(&storage);
|
||||||
|
|
||||||
|
if (memcmp(pkg1_id->id, "2016", 4)) {
|
||||||
|
TPRINTFARGS("%kES & SSL keys...", colors[5]);
|
||||||
|
} else {
|
||||||
|
TPRINTFARGS("%kSSL keys... ", colors[5]);
|
||||||
|
}
|
||||||
|
|
||||||
// derive eticket_rsa_kek and ssl_rsa_kek
|
// derive eticket_rsa_kek and ssl_rsa_kek
|
||||||
if (_key_exists(es_keys[0]) && _key_exists(es_keys[1]) && _key_exists(master_key[0])) {
|
if (_key_exists(es_keys[0]) && _key_exists(es_keys[1]) && _key_exists(master_key[0])) {
|
||||||
for (u32 i = 0; i < 0x10; i++)
|
for (u32 i = 0; i < 0x10; i++)
|
||||||
|
@ -808,14 +821,6 @@ pkg2_done:
|
||||||
se_aes_crypt_block_ecb(8, 0, ssl_rsa_kek, ssl_keys[1]);
|
se_aes_crypt_block_ecb(8, 0, ssl_rsa_kek, ssl_keys[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
dismount:
|
|
||||||
f_mount(NULL, "emmc:", 1);
|
|
||||||
nx_emmc_gpt_free(&gpt);
|
|
||||||
sdmmc_storage_end(&storage);
|
|
||||||
|
|
||||||
gfx_con_setpos(&gfx_con, x - 16, y);
|
|
||||||
TPRINTFARGS("%k", colors[5]);
|
|
||||||
|
|
||||||
key_output: ;
|
key_output: ;
|
||||||
char *text_buffer = (char *)calloc(0x4000, 1);
|
char *text_buffer = (char *)calloc(0x4000, 1);
|
||||||
u32 buf_index = 0;
|
u32 buf_index = 0;
|
||||||
|
@ -904,8 +909,8 @@ static void _save_key(const char *name, const void *data, const u32 len, char *o
|
||||||
if (!_key_exists(data))
|
if (!_key_exists(data))
|
||||||
return;
|
return;
|
||||||
*buf_index += _sprintf(outbuf + *buf_index, "%s = ", name);
|
*buf_index += _sprintf(outbuf + *buf_index, "%s = ", name);
|
||||||
for (u32 i = 0; i < len; i += 4)
|
for (u32 i = 0; i < len; i++)
|
||||||
*buf_index += _sprintf(outbuf + *buf_index, "%08x", byte_swap_32(_REG(data, i)));
|
*buf_index += _sprintf(outbuf + *buf_index, "%02x", *(u8*)(data + i));
|
||||||
*buf_index += _sprintf(outbuf + *buf_index, "\n");
|
*buf_index += _sprintf(outbuf + *buf_index, "\n");
|
||||||
_key_count++;
|
_key_count++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,8 @@
|
||||||
#include "../../storage/nx_emmc.h"
|
#include "../../storage/nx_emmc.h"
|
||||||
#include "../../storage/sdmmc.h"
|
#include "../../storage/sdmmc.h"
|
||||||
|
|
||||||
extern gfx_con_t gfx_con;
|
#define SDMMC_UPPER_BUFFER 0xB8000000
|
||||||
|
#define DRAM_START 0x80000000
|
||||||
|
|
||||||
extern sdmmc_storage_t sd_storage;
|
extern sdmmc_storage_t sd_storage;
|
||||||
extern sdmmc_storage_t storage;
|
extern sdmmc_storage_t storage;
|
||||||
|
@ -48,8 +49,8 @@ typedef struct {
|
||||||
u8 cached_sector[0x200];
|
u8 cached_sector[0x200];
|
||||||
} sector_cache_t;
|
} sector_cache_t;
|
||||||
|
|
||||||
#define MAX_SEC_CACHE_ENTRIES 100
|
#define MAX_SEC_CACHE_ENTRIES 64
|
||||||
static sector_cache_t *sector_cache = NULL;
|
static sector_cache_t *sector_cache = (sector_cache_t*)0x40020000;
|
||||||
static u32 secindex = 0;
|
static u32 secindex = 0;
|
||||||
|
|
||||||
DSTATUS disk_status (
|
DSTATUS disk_status (
|
||||||
|
@ -139,19 +140,17 @@ DRESULT disk_read (
|
||||||
switch (pdrv)
|
switch (pdrv)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
if ((u32)buff >= 0x90000000)
|
if ((u32)buff >= DRAM_START)
|
||||||
return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;
|
return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;
|
||||||
u8 *buf = (u8 *)0x98000000; //TODO: define this somewhere.
|
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
|
||||||
if (sdmmc_storage_read(&sd_storage, sector, count, buf))
|
if (sdmmc_storage_read(&sd_storage, sector, count, buf))
|
||||||
{
|
{
|
||||||
memcpy(buff, buf, 512 * count);
|
memcpy(buff, buf, 512 * count);
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
}
|
}
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
case 1:
|
|
||||||
if (!sector_cache) // init sector cache
|
|
||||||
sector_cache = (sector_cache_t*)malloc(sizeof(sector_cache_t) * MAX_SEC_CACHE_ENTRIES);
|
|
||||||
|
|
||||||
|
case 1:;
|
||||||
static u8 tweak[0x10];
|
static u8 tweak[0x10];
|
||||||
static u64 prev_cluster = -1;
|
static u64 prev_cluster = -1;
|
||||||
static u32 prev_sector = 0;
|
static u32 prev_sector = 0;
|
||||||
|
@ -179,7 +178,7 @@ DRESULT disk_read (
|
||||||
secindex++;
|
secindex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((u32)buff >= 0x90000000) {
|
|
||||||
if (nx_emmc_part_read(&storage, system_part, sector, count, buff)) {
|
if (nx_emmc_part_read(&storage, system_part, sector, count, buff)) {
|
||||||
//gfx_hexdump(&gfx_con, 0, buff, 0x100);
|
//gfx_hexdump(&gfx_con, 0, buff, 0x100);
|
||||||
if (prev_cluster != sector / 0x20) { // sector in different cluster than last read
|
if (prev_cluster != sector / 0x20) { // sector in different cluster than last read
|
||||||
|
@ -204,17 +203,6 @@ DRESULT disk_read (
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
}
|
}
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
} else {
|
|
||||||
u8 *buf = (u8 *)0x98000000;
|
|
||||||
if (nx_emmc_part_read(&storage, system_part, sector, count, buf)) {
|
|
||||||
gfx_printf(&gfx_con, "sec %d count %d\n", sector, count);
|
|
||||||
// _emmc_xts(9, 8, 0, tweak, (sector + 0x20 - 1) / 0x20, buf, buf, count * 0x200);
|
|
||||||
//se_aes_xts_crypt(8, 9, 0, sector / 0x20, buf, buf, 0x200, (count + 0x20 - 1) / 0x20);
|
|
||||||
memcpy(buff, buf, 512 * count);
|
|
||||||
return RES_OK;
|
|
||||||
}
|
|
||||||
return RES_ERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -228,9 +216,9 @@ DRESULT disk_write (
|
||||||
{
|
{
|
||||||
if (pdrv == 1)
|
if (pdrv == 1)
|
||||||
return RES_WRPRT;
|
return RES_WRPRT;
|
||||||
if ((u32)buff >= 0x90000000)
|
if ((u32)buff >= DRAM_START)
|
||||||
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
||||||
u8 *buf = (u8 *)0x98000000; //TODO: define this somewhere.
|
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere.
|
||||||
memcpy(buf, buff, 512 * count);
|
memcpy(buf, buff, 512 * count);
|
||||||
if (sdmmc_storage_write(&sd_storage, sector, count, buf))
|
if (sdmmc_storage_write(&sd_storage, sector, count, buf))
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
#include "diskio.h" /* Declarations of device I/O functions */
|
#include "diskio.h" /* Declarations of device I/O functions */
|
||||||
|
|
||||||
#include "../../gfx/gfx.h"
|
#include "../../gfx/gfx.h"
|
||||||
extern gfx_ctxt_t gfx_ctxt;
|
|
||||||
extern gfx_con_t gfx_con;
|
|
||||||
#define EFSPRINTF(text, ...) print_error(); gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
#define EFSPRINTF(text, ...) print_error(); gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
||||||
//#define EFSPRINTF(...)
|
//#define EFSPRINTF(...)
|
||||||
|
|
||||||
|
@ -3780,6 +3778,9 @@ FRESULT f_read (
|
||||||
BYTE *rbuff = (BYTE*)buff;
|
BYTE *rbuff = (BYTE*)buff;
|
||||||
|
|
||||||
|
|
||||||
|
UINT br_tmp;
|
||||||
|
if (!br)
|
||||||
|
br = &br_tmp;
|
||||||
*br = 0; /* Clear read byte counter */
|
*br = 0; /* Clear read byte counter */
|
||||||
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
||||||
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
|
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
|
||||||
|
@ -3902,6 +3903,9 @@ FRESULT f_write (
|
||||||
const BYTE *wbuff = (const BYTE*)buff;
|
const BYTE *wbuff = (const BYTE*)buff;
|
||||||
|
|
||||||
|
|
||||||
|
UINT bw_tmp;
|
||||||
|
if (!bw)
|
||||||
|
bw = &bw_tmp;
|
||||||
*bw = 0; /* Clear write byte counter */
|
*bw = 0; /* Clear write byte counter */
|
||||||
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
||||||
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
|
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_LFN 3
|
#define FF_USE_LFN 1
|
||||||
#define FF_MAX_LFN 255
|
#define FF_MAX_LFN 255
|
||||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||||
/
|
/
|
||||||
|
|
|
@ -34,12 +34,6 @@
|
||||||
|
|
||||||
#include "keys/keys.h"
|
#include "keys/keys.h"
|
||||||
|
|
||||||
gfx_ctxt_t gfx_ctxt;
|
|
||||||
gfx_con_t gfx_con;
|
|
||||||
|
|
||||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
|
||||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
|
||||||
|
|
||||||
sdmmc_t sd_sdmmc;
|
sdmmc_t sd_sdmmc;
|
||||||
sdmmc_storage_t sd_storage;
|
sdmmc_storage_t sd_storage;
|
||||||
FATFS sd_fs;
|
FATFS sd_fs;
|
||||||
|
@ -206,7 +200,7 @@ void ipl_main() {
|
||||||
b_cfg = (boot_cfg_t *)(IPL_LOAD_ADDR + PATCHED_RELOC_SZ);
|
b_cfg = (boot_cfg_t *)(IPL_LOAD_ADDR + PATCHED_RELOC_SZ);
|
||||||
|
|
||||||
config_hw();
|
config_hw();
|
||||||
pivot_stack(0x90010000);
|
pivot_stack(0x4003F000);
|
||||||
heap_init(0x90020000);
|
heap_init(0x90020000);
|
||||||
|
|
||||||
display_init();
|
display_init();
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
#include "../mem/mc.h"
|
#include "../mem/mc.h"
|
||||||
#include "../utils/util.h"
|
#include "../utils/util.h"
|
||||||
|
|
||||||
/* #include "../gfx/gfx.h"
|
/* #include "../gfx/gfx.h" */
|
||||||
extern gfx_con_t gfx_con; */
|
|
||||||
|
|
||||||
static int _tsec_dma_wait_idle()
|
static int _tsec_dma_wait_idle()
|
||||||
{
|
{
|
||||||
|
|
|
@ -232,8 +232,7 @@ void config_hw()
|
||||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = (CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3333;
|
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = (CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3333;
|
||||||
|
|
||||||
sdram_init();
|
sdram_init();
|
||||||
// bundle lp0 fw instead of loading it from SD as hekate does
|
mc_enable_ahb_redirect();
|
||||||
sdram_lp0_save_params(sdram_get_params_patched());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
|
void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
|
||||||
|
|
|
@ -23,8 +23,6 @@
|
||||||
#include "../mem/heap.h"
|
#include "../mem/heap.h"
|
||||||
|
|
||||||
/*#include "gfx.h"
|
/*#include "gfx.h"
|
||||||
extern gfx_ctxt_t gfx_ctxt;
|
|
||||||
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(...)
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include "../soc/gpio.h"
|
#include "../soc/gpio.h"
|
||||||
|
|
||||||
/*#include "gfx.h"
|
/*#include "gfx.h"
|
||||||
extern gfx_ctxt_t gfx_ctxt;
|
|
||||||
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(...)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue