diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index 588be8db..a142f72e 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -131,23 +131,23 @@ static void _se_lock(bool lock_se) SB(SB_CSR) = SB_CSR_PIROM_DISABLE; } -static bool _hos_eks_rw_try(u8 *buf, bool write) +static int _hos_eks_rw_try(u8 *buf, bool write) { for (u32 i = 0; i < 3; i++) { if (!write) { if (sdmmc_storage_read(&sd_storage, 0, 1, buf)) - return true; + return 0; } else { if (sdmmc_storage_write(&sd_storage, 0, 1, buf)) - return true; + return 0; } } - return false; + return 1; } static void _hos_eks_get() @@ -161,7 +161,7 @@ static void _hos_eks_get() { // Read EKS blob. u8 *mbr = malloc(SD_BLOCKSIZE); - if (!_hos_eks_rw_try(mbr, false)) + if (_hos_eks_rw_try(mbr, false)) goto out; // Decrypt EKS blob. @@ -199,7 +199,7 @@ static void _hos_eks_save() { // Read EKS blob. u8 *mbr = malloc(SD_BLOCKSIZE); - if (!_hos_eks_rw_try(mbr, false)) + if (_hos_eks_rw_try(mbr, false)) { if (new_eks) { @@ -253,7 +253,7 @@ static void _hos_eks_clear(u32 mkey) { // Read EKS blob. u8 *mbr = malloc(SD_BLOCKSIZE); - if (!_hos_eks_rw_try(mbr, false)) + if (_hos_eks_rw_try(mbr, false)) goto out; // Disable current Master key version. @@ -291,7 +291,7 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s tsec_keys_t tsec_keys; if (mkey > HOS_MKEY_VER_MAX) - return 0; + return 1; // Do Mariko keygen. if (h_cfg.t210b01) @@ -306,7 +306,7 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s // Derive latest pkg2 key. se_aes_unwrap_key(8, 7, package2_keyseed); - return 1; + return 0; } // Do Erista keygen. @@ -317,7 +317,7 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s if (fuse_set_sbk()) sbk_is_set = true; else - return 1; // Continue with current SE keys. + return 0; // Continue with current SE keys. } // Use HOS EKS if it exists. @@ -354,7 +354,7 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s if (!tsec_ctxt->fw) { _hos_crit_error("Failed to load thk.bin"); - return 0; + return 1; } tsec_ctxt->size = 0x1F00; @@ -378,7 +378,7 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s if (retries > 15) { _hos_crit_error("Failed to get TSEC keys."); - return 0; + return 1; } } @@ -483,7 +483,7 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s se_aes_unwrap_key(11, 13, cmac_keyseed); se_aes_hash_cmac(cmac, SE_KEY_128_SIZE, 11, (void *)eks->ctr, sizeof(eks->ctr) + sizeof(eks->keys)); if (!memcmp(eks->cmac, cmac, SE_KEY_128_SIZE)) - return 0; + return 1; */ se_aes_crypt_ecb(13, DECRYPT, tsec_keys.tsec, cmac_keyseed, SE_KEY_128_SIZE); @@ -537,7 +537,7 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s se_aes_unwrap_key(8, !is_exo ? 12 : 13, package2_keyseed); } - return 1; + return 0; } static int _read_emmc_pkg1(launch_ctxt_t *ctxt) @@ -586,7 +586,7 @@ try_load: goto try_load; } - return 0; + return 1; } gfx_printf("Identified pkg1 and mkey %d\n\n", ctxt->pkg1_id->mkey); @@ -599,7 +599,7 @@ try_load: eks_size / EMMC_BLOCKSIZE, ctxt->eks); } - return 1; + return 0; } static u8 *_read_emmc_pkg2(launch_ctxt_t *ctxt) @@ -734,14 +734,14 @@ void hos_launch(ini_sec_t *cfg) } // Try to parse config if present. - if (!parse_boot_config(&ctxt)) + if (hos_parse_boot_config(&ctxt)) { _hos_crit_error("Wrong ini cfg or missing/corrupt files!"); goto error; } // Read package1 and the correct eks. - if (!_read_emmc_pkg1(&ctxt)) + if (_read_emmc_pkg1(&ctxt)) { // Check if stock is enabled and device can boot in OFW. if (ctxt.stock && (h_cfg.t210b01 || !tools_autorcm_enabled())) @@ -770,7 +770,7 @@ void hos_launch(ini_sec_t *cfg) } ctxt.patch_krn_proc_id = true; // Set kernel process id patching in case of no pkg3. - config_kip1patch(&ctxt, "emummc"); + hos_config_kip1patch(&ctxt, "emummc"); } else if (!emu_cfg.enabled && ctxt.emummc_forced) { @@ -801,7 +801,7 @@ void hos_launch(ini_sec_t *cfg) ((fuses & BIT(14)) && (ctxt.pkg1_id->fuses <= 14)) // HOS 12.0.2+ fuses burnt. ) )) - config_kip1patch(&ctxt, "nogc"); + hos_config_kip1patch(&ctxt, "nogc"); } gfx_printf("Loaded config and pkg1\n%s mode\n", ctxt.stock ? "Stock" : "CFW"); @@ -821,7 +821,7 @@ void hos_launch(ini_sec_t *cfg) tsec_ctxt.pkg11_off = ctxt.pkg1_id->pkg11_off; // Generate keys. - if (!_hos_keygen(ctxt.eks, mkey, &tsec_ctxt, ctxt.stock, is_exo)) + if (_hos_keygen(ctxt.eks, mkey, &tsec_ctxt, ctxt.stock, is_exo)) goto error; gfx_puts("Generated keys\n"); @@ -871,7 +871,7 @@ void hos_launch(ini_sec_t *cfg) } // Configure and manage Warmboot binary. - if (!pkg1_warmboot_config(&ctxt, warmboot_base, ctxt.pkg1_id->fuses, mkey)) + if (pkg1_warmboot_config(&ctxt, warmboot_base, ctxt.pkg1_id->fuses, mkey)) { // Can only happen on T210B01. _hos_crit_error("\nFailed to match warmboot with fuses!\nIf you continue, sleep wont work!"); @@ -928,7 +928,7 @@ void hos_launch(ini_sec_t *cfg) } LIST_INIT(kip1_info); - if (!pkg2_parse_kips(&kip1_info, pkg2_hdr, &ctxt.new_pkg2)) + if (pkg2_parse_kips(&kip1_info, pkg2_hdr, &ctxt.new_pkg2)) { _hos_crit_error("INI1 parsing failed!"); goto error; diff --git a/bootloader/hos/hos_config.c b/bootloader/hos/hos_config.c index eb64ae1f..b88f28db 100644 --- a/bootloader/hos/hos_config.c +++ b/bootloader/hos/hos_config.c @@ -31,27 +31,27 @@ static int _config_warmboot(launch_ctxt_t *ctxt, const char *value) { ctxt->warmboot = sd_file_read(value, &ctxt->warmboot_size); if (!ctxt->warmboot) - return 0; + return 1; - return 1; + return 0; } static int _config_secmon(launch_ctxt_t *ctxt, const char *value) { ctxt->secmon = sd_file_read(value, &ctxt->secmon_size); if (!ctxt->secmon) - return 0; + return 1; - return 1; + return 0; } static int _config_kernel(launch_ctxt_t *ctxt, const char *value) { ctxt->kernel = sd_file_read(value, &ctxt->kernel_size); if (!ctxt->kernel) - return 0; + return 1; - return 1; + return 0; } static int _config_kip1(launch_ctxt_t *ctxt, const char *value) @@ -88,7 +88,7 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value) free(dir); free(filelist); - return 0; + return 1; } DPRINTF("Loaded kip1 from SD (size %08X)\n", size); list_append(&ctxt->kip1_list, &mkip1->link); @@ -108,20 +108,20 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value) { free(mkip1); - return 0; + return 1; } DPRINTF("Loaded kip1 from SD (size %08X)\n", size); list_append(&ctxt->kip1_list, &mkip1->link); } - return 1; + return 0; } -int config_kip1patch(launch_ctxt_t *ctxt, const char *value) +int hos_config_kip1patch(launch_ctxt_t *ctxt, const char *value) { int len = strlen(value); if (!len) - return 0; + return 1; if (ctxt->kip1_patches == NULL) { @@ -142,7 +142,8 @@ int config_kip1patch(launch_ctxt_t *ctxt, const char *value) memcpy(&ctxt->kip1_patches[old_len], value, len); ctxt->kip1_patches[old_len + len] = 0; } - return 1; + + return 0; } static int _config_svcperm(launch_ctxt_t *ctxt, const char *value) @@ -152,7 +153,8 @@ static int _config_svcperm(launch_ctxt_t *ctxt, const char *value) DPRINTF("Disabled SVC verification\n"); ctxt->svcperm = true; } - return 1; + + return 0; } static int _config_debugmode(launch_ctxt_t *ctxt, const char *value) @@ -162,7 +164,8 @@ static int _config_debugmode(launch_ctxt_t *ctxt, const char *value) DPRINTF("Enabled Debug mode\n"); ctxt->debugmode = true; } - return 1; + + return 0; } static int _config_stock(launch_ctxt_t *ctxt, const char *value) @@ -172,7 +175,8 @@ static int _config_stock(launch_ctxt_t *ctxt, const char *value) DPRINTF("Enabled stock mode\n"); ctxt->stock = true; } - return 1; + + return 0; } static int _config_emummc_forced(launch_ctxt_t *ctxt, const char *value) @@ -182,7 +186,8 @@ static int _config_emummc_forced(launch_ctxt_t *ctxt, const char *value) DPRINTF("Forced emuMMC\n"); ctxt->emummc_forced = true; } - return 1; + + return 0; } static int _config_kernel_proc_id(launch_ctxt_t *ctxt, const char *value) @@ -192,7 +197,8 @@ static int _config_kernel_proc_id(launch_ctxt_t *ctxt, const char *value) DPRINTF("Enabled kernel process id send/recv patching\n"); ctxt->patch_krn_proc_id = true; } - return 1; + + return 0; } static int _config_dis_exo_user_exceptions(launch_ctxt_t *ctxt, const char *value) @@ -202,7 +208,8 @@ static int _config_dis_exo_user_exceptions(launch_ctxt_t *ctxt, const char *valu DPRINTF("Disabled exosphere user exception handlers\n"); ctxt->exo_ctx.no_user_exceptions = true; } - return 1; + + return 0; } static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value) @@ -212,7 +219,8 @@ static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value) DPRINTF("Enabled user access to PMU\n"); ctxt->exo_ctx.user_pmu = true; } - return 1; + + return 0; } static int _config_exo_usb3_force(launch_ctxt_t *ctxt, const char *value) @@ -225,7 +233,8 @@ static int _config_exo_usb3_force(launch_ctxt_t *ctxt, const char *value) DPRINTF("Enabled USB 3.0\n"); *ctxt->exo_ctx.usb3_force = true; } - return 1; + + return 0; } static int _config_exo_cal0_blanking(launch_ctxt_t *ctxt, const char *value) @@ -238,7 +247,8 @@ static int _config_exo_cal0_blanking(launch_ctxt_t *ctxt, const char *value) DPRINTF("Enabled prodinfo blanking\n"); *ctxt->exo_ctx.cal0_blank = true; } - return 1; + + return 0; } static int _config_exo_cal0_writes_enable(launch_ctxt_t *ctxt, const char *value) @@ -252,7 +262,7 @@ static int _config_exo_cal0_writes_enable(launch_ctxt_t *ctxt, const char *value *ctxt->exo_ctx.cal0_allow_writes_sys = true; } - return 1; + return 0; } static int _config_pkg3(launch_ctxt_t *ctxt, const char *value) @@ -264,9 +274,9 @@ static int _config_exo_fatal_payload(launch_ctxt_t *ctxt, const char *value) { ctxt->exofatal = sd_file_read(value, &ctxt->exofatal_size); if (!ctxt->exofatal) - return 0; + return 1; - return 1; + return 0; } static int _config_ucid(launch_ctxt_t *ctxt, const char *value) @@ -274,7 +284,7 @@ static int _config_ucid(launch_ctxt_t *ctxt, const char *value) // Override uCID if set. ctxt->ucid = atoi(value); - return 1; + return 0; } typedef struct _cfg_handler_t @@ -309,10 +319,10 @@ static const cfg_handler_t _config_handlers[] = { { NULL, NULL }, }; -int parse_boot_config(launch_ctxt_t *ctxt) +int hos_parse_boot_config(launch_ctxt_t *ctxt) { if (!ctxt->cfg) - return 1; + return 0; // Check each config key. LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link) @@ -322,12 +332,12 @@ int parse_boot_config(launch_ctxt_t *ctxt) // If key matches, call its handler. if (!strcmp(_config_handlers[i].key, kv->key)) { - if (!_config_handlers[i].handler(ctxt, kv->val)) + if (_config_handlers[i].handler(ctxt, kv->val)) { gfx_con.mute = false; EPRINTFARGS("Error while loading %s:\n%s", kv->key, kv->val); - return 0; + return 1; } break; @@ -335,5 +345,5 @@ int parse_boot_config(launch_ctxt_t *ctxt) } } - return 1; + return 0; } diff --git a/bootloader/hos/hos_config.h b/bootloader/hos/hos_config.h index f835302a..7b9a119e 100644 --- a/bootloader/hos/hos_config.h +++ b/bootloader/hos/hos_config.h @@ -19,8 +19,8 @@ #include "hos.h" -int parse_boot_config(launch_ctxt_t *ctxt); -int config_kip1patch(launch_ctxt_t *ctxt, const char *value); +int hos_parse_boot_config(launch_ctxt_t *ctxt); +int hos_config_kip1patch(launch_ctxt_t *ctxt, const char *value); #endif diff --git a/bootloader/hos/pkg1.c b/bootloader/hos/pkg1.c index 81ddfab6..29c40eeb 100644 --- a/bootloader/hos/pkg1.c +++ b/bootloader/hos/pkg1.c @@ -195,7 +195,7 @@ const pkg1_id_t *pkg1_identify(u8 *pkg1) return NULL; } -int pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1) +bool pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1) { pk11_hdr_t *hdr; @@ -344,7 +344,7 @@ void pkg1_warmboot_patch(void *hos_ctxt) int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base, u32 fuses_fw, u8 mkey) { launch_ctxt_t *ctxt = (launch_ctxt_t *)hos_ctxt; - int res = 1; + int res = 0; if (h_cfg.t210b01) { @@ -374,7 +374,7 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base, u32 fuses_fw, u8 mke // Check if high enough. if (!warmboot_fw || burnt_fuses > fuses_fw) - res = 0; + res = 1; else { ctxt->warmboot = warmboot_fw + sizeof(u32); diff --git a/bootloader/hos/pkg1.h b/bootloader/hos/pkg1.h index e810d6f4..375bf150 100644 --- a/bootloader/hos/pkg1.h +++ b/bootloader/hos/pkg1.h @@ -162,7 +162,7 @@ typedef struct _nx_bit_t const pkg1_id_t *pkg1_get_latest(); const pkg1_id_t *pkg1_identify(u8 *pkg1); -int pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1); +bool pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1); const u8 *pkg1_unpack(void *wm_dst, u32 *wb_sz, void *sm_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1); void pkg1_secmon_patch(void *hos_ctxt, u32 secmon_base, bool t210b01); void pkg1_warmboot_patch(void *hos_ctxt); diff --git a/bootloader/hos/pkg2.c b/bootloader/hos/pkg2.c index a6365e52..1927f2ea 100644 --- a/bootloader/hos/pkg2.c +++ b/bootloader/hos/pkg2.c @@ -63,101 +63,101 @@ static void parse_external_kip_patches() if (ext_patches_parsed) return; + ext_patches_parsed = true; + LIST_INIT(ini_kip_sections); if (ini_patch_parse(&ini_kip_sections, "bootloader/patches.ini")) + return; + + // Copy ids into a new patchset. + _kip_id_sets = zalloc(sizeof(kip1_id_t) * 256); // Max 256 kip ids. + memcpy(_kip_id_sets, _kip_ids, sizeof(_kip_ids)); + + // Parse patchsets and glue them together. + LIST_FOREACH_ENTRY(ini_kip_sec_t, ini_psec, &ini_kip_sections, link) { - // Copy ids into a new patchset. - _kip_id_sets = zalloc(sizeof(kip1_id_t) * 256); // Max 256 kip ids. - memcpy(_kip_id_sets, _kip_ids, sizeof(_kip_ids)); - - // Parse patchsets and glue them together. - LIST_FOREACH_ENTRY(ini_kip_sec_t, ini_psec, &ini_kip_sections, link) + kip1_id_t *kip = NULL; + bool found = false; + for (u32 kip_idx = 0; kip_idx < _kip_id_sets_cnt + 1; kip_idx++) { - kip1_id_t *kip = NULL; - bool found = false; - for (u32 kip_idx = 0; kip_idx < _kip_id_sets_cnt + 1; kip_idx++) + kip = &_kip_id_sets[kip_idx]; + + // Check if reached the end of predefined list. + if (!kip->name) + break; + + // Check if name and hash match. + if (!strcmp(kip->name, ini_psec->name) && !memcmp(kip->hash, ini_psec->hash, 8)) { - kip = &_kip_id_sets[kip_idx]; - - // Check if reached the end of predefined list. - if (!kip->name) - break; - - // Check if name and hash match. - if (!strcmp(kip->name, ini_psec->name) && !memcmp(kip->hash, ini_psec->hash, 8)) - { - found = true; - break; - } + found = true; + break; } - - if (!kip) - continue; - - // If not found, create a new empty entry. - if (!found) - { - kip->name = ini_psec->name; - memcpy(kip->hash, ini_psec->hash, 8); - kip->patchset = zalloc(sizeof(kip1_patchset_t)); - - _kip_id_sets_cnt++; - } - - kip1_patchset_t *patchsets = (kip1_patchset_t *)zalloc(sizeof(kip1_patchset_t) * 16); // Max 16 patchsets per kip. - - u32 patchset_idx; - for (patchset_idx = 0; kip->patchset[patchset_idx].name != NULL; patchset_idx++) - { - patchsets[patchset_idx].name = kip->patchset[patchset_idx].name; - patchsets[patchset_idx].patches = kip->patchset[patchset_idx].patches; - } - - kip->patchset = patchsets; - bool first_ext_patch = true; - u32 patch_idx = 0; - - // Parse patches and glue them together to a patchset. - kip1_patch_t *patches = zalloc(sizeof(kip1_patch_t) * 32); // Max 32 patches per set. - LIST_FOREACH_ENTRY(ini_patchset_t, pt, &ini_psec->pts, link) - { - if (first_ext_patch) - { - first_ext_patch = false; - patchsets[patchset_idx].name = pt->name; - patchsets[patchset_idx].patches = patches; - } - else if (strcmp(pt->name, patchsets[patchset_idx].name)) - { - // New patchset name found, create a new set. - patchset_idx++; - patch_idx = 0; - patches = zalloc(sizeof(kip1_patch_t) * 32); // Max 32 patches per set. - - patchsets[patchset_idx].name = pt->name; - patchsets[patchset_idx].patches = patches; - } - - if (pt->length) - { - patches[patch_idx].offset = pt->offset; - patches[patch_idx].length = pt->length; - - patches[patch_idx].src_data = (char *)pt->src_data; - patches[patch_idx].dst_data = (char *)pt->dst_data; - } - else - patches[patch_idx].src_data = malloc(1); // Empty patches check. Keep everything else as 0. - - patch_idx++; - } - patchset_idx++; - patchsets[patchset_idx].name = NULL; - patchsets[patchset_idx].patches = NULL; } - } - ext_patches_parsed = true; + if (!kip) + continue; + + // If not found, create a new empty entry. + if (!found) + { + kip->name = ini_psec->name; + memcpy(kip->hash, ini_psec->hash, 8); + kip->patchset = zalloc(sizeof(kip1_patchset_t)); + + _kip_id_sets_cnt++; + } + + kip1_patchset_t *patchsets = (kip1_patchset_t *)zalloc(sizeof(kip1_patchset_t) * 16); // Max 16 patchsets per kip. + + u32 patchset_idx; + for (patchset_idx = 0; kip->patchset[patchset_idx].name != NULL; patchset_idx++) + { + patchsets[patchset_idx].name = kip->patchset[patchset_idx].name; + patchsets[patchset_idx].patches = kip->patchset[patchset_idx].patches; + } + + kip->patchset = patchsets; + bool first_ext_patch = true; + u32 patch_idx = 0; + + // Parse patches and glue them together to a patchset. + kip1_patch_t *patches = zalloc(sizeof(kip1_patch_t) * 32); // Max 32 patches per set. + LIST_FOREACH_ENTRY(ini_patchset_t, pt, &ini_psec->pts, link) + { + if (first_ext_patch) + { + first_ext_patch = false; + patchsets[patchset_idx].name = pt->name; + patchsets[patchset_idx].patches = patches; + } + else if (strcmp(pt->name, patchsets[patchset_idx].name)) + { + // New patchset name found, create a new set. + patchset_idx++; + patch_idx = 0; + patches = zalloc(sizeof(kip1_patch_t) * 32); // Max 32 patches per set. + + patchsets[patchset_idx].name = pt->name; + patchsets[patchset_idx].patches = patches; + } + + if (pt->length) + { + patches[patch_idx].offset = pt->offset; + patches[patch_idx].length = pt->length; + + patches[patch_idx].src_data = (char *)pt->src_data; + patches[patch_idx].dst_data = (char *)pt->dst_data; + } + else + patches[patch_idx].src_data = malloc(1); // Empty patches check. Keep everything else as 0. + + patch_idx++; + } + patchset_idx++; + patchsets[patchset_idx].name = NULL; + patchsets[patchset_idx].patches = NULL; + } } const pkg2_kernel_id_t *pkg2_identify(const u8 *hash) @@ -226,7 +226,7 @@ static void _pkg2_get_newkern_info(u8 *kern_data) } } -bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2) +int pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2) { u8 *ptr; // Check for new pkg2 type. @@ -235,7 +235,7 @@ bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2) _pkg2_get_newkern_info(pkg2->data); if (!pkg2_newkern_ini1_start) - return false; + return 1; ptr = pkg2->data + pkg2_newkern_ini1_start; *new_pkg2 = true; @@ -257,15 +257,15 @@ bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2) DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size); } - return true; + return 0; } -int pkg2_has_kip(link_t *info, u64 tid) +bool pkg2_has_kip(link_t *info, u64 tid) { LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link) if (ki->kip1->tid == tid) - return 1; - return 0; + return true; + return false; } void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1) @@ -371,65 +371,63 @@ static int _decompress_kip(pkg2_kip1_info_t *ki, u32 sectsToDecomp) static int _kipm_inject(const char *kipm_path, char *target_name, pkg2_kip1_info_t *ki) { - if (!strcmp((char *)ki->kip1->name, target_name)) + if (strcmp((char *)ki->kip1->name, target_name)) + return 1; + + u32 size = 0; + u8 *kipm_data = (u8 *)sd_file_read(kipm_path, &size); + if (!kipm_data) + return 1; + + u32 inject_size = size - sizeof(ki->kip1->caps); + u8 *kip_patched_data = (u8 *)malloc(ki->size + inject_size); + + // Copy headers. + memcpy(kip_patched_data, ki->kip1, sizeof(pkg2_kip1_t)); + + pkg2_kip1_t *fs_kip = ki->kip1; + ki->kip1 = (pkg2_kip1_t *)kip_patched_data; + ki->size = ki->size + inject_size; + + // Patch caps. + memcpy(&ki->kip1->caps, kipm_data, sizeof(ki->kip1->caps)); + // Copy our .text data. + memcpy(&ki->kip1->data, kipm_data + sizeof(ki->kip1->caps), inject_size); + + u32 new_offset = 0; + + for (u32 section_idx = 0; section_idx < KIP1_NUM_SECTIONS - 2; section_idx++) { - u32 size = 0; - u8 *kipm_data = (u8 *)sd_file_read(kipm_path, &size); - if (!kipm_data) - return 1; - - u32 inject_size = size - sizeof(ki->kip1->caps); - u8 *kip_patched_data = (u8 *)malloc(ki->size + inject_size); - - // Copy headers. - memcpy(kip_patched_data, ki->kip1, sizeof(pkg2_kip1_t)); - - pkg2_kip1_t *fs_kip = ki->kip1; - ki->kip1 = (pkg2_kip1_t *)kip_patched_data; - ki->size = ki->size + inject_size; - - // Patch caps. - memcpy(&ki->kip1->caps, kipm_data, sizeof(ki->kip1->caps)); - // Copy our .text data. - memcpy(&ki->kip1->data, kipm_data + sizeof(ki->kip1->caps), inject_size); - - u32 new_offset = 0; - - for (u32 section_idx = 0; section_idx < KIP1_NUM_SECTIONS - 2; section_idx++) + if (!section_idx) // .text. { - if (!section_idx) // .text. - { - memcpy(ki->kip1->data + inject_size, fs_kip->data, fs_kip->sections[0].size_comp); - ki->kip1->sections[0].size_decomp += inject_size; - ki->kip1->sections[0].size_comp += inject_size; - } - else // Others. - { - if (section_idx < 3) - memcpy(ki->kip1->data + new_offset + inject_size, fs_kip->data + new_offset, fs_kip->sections[section_idx].size_comp); - ki->kip1->sections[section_idx].offset += inject_size; - } - new_offset += fs_kip->sections[section_idx].size_comp; + memcpy(ki->kip1->data + inject_size, fs_kip->data, fs_kip->sections[0].size_comp); + ki->kip1->sections[0].size_decomp += inject_size; + ki->kip1->sections[0].size_comp += inject_size; } - - // Patch PMC capabilities for 1.0.0. - if (!emu_cfg.fs_ver) + else // Others. { - for (u32 i = 0; i < 0x20; i++) - { - if (ki->kip1->caps[i] == 0xFFFFFFFF) - { - ki->kip1->caps[i] = 0x07000E7F; - break; - } - } + if (section_idx < 3) + memcpy(ki->kip1->data + new_offset + inject_size, fs_kip->data + new_offset, fs_kip->sections[section_idx].size_comp); + ki->kip1->sections[section_idx].offset += inject_size; } - - free(kipm_data); - return 0; + new_offset += fs_kip->sections[section_idx].size_comp; } - return 1; + // Patch PMC capabilities for 1.0.0. + if (!emu_cfg.fs_ver) + { + for (u32 i = 0; i < 0x20; i++) + { + if (ki->kip1->caps[i] == 0xFFFFFFFF) + { + ki->kip1->caps[i] = 0x07000E7F; + break; + } + } + } + + free(kipm_data); + return 0; } const char *pkg2_patch_kips(link_t *info, char *patch_names) diff --git a/bootloader/hos/pkg2.h b/bootloader/hos/pkg2.h index c6ee4dfb..5d6fbebf 100644 --- a/bootloader/hos/pkg2.h +++ b/bootloader/hos/pkg2.h @@ -208,8 +208,8 @@ typedef struct _nx_bc_t { u8 padding2[0xC0]; } nx_bc_t; -bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2); -int pkg2_has_kip(link_t *info, u64 tid); +int pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2); +bool pkg2_has_kip(link_t *info, u64 tid); void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1); void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1); void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1); diff --git a/bootloader/hos/pkg2_ini_kippatch.c b/bootloader/hos/pkg2_ini_kippatch.c index 9567eeff..579f2dc6 100644 --- a/bootloader/hos/pkg2_ini_kippatch.c +++ b/bootloader/hos/pkg2_ini_kippatch.c @@ -104,7 +104,7 @@ int ini_patch_parse(link_t *dst, const char *ini_path) // Open ini. if (f_open(&fp, ini_path, FA_READ) != FR_OK) - return 0; + return 1; lbuf = malloc(512); @@ -176,5 +176,5 @@ int ini_patch_parse(link_t *dst, const char *ini_path) free(lbuf); - return 1; + return 0; } diff --git a/bootloader/hos/pkg3.c b/bootloader/hos/pkg3.c index 2dab4089..51907947 100644 --- a/bootloader/hos/pkg3.c +++ b/bootloader/hos/pkg3.c @@ -96,7 +96,7 @@ static int _pkg3_kip1_skip(char ***pkg3_kip1_skip, u32 *pkg3_kip1_skip_num, char { int len = strlen(value); if (!len || (*pkg3_kip1_skip_num) >= PKG3_KIP_SKIP_MAX) - return 0; + return 1; // Allocate pointer list memory. if (!(*pkg3_kip1_skip)) @@ -116,11 +116,11 @@ static int _pkg3_kip1_skip(char ***pkg3_kip1_skip, u32 *pkg3_kip1_skip_num, char (*pkg3_kip1_skip)[(*pkg3_kip1_skip_num)++] = c + 1; if ((*pkg3_kip1_skip_num) >= PKG3_KIP_SKIP_MAX) - return 0; + return 1; } } - return 1; + return 0; } int parse_pkg3(launch_ctxt_t *ctxt, const char *path) @@ -153,15 +153,15 @@ int parse_pkg3(launch_ctxt_t *ctxt, const char *path) #ifdef HOS_MARIKO_STOCK_SECMON if (stock && emummc_disabled && (pkg1_old || h_cfg.t210b01)) - return 1; + return 0; #else if (stock && emummc_disabled && pkg1_old) - return 1; + return 0; #endif // Try to open PKG3. if (f_open(&fp, path, FA_READ) != FR_OK) - return 0; + return 1; void *pkg3 = malloc(f_size(&fp)); @@ -268,7 +268,7 @@ int parse_pkg3(launch_ctxt_t *ctxt, const char *path) free(pkg3_kip1_skip); - return 1; + return 0; } // Failed. Close and free all. @@ -277,5 +277,5 @@ int parse_pkg3(launch_ctxt_t *ctxt, const char *path) free(pkg3_kip1_skip); free(pkg3); - return 0; + return 1; } diff --git a/bootloader/l4t/l4t.c b/bootloader/l4t/l4t.c index a1aeb030..78531959 100644 --- a/bootloader/l4t/l4t.c +++ b/bootloader/l4t/l4t.c @@ -824,7 +824,7 @@ static int _l4t_sc7_exit_config(bool t210b01) { // Get latest SC7-Exit if needed and setup PA id. launch_ctxt_t hos_ctxt = {0}; - if (!pkg1_warmboot_config(&hos_ctxt, 0, 0, 0)) + if (pkg1_warmboot_config(&hos_ctxt, 0, 0, 0)) { gfx_con.mute = false; gfx_wputs("\nFailed to match warmboot with fuses!\nIf you continue, sleep wont work!"); diff --git a/nyx/nyx_gui/frontend/fe_emummc_tools.c b/nyx/nyx_gui/frontend/fe_emummc_tools.c index 3a1dc542..614fb75b 100644 --- a/nyx/nyx_gui/frontend/fe_emummc_tools.c +++ b/nyx/nyx_gui/frontend/fe_emummc_tools.c @@ -766,11 +766,12 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part int emummc_raw_derive_bis_keys() { - // Generate BIS keys. - hos_bis_keygen(); - u8 *cal0_buff = malloc(SZ_64K); + // Generate BIS keys. + if (hos_bis_keygen()) + goto error; + // Read and decrypt CAL0 for validation of working BIS keys. emmc_set_partition(EMMC_GPP); LIST_INIT(gpt); @@ -786,6 +787,7 @@ int emummc_raw_derive_bis_keys() // Check keys validity. if (memcmp(&cal0->magic, "CAL0", 4)) { +error: // Clear EKS keys. hos_eks_clear(HOS_MKEY_VER_MAX); diff --git a/nyx/nyx_gui/hos/hos.c b/nyx/nyx_gui/hos/hos.c index e08db65f..22021cee 100644 --- a/nyx/nyx_gui/hos/hos.c +++ b/nyx/nyx_gui/hos/hos.c @@ -26,7 +26,6 @@ #include "../config.h" u8 *cal0_buf = NULL; -static u8 *bis_keys = NULL; static const u8 eks_keyseeds[HOS_MKEY_VER_600 - HOS_MKEY_VER_100 + 1][SE_KEY_128_SIZE] = { { 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3 }, // 1.0.0. @@ -173,23 +172,23 @@ static const u8 bis_keyseed[][SE_KEY_128_SIZE] = { { 0x4D, 0x12, 0xE1, 0x4B, 0x2A, 0x47, 0x4C, 0x1C, 0x09, 0xCB, 0x03, 0x59, 0xF0, 0x15, 0xF4, 0xE4 } // BIS 2/3 Tweak seed. }; -bool hos_eks_rw_try(u8 *buf, bool write) +static int _hos_eks_rw_try(u8 *buf, bool write) { for (u32 i = 0; i < 3; i++) { if (!write) { if (sdmmc_storage_read(&sd_storage, 0, 1, buf)) - return true; + return 0; } else { if (sdmmc_storage_write(&sd_storage, 0, 1, buf)) - return true; + return 0; } } - return false; + return 1; } static void _hos_eks_get() @@ -203,7 +202,7 @@ static void _hos_eks_get() { // Read EKS blob. u8 *mbr = malloc(SD_BLOCKSIZE); - if (!hos_eks_rw_try(mbr, false)) + if (_hos_eks_rw_try(mbr, false)) goto out; // Decrypt EKS blob. @@ -241,7 +240,7 @@ static void _hos_eks_save() { // Read EKS blob. u8 *mbr = malloc(SD_BLOCKSIZE); - if (!hos_eks_rw_try(mbr, false)) + if (_hos_eks_rw_try(mbr, false)) { if (new_eks) { @@ -273,7 +272,7 @@ static void _hos_eks_save() // Write EKS blob to SD. memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t)); - hos_eks_rw_try(mbr, true); + _hos_eks_rw_try(mbr, true); free(eks); free(keys); @@ -295,7 +294,7 @@ void hos_eks_clear(u32 mkey) { // Read EKS blob. u8 *mbr = malloc(SD_BLOCKSIZE); - if (!hos_eks_rw_try(mbr, false)) + if (_hos_eks_rw_try(mbr, false)) goto out; // Disable current Master key version. @@ -308,7 +307,7 @@ void hos_eks_clear(u32 mkey) // Write EKS blob to SD. memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t)); - hos_eks_rw_try(mbr, true); + _hos_eks_rw_try(mbr, true); free(eks); out: @@ -331,7 +330,7 @@ int hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt) tsec_keys_t tsec_keys; if (mkey > HOS_MKEY_VER_MAX) - return 0; + return 1; // Do Mariko keygen. if (h_cfg.t210b01) @@ -346,7 +345,7 @@ int hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt) // Derive latest pkg2 key. se_aes_unwrap_key(8, 7, package2_keyseed); - return 1; + return 0; } // Do Erista keygen. @@ -385,7 +384,7 @@ int hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt) if (!tsec_ctxt->fw) { EPRINTF("\nFailed to load thk.bin"); - return 0; + return 1; } tsec_ctxt->size = 0x1F00; @@ -409,7 +408,7 @@ int hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt) if (retries > 15) { EPRINTF("\nFailed to get TSEC keys. Please try again."); - return 0; + return 1; } } @@ -480,7 +479,7 @@ int hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt) se_aes_unwrap_key(11, 13, cmac_keyseed); se_aes_hash_cmac(cmac, SE_KEY_128_SIZE, 11, (void *)eks->ctr, sizeof(eks->ctr) + sizeof(eks->keys)); if (!memcmp(eks->cmac, cmac, SE_KEY_128_SIZE)) - return 0; + return 1; */ se_aes_crypt_ecb(13, DECRYPT, tsec_keys.tsec, cmac_keyseed, SE_KEY_128_SIZE); @@ -521,7 +520,7 @@ int hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt) se_aes_unwrap_key(8, 12, package2_keyseed); } - return 1; + return 0; } static void _hos_validate_mkey() @@ -568,11 +567,9 @@ int hos_bis_keygen() u32 console_key_slot = 15; // HOS_MKEY_VER_MAX. Only for Erista. tsec_ctxt_t tsec_ctxt = {0}; - if (!bis_keys) - bis_keys = malloc(SE_KEY_128_SIZE * 6); - // Run initial keygen. - hos_keygen(NULL, HOS_MKEY_VER_MAX, &tsec_ctxt); + if (hos_keygen(NULL, HOS_MKEY_VER_MAX, &tsec_ctxt)) + return 1; // All Mariko use new device keygen. New keygen was introduced in 4.0.0. // We check unconditionally in order to support downgrades. @@ -613,6 +610,7 @@ int hos_bis_keygen() se_aes_unwrap_key(2, console_key_slot, gen_keyseed_retail); // Clear bis keys storage. + u8 *bis_keys = malloc(SE_KEY_128_SIZE * 6); memset(bis_keys, 0, SE_KEY_128_SIZE * 6); // Generate BIS 0 Keys. @@ -655,7 +653,7 @@ int hos_bis_keygen() se_aes_key_set(4, bis_keys + (4 * SE_KEY_128_SIZE), SE_KEY_128_SIZE); se_aes_key_set(5, bis_keys + (5 * SE_KEY_128_SIZE), SE_KEY_128_SIZE); - return 1; + return 0; } void hos_bis_keys_clear() @@ -672,7 +670,8 @@ int hos_dump_cal0() return 1; // Generate BIS keys - hos_bis_keygen(); + if (hos_bis_keygen()) + return 2; if (!cal0_buf) cal0_buf = malloc(SZ_64K); diff --git a/nyx/nyx_gui/hos/pkg1.c b/nyx/nyx_gui/hos/pkg1.c index 5d52300e..c8c7e95a 100644 --- a/nyx/nyx_gui/hos/pkg1.c +++ b/nyx/nyx_gui/hos/pkg1.c @@ -86,7 +86,7 @@ const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date) return NULL; } -int pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1) +bool pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1) { pk11_hdr_t *hdr; diff --git a/nyx/nyx_gui/hos/pkg1.h b/nyx/nyx_gui/hos/pkg1.h index 4d3ab894..44b7aa10 100644 --- a/nyx/nyx_gui/hos/pkg1.h +++ b/nyx/nyx_gui/hos/pkg1.h @@ -94,7 +94,7 @@ typedef struct _pk11_hdr_t } pk11_hdr_t; const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date); -int pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1); +bool pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1); const u8 *pkg1_unpack(void *wm_dst, void *sm_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1); #endif