diff --git a/bdk/utils/types.h b/bdk/utils/types.h index 42c45f7..00af900 100644 --- a/bdk/utils/types.h +++ b/bdk/utils/types.h @@ -62,6 +62,7 @@ typedef int bool; #define EXTRA_CFG_PAYLOAD (1 << 1) #define EXTRA_CFG_MODULE (1 << 2) +#define EXTRA_CFG_NYX_BIS (1 << 4) #define EXTRA_CFG_NYX_UMS (1 << 5) #define EXTRA_CFG_NYX_RELOAD (1 << 6) #define EXTRA_CFG_NYX_DUMP (1 << 7) diff --git a/bdk/utils/util.h b/bdk/utils/util.h index 2c59b61..948e02c 100644 --- a/bdk/utils/util.h +++ b/bdk/utils/util.h @@ -23,8 +23,9 @@ typedef enum { - NYX_CFG_UMS = (1 << 6), - NYX_CFG_DUMP = (1 << 7), + NYX_CFG_BIS = (1 << 5), + NYX_CFG_UMS = (1 << 6), + NYX_CFG_DUMP = (1 << 7), } nyx_cfg_t; typedef enum diff --git a/bootloader/main.c b/bootloader/main.c index 28dc638..68f4ede 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -705,6 +705,11 @@ void nyx_load_run() b_cfg.extra_cfg &= ~(EXTRA_CFG_NYX_DUMP); nyx_str->cfg |= NYX_CFG_DUMP; } + if (b_cfg.extra_cfg & EXTRA_CFG_NYX_BIS) + { + b_cfg.extra_cfg &= ~(EXTRA_CFG_NYX_BIS); + nyx_str->cfg |= NYX_CFG_BIS; + } if (b_cfg.extra_cfg & EXTRA_CFG_NYX_UMS) { b_cfg.extra_cfg &= ~(EXTRA_CFG_NYX_UMS); @@ -763,7 +768,7 @@ static ini_sec_t *get_ini_sec_from_id(ini_sec_t *ini_sec, char **bootlogoCustomE static void _auto_launch_firmware() { - if(b_cfg.extra_cfg & EXTRA_CFG_NYX_DUMP) + if(b_cfg.extra_cfg & (EXTRA_CFG_NYX_DUMP | EXTRA_CFG_NYX_BIS)) { if (!h_cfg.sept_run) EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD; diff --git a/nyx/nyx_gui/frontend/gui.c b/nyx/nyx_gui/frontend/gui.c index 2188196..1a4ab89 100644 --- a/nyx/nyx_gui/frontend/gui.c +++ b/nyx/nyx_gui/frontend/gui.c @@ -2185,6 +2185,12 @@ static void _nyx_main_menu(lv_theme_t * th) lv_task_t *task_run_dump = lv_task_create(sept_run_dump, LV_TASK_ONESHOT, LV_TASK_PRIO_MID, NULL); lv_task_once(task_run_dump); } + else if (nyx_str->cfg & NYX_CFG_BIS) + { + nyx_str->cfg &= ~(NYX_CFG_BIS); + lv_task_t *task_run_cal0 = lv_task_create(sept_run_cal0, LV_TASK_ONESHOT, LV_TASK_PRIO_LOWEST, NULL); + lv_task_once(task_run_cal0); + } else if (nyx_str->cfg & NYX_CFG_UMS) { nyx_str->cfg &= ~(NYX_CFG_UMS); diff --git a/nyx/nyx_gui/frontend/gui_info.c b/nyx/nyx_gui/frontend/gui_info.c index 82e39db..fbad025 100644 --- a/nyx/nyx_gui/frontend/gui_info.c +++ b/nyx/nyx_gui/frontend/gui_info.c @@ -18,8 +18,10 @@ #include "gui.h" #include +#include "../config.h" #include "../hos/hos.h" #include "../hos/pkg1.h" +#include "../hos/sept.h" #include #include #include @@ -28,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -43,10 +46,14 @@ #define SECTORS_TO_MIB_COEFF 11 +extern hekate_config h_cfg; +extern volatile boot_cfg_t *b_cfg; extern volatile nyx_storage_t *nyx_str; extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage); +static u8 *cal0_buf = NULL; + static lv_res_t _create_window_dump_done(int error, char *dump_filenames) { lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); @@ -217,10 +224,197 @@ static lv_res_t _tsec_keys_dump_window_action(lv_obj_t * btn) return LV_RES_OK; } +static lv_res_t _create_mbox_cal0(lv_obj_t *btn) +{ + lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); + lv_obj_set_style(dark_bg, &mbox_darken); + lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); + + static const char * mbox_btn_map[] = { "\211", "\222OK", "\211", "" }; + lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL); + lv_mbox_set_recolor_text(mbox, true); + lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5); + + lv_mbox_set_text(mbox, "#C7EA46 CAL0 Info#"); + + char *txt_buf = (char *)malloc(0x4000); + + lv_obj_t * lb_desc = lv_label_create(mbox, NULL); + lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK); + lv_label_set_recolor(lb_desc, true); + lv_label_set_style(lb_desc, &monospace_text); + lv_obj_set_width(lb_desc, LV_HOR_RES / 9 * 3); + + // Read package1. + char *build_date = malloc(32); + u8 *pkg1 = (u8 *)malloc(0x40000); + sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400); + sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0); + sdmmc_storage_read(&emmc_storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1); + + const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date); + + s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n", build_date); + free(build_date); + + sd_mount(); + + if (!pkg1_id) + { + s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#"); + lv_label_set_text(lb_desc, txt_buf); + + goto out; + } + + tsec_ctxt_t tsec_ctxt; + tsec_ctxt.fw = (u8 *)pkg1 + pkg1_id->tsec_off; + tsec_ctxt.pkg1 = pkg1; + tsec_ctxt.pkg11_off = pkg1_id->pkg11_off; + tsec_ctxt.secmon_base = pkg1_id->secmon_base; + + // Get keys. + hos_eks_get(); + if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run) + { + u32 key_idx = 0; + if (pkg1_id->kb >= KB_FIRMWARE_VERSION_810) + key_idx = 1; + + if (h_cfg.eks && h_cfg.eks->enabled[key_idx] >= pkg1_id->kb) + h_cfg.sept_run = true; + else + { + b_cfg->autoboot = 0; + b_cfg->autoboot_list = 0; + b_cfg->extra_cfg = EXTRA_CFG_NYX_BIS; + + if (!reboot_to_sept((u8 *)tsec_ctxt.fw, pkg1_id->kb)) + { + lv_label_set_text(lb_desc, "#FFDD00 Failed to run sept#\n"); + goto out; + } + } + } + + // Read the correct keyblob. + u8 *keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1); + sdmmc_storage_read(&emmc_storage, 0x180000 / NX_EMMC_BLOCKSIZE + pkg1_id->kb, 1, keyblob); + + // Generate BIS keys + hos_bis_keygen(keyblob, pkg1_id->kb, &tsec_ctxt); + + free(keyblob); + + if (!cal0_buf) + cal0_buf = malloc(0x10000); + + // Read and decrypt CAL0. + sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_GPP); + LIST_INIT(gpt); + nx_emmc_gpt_parse(&gpt, &emmc_storage); + emmc_part_t *cal0_part = nx_emmc_part_find(&gpt, "PRODINFO"); // check if null + nx_emmc_bis_init(cal0_part); + nx_emmc_bis_read(0, 0x40, cal0_buf); + + // Clear BIS keys slots. + hos_bis_keys_clear(); + + nx_emmc_cal0_t *cal0 = (nx_emmc_cal0_t *)cal0_buf; + + // If successful, save BIS keys. + if (memcmp(&cal0->magic, "CAL0", 4)) + { + free(cal0_buf); + cal0_buf = NULL; + + hos_eks_bis_clear(); + + lv_label_set_text(lb_desc, "#FFDD00 CAL0 is corrupt or wrong keys!#\n"); + goto out; + } + else + hos_eks_bis_save(); + + u32 hash[8]; + se_calc_sha256_oneshot(hash, (u8 *)cal0 + 0x40, cal0->body_size); + + s_printf(txt_buf, + "#FF8000 CAL0 Version:# %d\n" + "#FF8000 Update Count:# %d\n" + "#FF8000 Serial Number:# %s\n" + "#FF8000 WLAN MAC:# %02X:%02X:%02X:%02X:%02X:%02X\n" + "#FF8000 Bluetooth MAC:# %02X:%02X:%02X:%02X:%02X:%02X\n" + "#FF8000 Battery LOT:# %s\n" + "#FF8000 LCD Vendor:# ", + cal0->version, cal0->update_cnt, cal0->serial_number, + cal0->wlan_mac[0], cal0->wlan_mac[1], cal0->wlan_mac[2], cal0->wlan_mac[3], cal0->wlan_mac[4], cal0->wlan_mac[5], + cal0->bd_mac[0], cal0->bd_mac[1], cal0->bd_mac[2], cal0->bd_mac[3], cal0->bd_mac[4], cal0->bd_mac[5], + cal0->battery_lot); + + u32 display_id = (cal0->lcd_vendor & 0xFF) << 8 | (cal0->lcd_vendor & 0xFF0000) >> 16; + switch (display_id) + { + case PANEL_JDI_LAM062M109A: + s_printf(txt_buf + strlen(txt_buf), "JDI LAM062M109A"); + break; + case PANEL_JDI_LPM062M326A: + s_printf(txt_buf + strlen(txt_buf), "JDI LPM062M326A"); + break; + case PANEL_INL_P062CCA_AZ1: + s_printf(txt_buf + strlen(txt_buf), "InnoLux P062CCA-AZ1"); + break; + case PANEL_AUO_A062TAN01: + s_printf(txt_buf + strlen(txt_buf), "AUO A062TAN01"); + break; + case PANEL_INL_P062CCA_AZ2: + s_printf(txt_buf + strlen(txt_buf), "InnoLux P062CCA-AZ2"); + break; + case PANEL_AUO_A062TAN02: + s_printf(txt_buf + strlen(txt_buf), "AUO A062TAN02"); + break; + default: + switch (cal0->lcd_vendor & 0xFF) + { + case 0: + case PANEL_JDI_XXX062M: + s_printf(txt_buf + strlen(txt_buf), "JDI "); + break; + case (PANEL_INL_P062CCA_AZ1 & 0xFF): + s_printf(txt_buf + strlen(txt_buf), "InnoLux "); + break; + case (PANEL_AUO_A062TAN01 & 0xFF): + s_printf(txt_buf + strlen(txt_buf), "AUO "); + break; + } + s_printf(txt_buf + strlen(txt_buf), "Unknown"); + break; + } + + bool valid_cal0 = !memcmp(hash, cal0->body_sha256, 0x20); + s_printf(txt_buf + strlen(txt_buf), " (%06X)\n#FF8000 SHA256 Hash Match:# %s", cal0->lcd_vendor, valid_cal0 ? "Pass" : "Failed"); + + lv_label_set_text(lb_desc, txt_buf); + +out: + free(pkg1); + free(txt_buf); + sd_unmount(); + sdmmc_storage_end(&emmc_storage); + + lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_top(mbox, true); + + return LV_RES_OK; +} + static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn) { lv_obj_t *win = nyx_create_standard_window(SYMBOL_CHIP" HW & Cached Fuses Info"); lv_win_add_btn(win, NULL, SYMBOL_DOWNLOAD" Dump fuses", _fuse_dump_window_action); + lv_win_add_btn(win, NULL, SYMBOL_INFO" CAL0 Info", _create_mbox_cal0); lv_obj_t *desc = lv_cont_create(win, NULL); lv_obj_set_size(desc, LV_HOR_RES / 2 / 5 * 2, LV_VER_RES - (LV_DPI * 11 / 7) - 5); @@ -511,9 +705,17 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn) lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2)); lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0); + if (!btn) + _create_mbox_cal0(NULL); + return LV_RES_OK; } +void sept_run_cal0(void *param) +{ + _create_window_fuses_info_status(NULL); +} + static char *ipatches_txt; static void _ipatch_process(u32 offset, u32 value) { @@ -566,8 +768,6 @@ static lv_res_t _create_window_tsec_keys_status(lv_obj_t *btn) u32 retries = 0; tsec_ctxt_t tsec_ctxt; - sdmmc_storage_t storage; - sdmmc_t sdmmc; lv_obj_t *win = nyx_create_standard_window(SYMBOL_CHIP" TSEC Keys");