diff --git a/source/hos/fss.c b/source/hos/fss.c deleted file mode 100644 index 9bf3930..0000000 --- a/source/hos/fss.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Atmosphère Fusée Secondary Storage parser. - * - * Copyright (c) 2019-2020 CTCaer - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include "fss.h" -#include "hos.h" -#include "../config.h" -#include "../storage/emummc.h" -#include -#include - -#include -#define DPRINTF(...) - -extern hekate_config h_cfg; - -extern bool is_ipl_updated(void *buf, char *path, bool force); - -// FSS0 Magic and Meta header offset. -#define FSS0_MAGIC 0x30535346 -#define FSS0_META_OFFSET 0x4 -#define FSS0_VERSION_0_17_0 0x110000 - -// FSS0 Content Types. -#define CNT_TYPE_FSP 0 -#define CNT_TYPE_EXO 1 // Exosphere (Secure Monitor). -#define CNT_TYPE_WBT 2 // Warmboot (SC7Exit fw). -#define CNT_TYPE_RBT 3 // Rebootstub (Warmboot based reboot fw). -#define CNT_TYPE_SP1 4 // Sept Primary (TSEC and Sept Secondary loader). -#define CNT_TYPE_SP2 5 // Sept Secondary (Acts as pkg11 and derives keys). -#define CNT_TYPE_KIP 6 // KIP1 (Used for replacement or addition). -#define CNT_TYPE_BMP 7 -#define CNT_TYPE_EMC 8 -#define CNT_TYPE_KLD 9 // Kernel Loader. -#define CNT_TYPE_KRN 10 // Kernel. -#define CNT_TYPE_EXF 11 // Exosphere Mariko fatal payload. - -// FSS0 Content Flags. -#define CNT_FLAG0_EXPERIMENTAL BIT(0) - -// FSS0 Meta Header. -typedef struct _fss_meta_t -{ - u32 magic; - u32 size; - u32 crt0_off; - u32 cnt_off; - u32 cnt_count; - u32 hos_ver; - u32 version; - u32 git_rev; -} fss_meta_t; - -// FSS0 Content Header. -typedef struct _fss_content_t -{ - u32 offset; - u32 size; - u8 type; - u8 flags0; - u8 flags1; - u8 flags2; - u32 rsvd1; - char name[0x10]; -} fss_content_t; - -int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt) -{ - FIL fp; - - bool stock = false; - int sept_used = 0; - - // Skip if stock and Exosphere and warmboot are not needed. - if (!sept_ctxt) - { - bool pkg1_old = ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620; - bool emummc_disabled = !emu_cfg.enabled || h_cfg.emummc_force_disable; - - LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link) - { - if (!strcmp("stock", kv->key)) - if (kv->val[0] == '1') - stock = true; - } - -#ifdef HOS_MARIKO_STOCK_SECMON - if (stock && emummc_disabled && (pkg1_old || h_cfg.t210b01)) -#else - if (stock && emummc_disabled && pkg1_old) -#endif - return 1; - } - - if (f_open(&fp, path, FA_READ) != FR_OK) - return 0; - - void *fss = malloc(f_size(&fp)); - - // Read first 1024 bytes of the fss file. - f_read(&fp, fss, 1024, NULL); - - // Get FSS0 Meta header offset. - u32 fss_meta_addr = *(u32 *)(fss + FSS0_META_OFFSET); - fss_meta_t *fss_meta = (fss_meta_t *)(fss + fss_meta_addr); - - // Check if valid FSS0 and parse it. - if (fss_meta->magic == FSS0_MAGIC) - { - bool mariko_not_supported = false; - if (h_cfg.t210b01 && (fss_meta->version < FSS0_VERSION_0_17_0)) - { - gfx_con.mute = false; - mariko_not_supported = true; - } - - gfx_printf("Found FSS0, Atmosphere %d.%d.%d-%08x\n" - "Max HOS supported: %d.%d.%d\n" - "Unpacking and loading components.. ", - fss_meta->version >> 24, (fss_meta->version >> 16) & 0xFF, (fss_meta->version >> 8) & 0xFF, fss_meta->git_rev, - fss_meta->hos_ver >> 24, (fss_meta->hos_ver >> 16) & 0xFF, (fss_meta->hos_ver >> 8) & 0xFF); - - if (mariko_not_supported) - { - EPRINTF("Mariko not supported on < 0.17.0!"); - goto fail; - } - - if (!sept_ctxt) - { - ctxt->atmosphere = true; - ctxt->fss0_hosver = fss_meta->hos_ver; - } - - // Parse FSS0 contents. - fss_content_t *curr_fss_cnt = (fss_content_t *)(fss + fss_meta->cnt_off); - void *content; - for (u32 i = 0; i < fss_meta->cnt_count; i++) - { - content = (void *)(fss + curr_fss_cnt[i].offset); - - // Check if offset is inside limits. - if ((curr_fss_cnt[i].offset + curr_fss_cnt[i].size) > fss_meta->size) - continue; - - // If content is experimental and experimental flag is not enabled, skip it. - if ((curr_fss_cnt[i].flags0 & CNT_FLAG0_EXPERIMENTAL) && !ctxt->fss0_experimental) - continue; - - // Parse content. - if (!sept_ctxt) - { - // Prepare content context. - switch (curr_fss_cnt[i].type) - { - case CNT_TYPE_KIP: - if (stock) - continue; - merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t)); - mkip1->kip1 = content; - list_append(&ctxt->kip1_list, &mkip1->link); - DPRINTF("Loaded %s.kip1 from FSS0 (size %08X)\n", curr_fss_cnt[i].name, curr_fss_cnt[i].size); - break; - - case CNT_TYPE_KRN: - if (stock) - continue; - ctxt->kernel_size = curr_fss_cnt[i].size; - ctxt->kernel = content; - break; - - case CNT_TYPE_EXO: - ctxt->secmon_size = curr_fss_cnt[i].size; - ctxt->secmon = content; - break; - - case CNT_TYPE_EXF: - ctxt->exofatal_size = curr_fss_cnt[i].size; - ctxt->exofatal = content; - break; - - case CNT_TYPE_WBT: - if (h_cfg.t210b01) - continue; - ctxt->warmboot_size = curr_fss_cnt[i].size; - ctxt->warmboot = content; - break; - - default: - continue; - } - - // Load content to launch context. - f_lseek(&fp, curr_fss_cnt[i].offset); - f_read(&fp, content, curr_fss_cnt[i].size, NULL); - } - else - { - // Load sept content directly to launch context. - switch (curr_fss_cnt[i].type) - { - case CNT_TYPE_SP1: - f_lseek(&fp, curr_fss_cnt[i].offset); - f_read(&fp, sept_ctxt->sept_primary, curr_fss_cnt[i].size, NULL); - break; - case CNT_TYPE_SP2: - if (!memcmp(curr_fss_cnt[i].name, (sept_ctxt->kb < KB_FIRMWARE_VERSION_810) ? "septsecondary00" : "septsecondary01", 15)) - { - f_lseek(&fp, curr_fss_cnt[i].offset); - f_read(&fp, sept_ctxt->sept_secondary, curr_fss_cnt[i].size, NULL); - sept_used = 1; - goto out; - } - break; - default: - break; - } - } - } - -out: - gfx_printf("Done!\n"); - f_close(&fp); - - return (!sept_ctxt ? 1 : sept_used); - } - -fail: - f_close(&fp); - free(fss); - - return 0; -} - -int load_sept_from_ffs0(fss0_sept_t *sept_ctxt) -{ - LIST_FOREACH_ENTRY(ini_kv_t, kv, &sept_ctxt->cfg_sec->kvs, link) - { - if (!strcmp("fss0", kv->key)) - return parse_fss(NULL, kv->val, sept_ctxt); - } - - return 0; -} diff --git a/source/hos/fss.h b/source/hos/fss.h deleted file mode 100644 index 3f56d7c..0000000 --- a/source/hos/fss.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2019 CTCaer - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef _FSS_H_ -#define _FSS_H_ - -#include "hos.h" - -typedef struct _fss0_sept_t -{ - u32 kb; - ini_sec_t *cfg_sec; - void *sept_primary; - void *sept_secondary; - -} fss0_sept_t; - -int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt); -int load_sept_from_ffs0(fss0_sept_t *sept_ctxt); - -#endif diff --git a/source/hos/hos.h b/source/hos/hos.h deleted file mode 100644 index b5900c6..0000000 --- a/source/hos/hos.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef _HOS_H_ -#define _HOS_H_ - -#include "pkg1.h" -#include "pkg2.h" -#include -#include -#include - -#include - -#define KB_FIRMWARE_VERSION_100_200 0 -#define KB_FIRMWARE_VERSION_300 1 -#define KB_FIRMWARE_VERSION_301 2 -#define KB_FIRMWARE_VERSION_400 3 -#define KB_FIRMWARE_VERSION_500 4 -#define KB_FIRMWARE_VERSION_600 5 -#define KB_FIRMWARE_VERSION_620 6 -#define KB_FIRMWARE_VERSION_700 7 -#define KB_FIRMWARE_VERSION_810 8 -#define KB_FIRMWARE_VERSION_900 9 -#define KB_FIRMWARE_VERSION_910 10 -#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_910 - -#define HOS_PKG11_MAGIC 0x31314B50 -#define HOS_EKS_MAGIC 0x30534B45 - -// Use official Mariko secmon when in stock. -//#define HOS_MARIKO_STOCK_SECMON - -typedef struct _exo_ctxt_t -{ - bool fs_is_510; - bool no_user_exceptions; - bool user_pmu; - bool *cal0_blank; - bool *cal0_allow_writes_sys; -} exo_ctxt_t; - -typedef struct _hos_eks_keys_t -{ - u8 mkk[0x10]; - u8 fdk[0x10]; -} hos_eks_keys_t; - -typedef struct _hos_eks_bis_keys_t -{ - u8 crypt[0x10]; - u8 tweak[0x10]; -} hos_eks_bis_keys_t; - -typedef struct _hos_eks_mbr_t -{ - u32 magic; - u8 enabled[5]; - u8 enabled_bis; - u8 rsvd[2]; - u32 lot0; - u8 dkg[0x10]; - u8 dkk[0x10]; - hos_eks_keys_t keys[5]; - hos_eks_bis_keys_t bis_keys[3]; -} hos_eks_mbr_t; - -static_assert(sizeof(hos_eks_mbr_t) == 304, "HOS EKS size is wrong!"); - -typedef struct _launch_ctxt_t -{ - void *keyblob; - - void *pkg1; - const pkg1_id_t *pkg1_id; - const pkg2_kernel_id_t *pkg2_kernel_id; - - void *warmboot; - u32 warmboot_size; - void *secmon; - u32 secmon_size; - void *exofatal; - u32 exofatal_size; - - void *pkg2; - u32 pkg2_size; - bool new_pkg2; - - void *kernel; - u32 kernel_size; - - link_t kip1_list; - char* kip1_patches; - - u32 fss0_hosver; - bool svcperm; - bool debugmode; - bool stock; - bool atmosphere; - bool fss0_experimental; - bool emummc_forced; - - exo_ctxt_t exo_ctx; - - ini_sec_t *cfg; -} launch_ctxt_t; - -typedef struct _merge_kip_t -{ - void *kip1; - link_t link; -} merge_kip_t; - -void hos_eks_get(); -void hos_eks_save(u32 kb); -void hos_eks_clear(u32 kb); -int hos_launch(ini_sec_t *cfg); -int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt); - -#endif diff --git a/source/hos/pkg1.c b/source/hos/pkg1.c deleted file mode 100644 index dcfb8e4..0000000 --- a/source/hos/pkg1.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2018 naehrwert - * Copyright (c) 2018 st4rk - * Copyright (c) 2018-2019 CTCaer - * Copyright (c) 2018 balika011 - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include "pkg1.h" -#include - -static const pkg1_id_t _pkg1_ids[] = { - { "20161121", 0 }, //1.0.0 - { "20170210", 0 }, //2.0.0 - 2.3.0 - { "20170519", 1 }, //3.0.0 - { "20170710", 2 }, //3.0.1 - 3.0.2 - { "20170921", 3 }, //4.0.0 - 4.1.0 - { "20180220", 4 }, //5.0.0 - 5.1.0 - { "20180802", 5 }, //6.0.0 - 6.1.0 - { "20181107", 6 }, //6.2.0 - { "20181218", 7 }, //7.0.0 - { "20190208", 7 }, //7.0.1 - { "20190314", 7 }, //8.0.0 - 8.0.1 - { "20190531", 8 }, //8.1.0 - 8.1.1 - { "20190809", 9 }, //9.0.0 - 9.0.1 - { "20191021", 10}, //9.1.0 - 9.2.0 - { "20200303", 10}, //10.0.0 - 10.2.0 - { "20201030", 10}, //11.0.0 - 11.0.1 - { "20210129", 10}, //12.0.0 - 12.0.1 - { "20210422", 10}, //12.0.2 - 12.0.3 - { "20210607", 11}, //12.1.0 - { "20210805", 12}, //13.0.0 - 13.2.0 - { "20220105", 12}, //13.2.1+ - { NULL } //End. -}; - -#define KB_FIRMWARE_VERSION_MAX 11 - -const pkg1_id_t *pkg1_identify(u8 *pkg1) -{ - for (u32 i = 0; _pkg1_ids[i].id; i++) - if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 8)) - return &_pkg1_ids[i]; - - char build_date[15]; - memcpy(build_date, (char *)(pkg1 + 0x10), 14); - build_date[14] = 0; - - if (*(pkg1 + 0xE) != KB_FIRMWARE_VERSION_MAX + 1) { - return NULL; - } - - return &_pkg1_ids[ARRAY_SIZE(_pkg1_ids)-1]; -} diff --git a/source/hos/pkg1.h b/source/hos/pkg1.h deleted file mode 100644 index 81bef20..0000000 --- a/source/hos/pkg1.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2018 naehrwert - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef _PKG1_H_ -#define _PKG1_H_ - -#include - -#define PKG1_MAX_SIZE 0x40000 -#define PKG1_OFFSET 0x100000 -#define KEYBLOB_OFFSET 0x180000 - -typedef struct _bl_hdr_t210b01_t -{ - u8 aes_mac[0x10]; - u8 rsa_sig[0x100]; - u8 salt[0x20]; - u8 sha256[0x20]; - u32 version; - u32 size; - u32 load_addr; - u32 entrypoint; - u8 rsvd[0x10]; -} bl_hdr_t210b01_t; - -typedef struct _pkg1_id_t -{ - const char *id; - u32 kb; -} pkg1_id_t; - -const pkg1_id_t *pkg1_identify(u8 *pkg1); - -#endif diff --git a/source/hos/pkg2.c b/source/hos/pkg2.c deleted file mode 100644 index b80c06d..0000000 --- a/source/hos/pkg2.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer - * Copyright (c) 2018 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include "pkg2.h" -#include -#include -#include -#include - -#include - -u32 pkg2_newkern_ini1_val; -u32 pkg2_newkern_ini1_start; -u32 pkg2_newkern_ini1_end; - -/*#include "util.h" -#define DPRINTF(...) gfx_printf(__VA_ARGS__) -#define DEBUG_PRINTING*/ -#define DPRINTF(...) - -static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1) -{ - u32 size = sizeof(pkg2_kip1_t); - for (u32 j = 0; j < KIP1_NUM_SECTIONS; j++) - size += kip1->sections[j].size_comp; - return size; -} - -void pkg2_get_newkern_info(u8 *kern_data) -{ - u32 pkg2_newkern_ini1_off = 0; - pkg2_newkern_ini1_start = 0; - - // Find static OP offset that is close to INI1 offset. - u32 counter_ops = 0x100; - while (counter_ops) - { - if (*(u32 *)(kern_data + 0x100 - counter_ops) == PKG2_NEWKERN_GET_INI1_HEURISTIC) - { - pkg2_newkern_ini1_off = 0x100 - counter_ops + 12; // OP found. Add 12 for the INI1 offset. - break; - } - - counter_ops -= 4; - } - - // Offset not found? - if (!counter_ops) - return; - - u32 info_op = *(u32 *)(kern_data + pkg2_newkern_ini1_off); - pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + pkg2_newkern_ini1_off; // Parse ADR and PC. - - pkg2_newkern_ini1_start = *(u32 *)(kern_data + pkg2_newkern_ini1_val); - pkg2_newkern_ini1_end = *(u32 *)(kern_data + pkg2_newkern_ini1_val + 0x8); - } - -bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2) -{ - u8 *ptr; - // Check for new pkg2 type. - if (!pkg2->sec_size[PKG2_SEC_INI1]) - { - pkg2_get_newkern_info(pkg2->data); - - if (!pkg2_newkern_ini1_start) - return false; - - ptr = pkg2->data + pkg2_newkern_ini1_start; - *new_pkg2 = true; - } - else - ptr = pkg2->data + pkg2->sec_size[PKG2_SEC_KERNEL]; - - pkg2_ini1_t *ini1 = (pkg2_ini1_t *)ptr; - ptr += sizeof(pkg2_ini1_t); - - for (u32 i = 0; i < ini1->num_procs; i++) - { - pkg2_kip1_t *kip1 = (pkg2_kip1_t *)ptr; - pkg2_kip1_info_t *ki = (pkg2_kip1_info_t *)malloc(sizeof(pkg2_kip1_info_t)); - ki->kip1 = kip1; - ki->size = _pkg2_calc_kip1_size(kip1); - list_append(info, &ki->link); - ptr += ki->size; -DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size); - } - - return true; -} - -int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp) -{ - u32 compClearMask = ~sectsToDecomp; - if ((ki->kip1->flags & compClearMask) == ki->kip1->flags) - return 0; // Already decompressed, nothing to do. - - pkg2_kip1_t hdr; - memcpy(&hdr, ki->kip1, sizeof(hdr)); - - unsigned int newKipSize = sizeof(hdr); - for (u32 sectIdx = 0; sectIdx < KIP1_NUM_SECTIONS; sectIdx++) - { - u32 sectCompBit = 1u << sectIdx; - // For compressed, cant get actual decompressed size without doing it, so use safe "output size". - if (sectIdx < 3 && (sectsToDecomp & sectCompBit) && (hdr.flags & sectCompBit)) - newKipSize += hdr.sections[sectIdx].size_decomp; - else - newKipSize += hdr.sections[sectIdx].size_comp; - } - - pkg2_kip1_t* newKip = malloc(newKipSize); - unsigned char* dstDataPtr = newKip->data; - const unsigned char* srcDataPtr = ki->kip1->data; - for (u32 sectIdx = 0; sectIdx < KIP1_NUM_SECTIONS; sectIdx++) - { - u32 sectCompBit = 1u << sectIdx; - // Easy copy path for uncompressed or ones we dont want to uncompress. - if (sectIdx >= 3 || !(sectsToDecomp & sectCompBit) || !(hdr.flags & sectCompBit)) - { - unsigned int dataSize = hdr.sections[sectIdx].size_comp; - if (dataSize == 0) - continue; - - memcpy(dstDataPtr, srcDataPtr, dataSize); - srcDataPtr += dataSize; - dstDataPtr += dataSize; - continue; - } - - unsigned int compSize = hdr.sections[sectIdx].size_comp; - unsigned int outputSize = hdr.sections[sectIdx].size_decomp; - //gfx_printf("Decomping %s KIP1 sect %d of size %d...\n", (const char*)hdr.name, sectIdx, compSize); - if (blz_uncompress_srcdest(srcDataPtr, compSize, dstDataPtr, outputSize) == 0) - { - gfx_printf("%kERROR decomping sect %d of %s KIP!%k\n", 0xFFFF0000, sectIdx, (char*)hdr.name, 0xFFCCCCCC); - free(newKip); - - return 1; - } - else - { - DPRINTF("Done! Decompressed size is %d!\n", outputSize); - } - hdr.sections[sectIdx].size_comp = outputSize; - srcDataPtr += compSize; - dstDataPtr += outputSize; - } - - hdr.flags &= compClearMask; - memcpy(newKip, &hdr, sizeof(hdr)); - newKipSize = dstDataPtr-(unsigned char*)(newKip); - - free(ki->kip1); - ki->kip1 = newKip; - ki->size = newKipSize; - - return 0; -} - -pkg2_hdr_t *pkg2_decrypt(void *data) -{ - u8 *pdata = (u8 *)data; - - // Skip signature. - pdata += 0x100; - - pkg2_hdr_t *hdr = (pkg2_hdr_t *)pdata; - - // Skip header. - pdata += sizeof(pkg2_hdr_t); - - // Decrypt header. - se_aes_crypt_ctr(8, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr); - //gfx_hexdump((u32)hdr, hdr, 0x100); - - if (hdr->magic != PKG2_MAGIC) - return NULL; - - for (u32 i = 0; i < 4; i++) - { -DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]); - if (!hdr->sec_size[i]) - continue; - - se_aes_crypt_ctr(8, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]); - //gfx_hexdump((u32)pdata, pdata, 0x100); - - pdata += hdr->sec_size[i]; - } - - return hdr; -} diff --git a/source/hos/pkg2.h b/source/hos/pkg2.h deleted file mode 100644 index e416fba..0000000 --- a/source/hos/pkg2.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef _PKG2_H_ -#define _PKG2_H_ - -#include -#include - -#define PKG2_MAGIC 0x31324B50 -#define PKG2_SEC_BASE 0x80000000 -#define PKG2_SEC_KERNEL 0 -#define PKG2_SEC_INI1 1 - -#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // Offset of OP + 12 is the INI1 offset. - -extern u32 pkg2_newkern_ini1_val; -extern u32 pkg2_newkern_ini1_start; -extern u32 pkg2_newkern_ini1_end; - -typedef struct _kernel_patch_t -{ - u32 id; - u32 off; - u32 val; - u32 *ptr; -} kernel_patch_t; - -typedef struct _pkg2_hdr_t -{ - u8 ctr[0x10]; - u8 sec_ctr[0x40]; - u32 magic; - u32 base; - u32 pad0; - u8 pkg2_ver; - u8 bl_ver; - u16 pad1; - u32 sec_size[4]; - u32 sec_off[4]; - u8 sec_sha256[0x80]; - u8 data[]; -} pkg2_hdr_t; - -typedef struct _pkg2_ini1_t -{ - u32 magic; - u32 size; - u32 num_procs; - u32 pad; -} pkg2_ini1_t; - -typedef struct _pkg2_kip1_sec_t -{ - u32 offset; - u32 size_decomp; - u32 size_comp; - u32 attrib; -} pkg2_kip1_sec_t; - -#define KIP1_NUM_SECTIONS 6 - -typedef struct _pkg2_kip1_t -{ - u32 magic; - u8 name[12]; - u64 tid; - u32 proc_cat; - u8 main_thrd_prio; - u8 def_cpu_core; - u8 res; - u8 flags; - pkg2_kip1_sec_t sections[KIP1_NUM_SECTIONS]; - u32 caps[0x20]; - u8 data[]; -} pkg2_kip1_t; - -typedef struct _pkg2_kip1_info_t -{ - pkg2_kip1_t *kip1; - u32 size; - link_t link; -} pkg2_kip1_info_t; - -typedef struct _pkg2_kernel_id_t -{ - u8 hash[8]; - kernel_patch_t *kernel_patchset; -} pkg2_kernel_id_t; - -bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2); -int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp); -pkg2_hdr_t *pkg2_decrypt(void *data); - -#endif diff --git a/source/keys/key_sources.inl b/source/keys/key_sources.inl index 91e640d..5afd363 100644 --- a/source/keys/key_sources.inl +++ b/source/keys/key_sources.inl @@ -16,7 +16,19 @@ // Sha256 hash of the null string. #include -#include "../hos/hos.h" + +#define KB_FIRMWARE_VERSION_100_200 0 +#define KB_FIRMWARE_VERSION_300 1 +#define KB_FIRMWARE_VERSION_301 2 +#define KB_FIRMWARE_VERSION_400 3 +#define KB_FIRMWARE_VERSION_500 4 +#define KB_FIRMWARE_VERSION_600 5 +#define KB_FIRMWARE_VERSION_620 6 +#define KB_FIRMWARE_VERSION_700 7 +#define KB_FIRMWARE_VERSION_810 8 +#define KB_FIRMWARE_VERSION_900 9 +#define KB_FIRMWARE_VERSION_910 10 +#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_910 static const u8 null_hash[0x20] __attribute__((aligned(4))) = { 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, diff --git a/source/keys/keys.c b/source/keys/keys.c index b13041b..369b711 100644 --- a/source/keys/keys.c +++ b/source/keys/keys.c @@ -3,7 +3,6 @@ #include #include #include "../config.h" -#include "../hos/pkg1.h" #include "../storage/emummc.h" #include "../gfx/gfx.h" #include "../tegraexplorer/tconf.h" @@ -17,6 +16,23 @@ extern hekate_config h_cfg; #define DPRINTF(x) #define TSEC_KEY_DATA_OFFSET 0x300 +#define PKG1_MAX_SIZE 0x40000 +#define PKG1_OFFSET 0x100000 +#define KEYBLOB_OFFSET 0x180000 + +typedef struct _bl_hdr_t210b01_t +{ + u8 aes_mac[0x10]; + u8 rsa_sig[0x100]; + u8 salt[0x20]; + u8 sha256[0x20]; + u32 version; + u32 size; + u32 load_addr; + u32 entrypoint; + u8 rsvd[0x10]; +} bl_hdr_t210b01_t; + static int _key_exists(const void *data) { return memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) != 0; }; @@ -155,7 +171,7 @@ static int _derive_master_keys_from_keyblobs(key_derivation_ctx_t *keys) { return false; } -static bool _derive_tsec_keys(tsec_ctxt_t *tsec_ctxt, u32 kb, key_derivation_ctx_t *keys) { +static bool _derive_tsec_keys(tsec_ctxt_t *tsec_ctxt, key_derivation_ctx_t *keys) { tsec_ctxt->fw = _find_tsec_fw(tsec_ctxt->pkg1); if (!tsec_ctxt->fw) { DPRINTF("Unable to locate TSEC firmware."); @@ -194,7 +210,7 @@ static bool _derive_tsec_keys(tsec_ctxt_t *tsec_ctxt, u32 kb, key_derivation_ctx return true; } -static ALWAYS_INLINE u8 *_read_pkg1(const pkg1_id_t **pkg1_id) { +static ALWAYS_INLINE u8 *_read_pkg1() { /* if (emummc_storage_init_mmc(&emmc_storage, &emmc_sdmmc)) { @@ -217,15 +233,9 @@ static ALWAYS_INLINE u8 *_read_pkg1(const pkg1_id_t **pkg1_id) { } u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header. - *pkg1_id = pkg1_identify(pkg1 + pk1_offset); - if (!*pkg1_id) { - DPRINTF("Unknown pkg1 version.\n Make sure you have the latest Lockpick_RCM.\n If a new firmware version just came out,\n Lockpick_RCM must be updated.\n Check Github for new release."); - //gfx_hexdump(0, pkg1 + pk1_offset, 0x20); - char pkg1txt[16] = {0}; - memcpy(pkg1txt, pkg1 + pk1_offset + 0x10, 14); - gfx_printf("Unknown pkg1 version\nMake sure you have the latest version of TegraExplorer\n\nPKG1: '%s'\n", pkg1txt); - return NULL; - } + char *pkg1txt = calloc(16, 1); + memcpy(pkg1txt, pkg1 + pk1_offset + 0x10, 14); + TConf.pkg1ID = pkg1txt; return pkg1; } @@ -236,20 +246,16 @@ int DumpKeys(){ if (h_cfg.t210b01) // i'm not even attempting to dump on mariko return 2; - const pkg1_id_t *pkg1_id; - u8 *pkg1 = _read_pkg1(&pkg1_id); + u8 *pkg1 = _read_pkg1(); if (!pkg1) { return 1; } - TConf.pkg1ID = pkg1_id->id; - TConf.pkg1ver = (u8)pkg1_id->kb; - bool res = true; tsec_ctxt_t tsec_ctxt; tsec_ctxt.pkg1 = pkg1; - res =_derive_tsec_keys(&tsec_ctxt, pkg1_id->kb, &dumpedKeys); + res =_derive_tsec_keys(&tsec_ctxt, &dumpedKeys); free(pkg1); if (res == false) { diff --git a/source/tegraexplorer/mainmenu.c b/source/tegraexplorer/mainmenu.c index 73e30af..158db4d 100644 --- a/source/tegraexplorer/mainmenu.c +++ b/source/tegraexplorer/mainmenu.c @@ -112,7 +112,7 @@ void ViewKeys(){ fuseCount++; } - gfx_printf("\n\nPkg1 ID: '%s' (kb %d)\nFuse count: %d", TConf.pkg1ID, TConf.pkg1ver, fuseCount); + gfx_printf("\n\nPkg1 ID: '%s'\nFuse count: %d", TConf.pkg1ID, fuseCount); hidWait(); } diff --git a/source/tegraexplorer/tconf.h b/source/tegraexplorer/tconf.h index 0e0ea3b..1a026b3 100644 --- a/source/tegraexplorer/tconf.h +++ b/source/tegraexplorer/tconf.h @@ -33,7 +33,6 @@ typedef struct { u16 optionUnion; }; const char *pkg1ID; - u8 pkg1ver; char *scriptCWD; } TConf_t; diff --git a/source/tegraexplorer/tools.c b/source/tegraexplorer/tools.c index b71a0bd..cb77950 100644 --- a/source/tegraexplorer/tools.c +++ b/source/tegraexplorer/tools.c @@ -16,104 +16,6 @@ #include #include -void DumpSysFw(){ - char sysPath[25 + 36 + 3 + 1]; // 24 for "bis:/Contents/registered", 36 for ncaName.nca, 3 for /00, and 1 to make sure :) - char *baseSdPath; - - u32 timer = get_tmr_s(); - - if (!sd_mount()) - return; - - if (connectMMC(MMC_CONN_EMMC)) - return; - - if (!TConf.keysDumped) - return; - - ErrCode_t err = mountMMCPart("SYSTEM"); - if (err.err){ - DrawError(err); - return; - } - - baseSdPath = malloc(36 + 16); - s_printf(baseSdPath, "sd:/tegraexplorer/Firmware/%d (%s)", TConf.pkg1ver, TConf.pkg1ID); - int baseSdPathLen = strlen(baseSdPath); - - f_mkdir("sd:/tegraexplorer"); - f_mkdir("sd:/tegraexplorer/Firmware"); - - gfx_clearscreen(); - - gfx_printf("Pkg1 id: '%s', kb %d\n", TConf.pkg1ID, TConf.pkg1ver); - if (FileExists(baseSdPath)){ - SETCOLOR(COLOR_ORANGE, COLOR_DEFAULT); - gfx_printf("Destination already exists. Replace? "); - if (!MakeYesNoHorzMenu(3, COLOR_DEFAULT)){ - free(baseSdPath); - return; - } - RESETCOLOR; - gfx_printf("\nDeleting... "); - FolderDelete(baseSdPath); - gfx_putc('\n'); - } - - f_mkdir(baseSdPath); - - gfx_printf("Out: %s\nReading entries...\n", baseSdPath); - int readRes = 0; - Vector_t fileVec = ReadFolder("bis:/Contents/registered", &readRes); - if (readRes){ - DrawError(newErrCode(readRes)); - free(baseSdPath); - return; - } - - gfx_printf("Starting dump...\n"); - SETCOLOR(COLOR_GREEN, COLOR_DEFAULT); - - int res = 0; - int total = 1; - vecDefArray(FSEntry_t*, fsEntries, fileVec); - for (int i = 0; i < fileVec.count; i++){ - s_printf(sysPath, (fsEntries[i].isDir) ? "%s/%s/00" : "%s/%s", "bis:/Contents/registered", fsEntries[i].name); - int contentType = GetNcaType(sysPath); - - if (contentType < 0){ - res = 1; - break; - } - - char *sdPath = malloc(baseSdPathLen + 45); - s_printf(sdPath, "%s/%s", baseSdPath, fsEntries[i].name); - if (contentType == Meta) - memcpy(sdPath + strlen(sdPath) - 4, ".cnmt.nca", 10); - - gfx_printf("[%3d / %3d] %s\r", total, fileVec.count, fsEntries[i].name); - total++; - err = FileCopy(sysPath, sdPath, 0); - free(sdPath); - if (err.err){ - DrawError(err); - res = 1; - break; - } - } - clearFileVector(&fileVec); - - RESETCOLOR; - - if (res){ - gfx_printf("\nDump failed...\n"); - } - - gfx_printf("\n\nDone! Time taken: %ds\nPress any key to exit", get_tmr_s() - timer); - free(baseSdPath); - hidWait(); -} - extern sdmmc_storage_t sd_storage; MenuEntry_t FatAndEmu[] = {