diff --git a/source/config/config.c b/source/config/config.c
index adcfee4..34b148b 100644
--- a/source/config/config.c
+++ b/source/config/config.c
@@ -45,7 +45,6 @@ void set_default_configuration()
h_cfg.brand = NULL;
h_cfg.tagline = NULL;
h_cfg.errors = 0;
- h_cfg.eks = NULL;
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
h_cfg.rcm_patched = true;
h_cfg.emummc_force_disable = false;
diff --git a/source/config/config.h b/source/config/config.h
index 012fea9..0410a7e 100644
--- a/source/config/config.h
+++ b/source/config/config.h
@@ -17,7 +17,6 @@
#ifndef _CONFIG_H_
#define _CONFIG_H_
-#include "../hos/hos.h"
#include "../utils/types.h"
typedef struct _hekate_config
@@ -39,7 +38,6 @@ typedef struct _hekate_config
bool rcm_patched;
u32 sbar_time_keeping;
u32 errors;
- hos_eks_mbr_t *eks;
} hekate_config;
void set_default_configuration();
diff --git a/source/hos/fss.c b/source/hos/fss.c
deleted file mode 100644
index b359880..0000000
--- a/source/hos/fss.c
+++ /dev/null
@@ -1,247 +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/config.h"
-#include "../libs/fatfs/ff.h"
-#include "../mem/heap.h"
-#include "../storage/emummc.h"
-#include "../storage/nx_sd.h"
-
-#include "../gfx/gfx.h"
-#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
-
-// 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.
-
-// FSS0 Content Flags.
-#define CNT_FLAG0_EXPERIMENTAL (1 << 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;
-
-static void _update_r2p(const char *path)
-{
- char *r2p_path = malloc(256);
- u32 path_len = strlen(path);
- strcpy(r2p_path, path);
-
- while(path_len)
- {
- if ((r2p_path[path_len - 1] == '/') || (r2p_path[path_len - 1] == 0x5C))
- {
- r2p_path[path_len] = 0;
- strcat(r2p_path, "reboot_payload.bin");
- u8 *r2p_payload = sd_file_read(r2p_path, NULL);
-
- is_ipl_updated(r2p_payload, r2p_path, h_cfg.updater2p ? true : false);
-
- free(r2p_payload);
- break;
- }
- path_len--;
- }
-
- free(r2p_path);
-}
-
-int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
-{
- FIL fp;
-
- bool stock = false;
- int sept_used = 0;
-
- if (!sept_ctxt)
- {
- LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link)
- {
- if (!strcmp("stock", kv->key))
- if (kv->val[0] == '1')
- stock = true;
- }
-
- if (stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable))
- 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)
- {
- 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 (!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_enable_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_EXO:
- ctxt->secmon_size = curr_fss_cnt[i].size;
- ctxt->secmon = content;
- break;
- case CNT_TYPE_WBT:
- 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);
-
- _update_r2p(path);
-
- return (!sept_ctxt ? 1 : sept_used);
- }
-
- 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.c b/source/hos/hos.c
deleted file mode 100644
index 2ef2d4b..0000000
--- a/source/hos/hos.c
+++ /dev/null
@@ -1,953 +0,0 @@
-/*
- * Copyright (c) 2018 naehrwert
- * Copyright (c) 2018 st4rk
- * Copyright (c) 2018 Ced2911
- * Copyright (c) 2018-2020 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 "hos.h"
-#include "hos_config.h"
-#include "sept.h"
-#include "secmon_exo.h"
-#include "../config/config.h"
-#include "../gfx/di.h"
-#include "../mem/heap.h"
-#include "../mem/mc.h"
-#include "../mem/minerva.h"
-#include "../sec/se.h"
-#include "../sec/se_t210.h"
-#include "../sec/tsec.h"
-#include "../soc/bpmp.h"
-#include "../soc/cluster.h"
-#include "../soc/fuse.h"
-#include "../soc/pmc.h"
-#include "../soc/smmu.h"
-#include "../soc/t210.h"
-#include "../storage/emummc.h"
-#include "../storage/nx_emmc.h"
-#include "../storage/nx_sd.h"
-#include "../storage/sdmmc.h"
-#include "../utils/util.h"
-#include "../gfx/gfx.h"
-
-extern hekate_config h_cfg;
-
-//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
-#define DPRINTF(...)
-
-#define EHPRINTFARGS(text, args...) \
- ({ display_backlight_brightness(h_cfg.backlight, 1000); \
- gfx_con.mute = false; \
- gfx_printf("%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC); })
-
-#define PKG2_LOAD_ADDR 0xA9800000
-
- // Secmon mailbox.
-#define SECMON_MB_ADDR 0x40002EF8
-#define SECMON7_MB_ADDR 0x400000F8
-typedef struct _secmon_mailbox_t
-{
- // < 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot.
- // >= 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM ready, 4: pkg2 ready and continue boot.
- u32 in;
- // Non-zero: Secmon ready.
- u32 out;
-} secmon_mailbox_t;
-
-static const u8 keyblob_keyseeds[][0x10] = {
- { 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3 }, //1.0.0
- { 0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC }, //3.0.0
- { 0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B }, //3.0.1
- { 0x2D, 0x1F, 0x48, 0x80, 0xED, 0xEC, 0xED, 0x3E, 0x3C, 0xF2, 0x48, 0xB5, 0x65, 0x7D, 0xF7, 0xBE }, //4.0.0
- { 0xBB, 0x5A, 0x01, 0xF9, 0x88, 0xAF, 0xF5, 0xFC, 0x6C, 0xFF, 0x07, 0x9E, 0x13, 0x3C, 0x39, 0x80 }, //5.0.0
- { 0xD8, 0xCC, 0xE1, 0x26, 0x6A, 0x35, 0x3F, 0xCC, 0x20, 0xF3, 0x2D, 0x3B, 0x51, 0x7D, 0xE9, 0xC0 } //6.0.0
-};
-
-static const u8 cmac_keyseed[0x10] =
- { 0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5 };
-
-static const u8 master_keyseed_retail[0x10] =
- { 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C };
-
-static const u8 console_keyseed[0x10] =
- { 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
-
-const u8 package2_keyseed[] =
- { 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
-
-static const u8 master_keyseed_4xx_5xx_610[0x10] =
- { 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 };
-
-static const u8 master_keyseed_620[0x10] =
- { 0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A };
-
-static const u8 console_keyseed_4xx_5xx[0x10] =
- { 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
-
-static void _hos_crit_error(const char *text)
-{
- gfx_con.mute = false;
- gfx_printf("%k%s%k\n", 0xFFFF0000, text, 0xFFCCCCCC);
-
- display_backlight_brightness(h_cfg.backlight, 1000);
-}
-
-static void _se_lock(bool lock_se)
-{
- if (lock_se)
- {
- for (u32 i = 0; i < 16; i++)
- se_key_acc_ctrl(i, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
-
- for (u32 i = 0; i < 2; i++)
- se_rsa_acc_ctrl(i, SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG);
- SE(SE_TZRAM_SECURITY_0) = 0; // Make SE TZRAM secure only.
- SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = 0; // Make all key access regs secure only.
- SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = 0; // Make all RSA access regs secure only.
- SE(SE_SECURITY_0) &= 0xFFFFFFFB; // Make access lock regs secure only.
- }
-
- memset((void *)IPATCH_BASE, 0, 14 * sizeof(u32));
- SB(SB_CSR) = SB_CSR_PIROM_DISABLE;
-
- // This is useful for documenting the bits in the SE config registers, so we can keep it around.
- /*gfx_printf("SE(SE_SECURITY_0) = %08X\n", SE(SE_SECURITY_0));
- gfx_printf("SE(0x4) = %08X\n", SE(0x4));
- gfx_printf("SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = %08X\n", SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET));
- gfx_printf("SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = %08X\n", SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET));
- for(u32 i = 0; i < 16; i++)
- gfx_printf("%02X ", SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + i * 4) & 0xFF);
- gfx_putc('\n');
- for(u32 i = 0; i < 2; i++)
- gfx_printf("%02X ", SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + i * 4) & 0xFF);
- gfx_putc('\n');
- gfx_hexdump(SE_BASE, (void *)SE_BASE, 0x400);*/
-}
-
-void _pmc_scratch_lock(u32 kb)
-{
- switch (kb)
- {
- case KB_FIRMWARE_VERSION_100_200:
- case KB_FIRMWARE_VERSION_300:
- case KB_FIRMWARE_VERSION_301:
- PMC(APBDEV_PMC_SEC_DISABLE) = 0x7FFFF3;
- PMC(APBDEV_PMC_SEC_DISABLE2) = 0xFFFFFFFF;
- PMC(APBDEV_PMC_SEC_DISABLE3) = 0xFFAFFFFF;
- PMC(APBDEV_PMC_SEC_DISABLE4) = 0xFFFFFFFF;
- PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF;
- PMC(APBDEV_PMC_SEC_DISABLE6) = 0xFFFFFFFF;
- PMC(APBDEV_PMC_SEC_DISABLE7) = 0xFFFFFFFF;
- PMC(APBDEV_PMC_SEC_DISABLE8) = 0xFFAAFFFF;
- break;
- default:
- PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF;
- PMC(APBDEV_PMC_SEC_DISABLE4) |= 0x3F3FFFFF;
- PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF;
- PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xF3FFC00F;
- PMC(APBDEV_PMC_SEC_DISABLE7) |= 0x3FFFFF;
- PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF;
- break;
- }
-}
-
-void _sysctr0_reset()
-{
- SYSCTR0(SYSCTR0_CNTCR) = 0;
- SYSCTR0(SYSCTR0_COUNTERID0) = 0;
- SYSCTR0(SYSCTR0_COUNTERID1) = 0;
- SYSCTR0(SYSCTR0_COUNTERID2) = 0;
- SYSCTR0(SYSCTR0_COUNTERID3) = 0;
- SYSCTR0(SYSCTR0_COUNTERID4) = 0;
- SYSCTR0(SYSCTR0_COUNTERID5) = 0;
- SYSCTR0(SYSCTR0_COUNTERID6) = 0;
- SYSCTR0(SYSCTR0_COUNTERID7) = 0;
- SYSCTR0(SYSCTR0_COUNTERID8) = 0;
- SYSCTR0(SYSCTR0_COUNTERID9) = 0;
- SYSCTR0(SYSCTR0_COUNTERID10) = 0;
- SYSCTR0(SYSCTR0_COUNTERID11) = 0;
-}
-
-void hos_eks_get()
-{
- // Check if EKS already found and parsed.
- if (!h_cfg.eks)
- {
- u8 *mbr = calloc(512 , 1);
-
- // Read EKS blob.
- sdmmc_storage_read(&sd_storage, 0, 1, mbr);
-
- // Decrypt EKS blob.
- hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x10);
- se_aes_crypt_ecb(14, 0, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
-
- // Check if valid and for this unit.
- if (eks->enabled &&
- eks->magic == HOS_EKS_MAGIC &&
- eks->magic2 == HOS_EKS_MAGIC &&
- eks->sbk_low[0] == FUSE(FUSE_PRIVATE_KEY0) &&
- eks->sbk_low[1] == FUSE(FUSE_PRIVATE_KEY1))
- {
- h_cfg.eks = eks;
- return;
- }
-
- free(mbr);
- }
-}
-
-void hos_eks_save(u32 kb)
-{
- if (kb >= KB_FIRMWARE_VERSION_700)
- {
- // Only 6 Master keys for now.
- u8 key_idx = kb - KB_FIRMWARE_VERSION_700;
- if (key_idx > 5)
- return;
-
- if (!h_cfg.eks)
- h_cfg.eks = calloc(512 , 1);
-
- // If matching blob doesn't exist, create it.
- if (!(h_cfg.eks->enabled & (1 << key_idx)))
- {
- // Get keys.
- u8 *keys = (u8 *)calloc(0x1000, 1);
- se_get_aes_keys(keys + 0x800, keys, 0x10);
-
- // Set magic and personalized info.
- h_cfg.eks->magic = HOS_EKS_MAGIC;
- h_cfg.eks->magic2 = HOS_EKS_MAGIC;
- h_cfg.eks->enabled |= 1 << key_idx;
- h_cfg.eks->sbk_low[0] = FUSE(FUSE_PRIVATE_KEY0);
- h_cfg.eks->sbk_low[1] = FUSE(FUSE_PRIVATE_KEY1);
-
- // Copy new keys.
- memcpy(h_cfg.eks->keys[key_idx].dkg, keys + 10 * 0x10, 0x10);
- memcpy(h_cfg.eks->keys[key_idx].mkk, keys + 12 * 0x10, 0x10);
- memcpy(h_cfg.eks->keys[key_idx].fdk, keys + 13 * 0x10, 0x10);
- memcpy(h_cfg.eks->keys[key_idx].dkk, keys + 15 * 0x10, 0x10);
-
- // Encrypt EKS.
- u8 *eks = calloc(512 , 1);
- memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
- se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
-
- // Write EKS to SD.
- u8 *mbr = calloc(512 , 1);
- sdmmc_storage_read(&sd_storage, 0, 1, mbr);
- memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t));
- sdmmc_storage_write(&sd_storage, 0, 1, mbr);
-
- free(eks);
- free(mbr);
- free(keys);
- }
- }
-}
-
-void hos_eks_clear(u32 kb)
-{
- if (h_cfg.eks && kb >= KB_FIRMWARE_VERSION_700)
- {
- // Check if Current Master key is enabled.
- u8 key_idx = kb - KB_FIRMWARE_VERSION_700;
- if (h_cfg.eks->enabled & (1 << key_idx))
- {
- // Disable current Master key version.
- h_cfg.eks->enabled &= ~(1 << key_idx);
-
- // Encrypt EKS.
- u8 *eks = calloc(512 , 1);
- memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
- se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
-
- // Write EKS to SD.
- u8 *mbr = calloc(512 , 1);
- sdmmc_storage_read(&sd_storage, 0, 1, mbr);
- memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t));
- sdmmc_storage_write(&sd_storage, 0, 1, mbr);
-
- free(eks);
- free(mbr);
- }
- }
-}
-
-int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt)
-{
- u8 tmp[0x20];
- u32 retries = 0;
-
- if (kb > KB_FIRMWARE_VERSION_MAX)
- return 0;
-
- if (kb <= KB_FIRMWARE_VERSION_600)
- tsec_ctxt->size = 0xF00;
- else if (kb == KB_FIRMWARE_VERSION_620)
- tsec_ctxt->size = 0x2900;
- else if (kb == KB_FIRMWARE_VERSION_700)
- tsec_ctxt->size = 0x3000;
- else
- tsec_ctxt->size = 0x3300;
-
- // Prepare smmu tsec page for 6.2.0.
- if (kb == KB_FIRMWARE_VERSION_620)
- {
- u8 *tsec_paged = (u8 *)page_alloc(3);
- memcpy(tsec_paged, (void *)tsec_ctxt->fw, tsec_ctxt->size);
- tsec_ctxt->fw = tsec_paged;
- }
-
- // Get TSEC key.
- if (kb <= KB_FIRMWARE_VERSION_620)
- {
- while (tsec_query(tmp, kb, tsec_ctxt) < 0)
- {
- memset(tmp, 0x00, 0x20);
- retries++;
-
- // We rely on racing conditions, make sure we cover even the unluckiest cases.
- if (retries > 15)
- {
- _hos_crit_error("\nFailed to get TSEC keys. Please try again.");
- return 0;
- }
- }
- }
-
- if (kb >= KB_FIRMWARE_VERSION_700)
- {
- // Use HOS EKS if it exists.
- u8 key_idx = kb - KB_FIRMWARE_VERSION_700;
- if (h_cfg.eks && (h_cfg.eks->enabled & (1 << key_idx)))
- {
- // Set Device keygen key to slot 10.
- se_aes_key_set(10, h_cfg.eks->keys[key_idx].dkg, 0x10);
- // Set Master key to slot 12.
- se_aes_key_set(12, h_cfg.eks->keys[key_idx].mkk, 0x10);
- // Set FW Device key key to slot 13.
- se_aes_key_set(13, h_cfg.eks->keys[key_idx].fdk, 0x10);
- // Set Device key to slot 15.
- se_aes_key_set(15, h_cfg.eks->keys[key_idx].dkk, 0x10);
-
- // Lock FDK.
- se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
- }
-
- se_aes_key_clear(8);
- se_aes_unwrap_key(8, 12, package2_keyseed);
- }
- else if (kb == KB_FIRMWARE_VERSION_620)
- {
- // Set TSEC key.
- se_aes_key_set(12, tmp, 0x10);
- // Set TSEC root key.
- se_aes_key_set(13, tmp + 0x10, 0x10);
-
- if (!(emu_cfg.enabled && !h_cfg.emummc_force_disable) && hos_ctxt->stock)
- {
- // Package2 key.
- se_aes_key_set(8, tmp + 0x10, 0x10);
- se_aes_unwrap_key(8, 8, master_keyseed_620);
- se_aes_unwrap_key(8, 8, master_keyseed_retail);
- se_aes_unwrap_key(8, 8, package2_keyseed);
- }
- else
- {
- // Decrypt keyblob and set keyslots
- se_aes_crypt_block_ecb(12, 0, tmp + 0x20, keyblob_keyseeds[0]);
- se_aes_unwrap_key(15, 14, tmp + 0x20);
- se_aes_unwrap_key(14, 15, console_keyseed_4xx_5xx);
- se_aes_unwrap_key(15, 15, console_keyseed);
-
- se_aes_unwrap_key(13, 13, master_keyseed_620);
- se_aes_unwrap_key(12, 13, master_keyseed_retail);
- se_aes_unwrap_key(10, 13, master_keyseed_4xx_5xx_610);
-
- // Package2 key.
- se_aes_unwrap_key(8, 12, package2_keyseed);
-
- h_cfg.se_keygen_done = 1;
- }
- }
- else
- {
- se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
- se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
-
- // Set TSEC key.
- se_aes_key_set(13, tmp, 0x10);
-
- // Derive keyblob keys from TSEC+SBK.
- se_aes_crypt_block_ecb(13, 0, tmp, keyblob_keyseeds[0]);
- se_aes_unwrap_key(15, 14, tmp);
- se_aes_crypt_block_ecb(13, 0, tmp, keyblob_keyseeds[kb]);
- se_aes_unwrap_key(13, 14, tmp);
-
- // Clear SBK.
- se_aes_key_clear(14);
-
- //TODO: verify keyblob CMAC.
- //se_aes_unwrap_key(11, 13, cmac_keyseed);
- //se_aes_cmac(tmp, 0x10, 11, keyblob + 0x10, 0xA0);
- //if (!memcmp(keyblob, tmp, 0x10))
- // return 0;
-
- se_aes_crypt_block_ecb(13, 0, tmp, cmac_keyseed);
- se_aes_unwrap_key(11, 13, cmac_keyseed);
-
- // Decrypt keyblob and set keyslots.
- se_aes_crypt_ctr(13, keyblob + 0x20, 0x90, keyblob + 0x20, 0x90, keyblob + 0x10);
- se_aes_key_set(11, keyblob + 0x20 + 0x80, 0x10); // Package1 key.
- se_aes_key_set(12, keyblob + 0x20, 0x10);
- se_aes_key_set(13, keyblob + 0x20, 0x10);
-
- se_aes_crypt_block_ecb(12, 0, tmp, master_keyseed_retail);
-
- switch (kb)
- {
- case KB_FIRMWARE_VERSION_100_200:
- case KB_FIRMWARE_VERSION_300:
- case KB_FIRMWARE_VERSION_301:
- se_aes_unwrap_key(13, 15, console_keyseed);
- se_aes_unwrap_key(12, 12, master_keyseed_retail);
- break;
- case KB_FIRMWARE_VERSION_400:
- se_aes_unwrap_key(13, 15, console_keyseed_4xx_5xx);
- se_aes_unwrap_key(15, 15, console_keyseed);
- se_aes_unwrap_key(14, 12, master_keyseed_4xx_5xx_610);
- se_aes_unwrap_key(12, 12, master_keyseed_retail);
- break;
- case KB_FIRMWARE_VERSION_500:
- case KB_FIRMWARE_VERSION_600:
- se_aes_unwrap_key(10, 15, console_keyseed_4xx_5xx);
- se_aes_unwrap_key(15, 15, console_keyseed);
- se_aes_unwrap_key(14, 12, master_keyseed_4xx_5xx_610);
- se_aes_unwrap_key(12, 12, master_keyseed_retail);
- break;
- }
-
- // Package2 key.
- se_key_acc_ctrl(8, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
- se_aes_unwrap_key(8, 12, package2_keyseed);
- }
-
- return 1;
-}
-
-static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
-{
- sdmmc_storage_t storage;
- sdmmc_t sdmmc;
-
- int res = emummc_storage_init_mmc(&storage, &sdmmc);
-
- if (res)
- {
- if (res == 2)
- _hos_crit_error("Failed to init eMMC");
- else
- _hos_crit_error("Failed to init emuMMC");
-
- return 0;
- }
-
- // Read package1.
- ctxt->pkg1 = (void *)malloc(0x40000);
- emummc_storage_set_mmc_partition(&storage, EMMC_BOOT0);
- emummc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, ctxt->pkg1);
- ctxt->pkg1_id = pkg1_identify(ctxt->pkg1);
- if (!ctxt->pkg1_id)
- {
- _hos_crit_error("Unknown pkg1 version.");
- EHPRINTFARGS("%sNot yet supported HOS version!",
- (emu_cfg.enabled && !h_cfg.emummc_force_disable) ? "Is emuMMC corrupt?\nOr " : "");
- goto out;
- }
- gfx_printf("Identified pkg1 and Keyblob %d\n\n", ctxt->pkg1_id->kb);
-
- // Read the correct keyblob.
- ctxt->keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
- emummc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
-
- res = 1;
-
-out:;
- sdmmc_storage_end(&storage);
- return res;
-}
-
-static u8 *_read_emmc_pkg2(launch_ctxt_t *ctxt)
-{
- u8 *bctBuf = NULL;
- sdmmc_storage_t storage;
- sdmmc_t sdmmc;
-
- int res = emummc_storage_init_mmc(&storage, &sdmmc);
-
- if (res)
- {
- if (res == 2)
- _hos_crit_error("Failed to init eMMC");
- else
- _hos_crit_error("Failed to init emuMMC");
-
- return NULL;
- }
-
- emummc_storage_set_mmc_partition(&storage, EMMC_GPP);
-
- // Parse eMMC GPT.
- LIST_INIT(gpt);
- nx_emmc_gpt_parse(&gpt, &storage);
-DPRINTF("Parsed GPT\n");
- // Find package2 partition.
- emmc_part_t *pkg2_part = nx_emmc_part_find(&gpt, "BCPKG2-1-Normal-Main");
- if (!pkg2_part)
- goto out;
-
- // Read in package2 header and get package2 real size.
- //TODO: implement memalign for DMA buffers.
- static const u32 BCT_SIZE = 0x4000;
- bctBuf = (u8 *)malloc(BCT_SIZE);
- nx_emmc_part_read(&storage, pkg2_part, BCT_SIZE / NX_EMMC_BLOCKSIZE, 1, bctBuf);
- u32 *hdr = (u32 *)(bctBuf + 0x100);
- u32 pkg2_size = hdr[0] ^ hdr[2] ^ hdr[3];
-DPRINTF("pkg2 size on emmc is %08X\n", pkg2_size);
-
- // Read in Boot Config.
- memset(bctBuf, 0, BCT_SIZE);
- nx_emmc_part_read(&storage, pkg2_part, 0, BCT_SIZE / NX_EMMC_BLOCKSIZE, bctBuf);
-
- // Read in package2.
- u32 pkg2_size_aligned = ALIGN(pkg2_size, NX_EMMC_BLOCKSIZE);
-DPRINTF("pkg2 size aligned is %08X\n", pkg2_size_aligned);
- ctxt->pkg2 = malloc(pkg2_size_aligned);
- ctxt->pkg2_size = pkg2_size;
- nx_emmc_part_read(&storage, pkg2_part, BCT_SIZE / NX_EMMC_BLOCKSIZE,
- pkg2_size_aligned / NX_EMMC_BLOCKSIZE, ctxt->pkg2);
-out:;
- nx_emmc_gpt_free(&gpt);
- sdmmc_storage_end(&storage);
-
- return bctBuf;
-}
-
-static void _free_launch_components(launch_ctxt_t *ctxt)
-{
- free(ctxt->keyblob);
- free(ctxt->pkg1);
- free(ctxt->pkg2);
- free(ctxt->warmboot);
- free(ctxt->secmon);
- free(ctxt->kernel);
- free(ctxt->kip1_patches);
-}
-
-static bool _get_fs_exfat_compatible(link_t *info)
-{
- u32 fs_idx;
- u32 fs_ids_cnt;
- u32 sha_buf[32 / sizeof(u32)];
- kip1_id_t *kip_ids;
-
- LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
- {
- if (strncmp((const char*)ki->kip1->name, "FS", 2))
- continue;
-
- if (!se_calc_sha256(sha_buf, ki->kip1, ki->size))
- break;
-
- pkg2_get_ids(&kip_ids, &fs_ids_cnt);
-
- for (fs_idx = 0; fs_idx < fs_ids_cnt; fs_idx++)
- if (!memcmp(sha_buf, kip_ids[fs_idx].hash, 8))
- break;
-
- // Return false if FAT32 only.
- if (fs_ids_cnt <= fs_idx && !(fs_idx & 1))
- return false;
-
- break;
- }
-
- return true;
-}
-
-int hos_launch(ini_sec_t *cfg)
-{
- minerva_change_freq(FREQ_1600);
- launch_ctxt_t ctxt;
- tsec_ctxt_t tsec_ctxt;
- volatile secmon_mailbox_t *secmon_mb;
-
- memset(&ctxt, 0, sizeof(launch_ctxt_t));
- memset(&tsec_ctxt, 0, sizeof(tsec_ctxt_t));
- list_init(&ctxt.kip1_list);
-
- ctxt.cfg = cfg;
-
- if (!gfx_con.mute)
- gfx_clear_grey(0x1B);
- gfx_con_setpos(0, 0);
-
- gfx_printf("Initializing...\n\n");
-
- // Read package1 and the correct keyblob.
- if (!_read_emmc_pkg1(&ctxt))
- return 0;
-
- // Try to parse config if present.
- if (ctxt.cfg && !parse_boot_config(&ctxt))
- {
- _hos_crit_error("Wrong ini cfg or missing files!");
- return 0;
- }
-
- // Enable emummc patching.
- if (emu_cfg.enabled && !h_cfg.emummc_force_disable)
- {
- if (ctxt.stock)
- {
- _hos_crit_error("Stock emuMMC is not supported yet!");
- return 0;
- }
-
- ctxt.atmosphere = true; // Set atmosphere patching in case of Stock emuMMC and no fss0.
- config_kip1patch(&ctxt, "emummc");
- }
- else if (!emu_cfg.enabled && ctxt.emummc_forced)
- {
- _hos_crit_error("emuMMC is forced but not enabled!");
- return 0;
- }
-
- // Check if fuses lower than 4.0.0 or 9.0.0 and if yes apply NO Gamecard patch.
- // Additionally check if running emuMMC and disable GC if v3 fuses are burnt and HOS is <= 8.1.0.
- if (!ctxt.stock)
- {
- u32 fuses = fuse_read_odm(7);
- if ((h_cfg.autonogc &&
- ((!(fuses & ~0xF) && (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_400)) || // LAFW v2.
- (!(fuses & ~0x3FF) && (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_900)))) // LAFW v3.
- || ((emu_cfg.enabled && !h_cfg.emummc_force_disable) &&
- ((fuses & 0x400) && (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_810))))
- config_kip1patch(&ctxt, "nogc");
- }
-
- gfx_printf("Loaded config, pkg1 and keyblob\n");
-
- // Generate keys.
- if (!h_cfg.se_keygen_done)
- {
- tsec_ctxt.fw = (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off;
- tsec_ctxt.pkg1 = ctxt.pkg1;
- tsec_ctxt.pkg11_off = ctxt.pkg1_id->pkg11_off;
- tsec_ctxt.secmon_base = ctxt.pkg1_id->secmon_base;
-
- if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
- {
- _hos_crit_error("Failed to run sept");
- return 0;
- }
-
- if (!hos_keygen(ctxt.keyblob, ctxt.pkg1_id->kb, &tsec_ctxt, &ctxt))
- return 0;
- gfx_printf("Generated keys\n");
- if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
- h_cfg.se_keygen_done = 1;
- }
-
- // Decrypt and unpack package1 if we require parts of it.
- if (!ctxt.warmboot || !ctxt.secmon)
- {
- if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
- pkg1_decrypt(ctxt.pkg1_id, ctxt.pkg1);
-
- if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && !(emu_cfg.enabled && !h_cfg.emummc_force_disable))
- {
- pkg1_unpack((void *)ctxt.pkg1_id->warmboot_base, (void *)ctxt.pkg1_id->secmon_base, NULL, ctxt.pkg1_id, ctxt.pkg1);
- gfx_printf("Decrypted & unpacked pkg1\n");
- }
- else
- {
- _hos_crit_error("No mandatory secmon or warmboot provided!");
- return 0;
- }
- }
-
- // Replace 'warmboot.bin' if requested.
- if (ctxt.warmboot)
- memcpy((void *)ctxt.pkg1_id->warmboot_base, ctxt.warmboot, ctxt.warmboot_size);
- else
- {
- if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
- {
- _hos_crit_error("No warmboot provided!");
- return 0;
- }
- // Else we patch it to allow downgrading.
- patch_t *warmboot_patchset = ctxt.pkg1_id->warmboot_patchset;
- gfx_printf("%kPatching Warmboot%k\n", 0xFFFFBA00, 0xFFCCCCCC);
- for (u32 i = 0; warmboot_patchset[i].off != 0xFFFFFFFF; i++)
- *(vu32 *)(ctxt.pkg1_id->warmboot_base + warmboot_patchset[i].off) = warmboot_patchset[i].val;
- }
- // Set warmboot address in PMC if required.
- if (ctxt.pkg1_id->set_warmboot)
- PMC(APBDEV_PMC_SCRATCH1) = ctxt.pkg1_id->warmboot_base;
-
- // Replace 'SecureMonitor' if requested.
- if (ctxt.secmon)
- memcpy((void *)ctxt.pkg1_id->secmon_base, ctxt.secmon, ctxt.secmon_size);
- else if (ctxt.pkg1_id->secmon_patchset)
- {
- // Else we patch it to allow for an unsigned package2 and patched kernel.
- patch_t *secmon_patchset = ctxt.pkg1_id->secmon_patchset;
- gfx_printf("%kPatching Secure Monitor%k\n", 0xFFFFBA00, 0xFFCCCCCC);
- for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++)
- *(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
- }
-
- gfx_printf("Loaded warmboot and secmon\n");
-
- // Read package2.
- u8 *bootConfigBuf = _read_emmc_pkg2(&ctxt);
- if (!bootConfigBuf)
- return 0;
-
- gfx_printf("Read pkg2\n");
-
- // Decrypt package2 and parse KIP1 blobs in INI1 section.
- pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(ctxt.pkg2, ctxt.pkg1_id->kb);
- if (!pkg2_hdr)
- {
- _hos_crit_error("Pkg2 decryption failed!");
- if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
- {
- EPRINTF("Is Sept updated?");
-
- // Clear EKS slot, in case something went wrong with sept keygen.
- hos_eks_clear(ctxt.pkg1_id->kb);
- }
- return 0;
- }
- else if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
- hos_eks_save(ctxt.pkg1_id->kb); // Save EKS slot if it doesn't exist.
-
- LIST_INIT(kip1_info);
- if (!pkg2_parse_kips(&kip1_info, pkg2_hdr, &ctxt.new_pkg2))
- {
- _hos_crit_error("INI1 parsing failed!");
- return 0;
- }
-
- gfx_printf("Parsed ini1\n");
-
- // Use the kernel included in package2 in case we didn't load one already.
- if (!ctxt.kernel)
- {
- ctxt.kernel = pkg2_hdr->data;
- ctxt.kernel_size = pkg2_hdr->sec_size[PKG2_SEC_KERNEL];
-
- if (!ctxt.stock && (ctxt.svcperm || ctxt.debugmode || ctxt.atmosphere))
- {
- u8 kernel_hash[0x20];
- // Hash only Kernel when it embeds INI1.
- if (!ctxt.new_pkg2)
- se_calc_sha256(kernel_hash, ctxt.kernel, ctxt.kernel_size);
- else
- se_calc_sha256(kernel_hash, ctxt.kernel + PKG2_NEWKERN_START,
- pkg2_newkern_ini1_start - PKG2_NEWKERN_START);
-
- ctxt.pkg2_kernel_id = pkg2_identify(kernel_hash);
- if (!ctxt.pkg2_kernel_id)
- {
- _hos_crit_error("Failed to identify kernel!");
-
- return 0;
- }
-
- // In case a kernel patch option is set; allows to disable SVC verification or/and enable debug mode.
- kernel_patch_t *kernel_patchset = ctxt.pkg2_kernel_id->kernel_patchset;
- if (kernel_patchset != NULL)
- {
- gfx_printf("%kPatching kernel%k\n", 0xFFFFBA00, 0xFFCCCCCC);
- u32 *temp;
- for (u32 i = 0; kernel_patchset[i].id != 0xFFFFFFFF; i++)
- {
- if ((ctxt.svcperm && kernel_patchset[i].id == SVC_VERIFY_DS)
- || (ctxt.debugmode && kernel_patchset[i].id == DEBUG_MODE_EN && !(ctxt.atmosphere && ctxt.secmon))
- || (ctxt.atmosphere && kernel_patchset[i].id == ATM_GEN_PATCH))
- *(vu32 *)(ctxt.kernel + kernel_patchset[i].off) = kernel_patchset[i].val;
- else if (ctxt.atmosphere && kernel_patchset[i].id == ATM_ARR_PATCH)
- {
- temp = (u32 *)kernel_patchset[i].ptr;
- for (u32 j = 0; j < kernel_patchset[i].val; j++)
- *(vu32 *)(ctxt.kernel + kernel_patchset[i].off + (j << 2)) = temp[j];
- }
- else if (kernel_patchset[i].id < SVC_VERIFY_DS)
- *(vu32 *)(ctxt.kernel + kernel_patchset[i].off) = kernel_patchset[i].val;
- }
- }
- }
- }
-
- // Merge extra KIP1s into loaded ones.
- gfx_printf("%kPatching kips%k\n", 0xFFFFBA00, 0xFFCCCCCC);
- LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
- pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
-
- // Check if FS is compatible with exFAT.
- if (!ctxt.stock && sd_fs.fs_type == FS_EXFAT && !_get_fs_exfat_compatible(&kip1_info))
- {
- _hos_crit_error("SD Card is exFAT and the installed\nFS only supports FAT32!");
-
- _free_launch_components(&ctxt);
- return 0;
- }
-
- // Patch kip1s in memory if needed.
- const char* unappliedPatch = pkg2_patch_kips(&kip1_info, ctxt.kip1_patches);
- if (unappliedPatch != NULL)
- {
- EHPRINTFARGS("Failed to apply '%s'!", unappliedPatch);
-
- _free_launch_components(&ctxt);
- return 0; // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated!
- }
-
- // Rebuild and encrypt package2.
- pkg2_build_encrypt((void *)PKG2_LOAD_ADDR, ctxt.kernel, ctxt.kernel_size, &kip1_info, ctxt.new_pkg2);
-
- gfx_printf("Rebuilt & loaded pkg2\n");
-
- // Unmount SD card.
- sd_unmount();
-
- gfx_printf("\n%kBooting...%k\n", 0xFF96FF00, 0xFFCCCCCC);
-
- // Clear pkg1/pkg2 keys.
- se_aes_key_clear(8);
- se_aes_key_clear(11);
-
- // Finalize per firmware keys.
- int bootStateDramPkg2 = 0;
- int bootStatePkg2Continue = 0;
-
- switch (ctxt.pkg1_id->kb)
- {
- case KB_FIRMWARE_VERSION_100_200:
- case KB_FIRMWARE_VERSION_300:
- case KB_FIRMWARE_VERSION_301:
- if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_300)
- PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; // Warmboot 3.0.0 PA address id.
- else if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_301)
- PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; // Warmboot 3.0.1/.2 PA address id.
- se_key_acc_ctrl(12, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG);
- se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG);
- bootStateDramPkg2 = 2;
- bootStatePkg2Continue = 3;
- break;
- case KB_FIRMWARE_VERSION_400:
- case KB_FIRMWARE_VERSION_500:
- case KB_FIRMWARE_VERSION_600:
- se_key_acc_ctrl(12, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG);
- se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG);
- default:
- bootStateDramPkg2 = 2;
- bootStatePkg2Continue = 4;
- break;
- }
-
- // Clear BCT area for retail units and copy it over if dev unit.
- if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_500)
- {
- memset((void *)0x4003D000, 0, 0x3000);
- if ((fuse_read_odm(4) & 3) == 3)
- memcpy((void *)0x4003D000, bootConfigBuf, 0x1000);
- }
- else
- {
- memset((void *)0x4003F000, 0, 0x1000);
- if ((fuse_read_odm(4) & 3) == 3)
- memcpy((void *)0x4003F800, bootConfigBuf, 0x800);
- }
- free(bootConfigBuf);
-
- // Config Exosphère if booting full Atmosphère.
- if (ctxt.atmosphere && ctxt.secmon)
- config_exosphere(&ctxt);
-
- // Finalize MC carveout.
- if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_301)
- mc_config_carveout();
-
- // Lock SE before starting 'SecureMonitor' if < 6.2.0, otherwise lock bootrom and ipatches.
- _se_lock(ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600);
-
- // Reset sysctr0 counters.
- if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_620)
- _sysctr0_reset();
-
- // < 4.0.0 pkg1.1 locks PMC scratches.
- //_pmc_scratch_lock(ctxt.pkg1_id->kb);
-
- // Set secmon mailbox address.
- if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
- secmon_mb = (secmon_mailbox_t *)SECMON7_MB_ADDR;
- else
- secmon_mb = (secmon_mailbox_t *)SECMON_MB_ADDR;
-
- // Start from DRAM ready signal and reset outgoing value.
- secmon_mb->in = bootStateDramPkg2;
- secmon_mb->out = 0;
-
- // Disable display. This must be executed before secmon to provide support for all fw versions.
- display_end();
-
- // Clear EMC_SCRATCH0.
- EMC(EMC_SCRATCH0) = 0;
-
- // Flush cache and disable MMU.
- bpmp_mmu_disable();
- bpmp_clk_rate_set(BPMP_CLK_NORMAL);
- minerva_change_freq(FREQ_1600);
-
- // emuMMC: Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
- sdmmc_storage_init_wait_sd();
-
- // Wait for secmon to get ready.
- if (smmu_is_used())
- smmu_exit();
- else
- cluster_boot_cpu0(ctxt.pkg1_id->secmon_base);
- while (!secmon_mb->out)
- ; // A usleep(1) only works when in IRAM or with a trained DRAM.
-
- // Signal pkg2 ready and continue boot.
- secmon_mb->in = bootStatePkg2Continue;
-
- // Halt ourselves in waitevent state and resume if there's JTAG activity.
- while (true)
- bpmp_halt();
-
- return 0;
-}
diff --git a/source/hos/hos.h b/source/hos/hos.h
deleted file mode 100644
index 6378738..0000000
--- a/source/hos/hos.h
+++ /dev/null
@@ -1,120 +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 "../utils/types.h"
-#include "../config/ini.h"
-#include "../sec/tsec.h"
-
-#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
-
-typedef struct _exo_ctxt_t
-{
- 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 dkg[0x10];
- u8 mkk[0x10];
- u8 fdk[0x10];
- u8 dkk[0x10];
-} hos_eks_keys_t;
-
-typedef struct _hos_eks_mbr_t
-{
- u32 magic;
- u32 enabled;
- u32 sbk_low[2];
- hos_eks_keys_t keys[6];
- u32 magic2;
- u32 rsvd2[3];
-} hos_eks_mbr_t;
-
-static_assert(sizeof(hos_eks_mbr_t) < 424, "HOS EKS storage bigger than MBR!");
-
-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 *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_enable_experimental;
- bool emummc_forced;
-
- exo_ctxt_t exo_cfg;
-
- 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/hos_config.c b/source/hos/hos_config.c
deleted file mode 100644
index 4c3d789..0000000
--- a/source/hos/hos_config.c
+++ /dev/null
@@ -1,309 +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 .
- */
-
-#include
-
-#include "hos.h"
-#include "hos_config.h"
-#include "fss.h"
-#include "../libs/fatfs/ff.h"
-#include "../mem/heap.h"
-#include "../storage/nx_sd.h"
-#include "../utils/dirlist.h"
-
-#include "../gfx/gfx.h"
-
-//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
-#define DPRINTF(...)
-
-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;
-}
-
-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;
-}
-
-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;
-}
-
-static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
-{
- u32 size;
-
- if (!memcmp(value + strlen(value) - 1, "*", 1))
- {
- char *dir = (char *)malloc(256);
- strcpy(dir, value);
-
- u32 dirlen = 0;
- dir[strlen(dir) - 2] = 0;
- char *filelist = dirlist(dir, "*.kip*", false);
-
- strcat(dir, "/");
- dirlen = strlen(dir);
-
- u32 i = 0;
- if (filelist)
- {
- while (true)
- {
- if (!filelist[i * 256])
- break;
-
- strcpy(dir + dirlen, &filelist[i * 256]);
-
- merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
- mkip1->kip1 = sd_file_read(dir, &size);
- if (!mkip1->kip1)
- {
- free(mkip1);
- free(dir);
- free(filelist);
-
- return 0;
- }
- DPRINTF("Loaded kip1 from SD (size %08X)\n", size);
- list_append(&ctxt->kip1_list, &mkip1->link);
-
- i++;
- }
- }
-
- free(dir);
- free(filelist);
- }
- else
- {
- merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
- mkip1->kip1 = sd_file_read(value, &size);
- if (!mkip1->kip1)
- {
- free(mkip1);
-
- return 0;
- }
- DPRINTF("Loaded kip1 from SD (size %08X)\n", size);
- list_append(&ctxt->kip1_list, &mkip1->link);
- }
-
- return 1;
-}
-
-int config_kip1patch(launch_ctxt_t *ctxt, const char *value)
-{
- if (value == NULL)
- return 0;
-
- int valueLen = strlen(value);
- if (!valueLen)
- return 0;
-
- if (ctxt->kip1_patches == NULL)
- {
- ctxt->kip1_patches = malloc(valueLen + 1);
- memcpy(ctxt->kip1_patches, value, valueLen);
- ctxt->kip1_patches[valueLen] = 0;
- }
- else
- {
- char *oldAlloc = ctxt->kip1_patches;
- int oldSize = strlen(oldAlloc);
- ctxt->kip1_patches = malloc(oldSize + 1 + valueLen + 1);
- memcpy(ctxt->kip1_patches, oldAlloc, oldSize);
- free(oldAlloc);
- oldAlloc = NULL;
- ctxt->kip1_patches[oldSize++] = ',';
- memcpy(&ctxt->kip1_patches[oldSize], value, valueLen);
- ctxt->kip1_patches[oldSize + valueLen] = 0;
- }
- return 1;
-}
-
-static int _config_svcperm(launch_ctxt_t *ctxt, const char *value)
-{
- if (*value == '1')
- {
- DPRINTF("Disabled SVC verification\n");
- ctxt->svcperm = true;
- }
- return 1;
-}
-
-static int _config_debugmode(launch_ctxt_t *ctxt, const char *value)
-{
- if (*value == '1')
- {
- DPRINTF("Enabled Debug mode\n");
- ctxt->debugmode = true;
- }
- return 1;
-}
-
-static int _config_stock(launch_ctxt_t *ctxt, const char *value)
-{
- if (*value == '1')
- {
- DPRINTF("Disabled all patching\n");
- ctxt->stock = true;
- }
- return 1;
-}
-
-static int _config_emummc_forced(launch_ctxt_t *ctxt, const char *value)
-{
- if (*value == '1')
- {
- DPRINTF("Forced emuMMC\n");
- ctxt->emummc_forced = true;
- }
- return 1;
-}
-
-static int _config_atmosphere(launch_ctxt_t *ctxt, const char *value)
-{
- if (*value == '1')
- {
- DPRINTF("Enabled atmosphere patching\n");
- ctxt->atmosphere = true;
- }
- return 1;
-}
-
-static int _config_dis_exo_user_exceptions(launch_ctxt_t *ctxt, const char *value)
-{
- if (*value == '1')
- {
- DPRINTF("Disabled exosphere user exception handlers\n");
- ctxt->exo_cfg.no_user_exceptions = true;
- }
- return 1;
-}
-
-static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value)
-{
- if (*value == '1')
- {
- DPRINTF("Enabled user access to PMU\n");
- ctxt->exo_cfg.user_pmu = true;
- }
- return 1;
-}
-
-static int _config_exo_cal0_blanking(launch_ctxt_t *ctxt, const char *value)
-{
- // Override key found.
- ctxt->exo_cfg.cal0_blank = calloc(1, 1);
-
- if (*value == '1')
- {
- DPRINTF("Enabled prodinfo blanking\n");
- *ctxt->exo_cfg.cal0_blank = true;
- }
- return 1;
-}
-
-static int _config_exo_cal0_writes_enable(launch_ctxt_t *ctxt, const char *value)
-{
- // Override key found.
- ctxt->exo_cfg.cal0_allow_writes_sys = calloc(1, 1);
-
- if (*value == '1')
- {
- DPRINTF("Enabled prodinfo writes\n");
- *ctxt->exo_cfg.cal0_allow_writes_sys = true;
- }
-
- return 1;
-}
-
-static int _config_fss(launch_ctxt_t *ctxt, const char *value)
-{
- LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link)
- {
- if (!strcmp("fss0experimental", kv->key))
- {
- ctxt->fss0_enable_experimental = *kv->val == '1';
- break;
- }
- }
-
- return parse_fss(ctxt, value, NULL);
-}
-
-typedef struct _cfg_handler_t
-{
- const char *key;
- int (*handler)(launch_ctxt_t *ctxt, const char *value);
-} cfg_handler_t;
-
-static const cfg_handler_t _config_handlers[] = {
- { "warmboot", _config_warmboot },
- { "secmon", _config_secmon },
- { "kernel", _config_kernel },
- { "kip1", _config_kip1 },
- { "kip1patch", config_kip1patch },
- { "fullsvcperm", _config_svcperm },
- { "debugmode", _config_debugmode },
- { "stock", _config_stock },
- { "atmosphere", _config_atmosphere },
- { "fss0", _config_fss },
- { "emummcforce", _config_emummc_forced },
- { "nouserexceptions", _config_dis_exo_user_exceptions },
- { "userpmu", _config_exo_user_pmu_access },
- { "cal0blank", _config_exo_cal0_blanking },
- { "cal0writesys", _config_exo_cal0_writes_enable },
- { NULL, NULL },
-};
-
-int parse_boot_config(launch_ctxt_t *ctxt)
-{
- LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link)
- {
- for(u32 i = 0; _config_handlers[i].key; i++)
- {
- if (!strcmp(_config_handlers[i].key, kv->key))
- {
- 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;
-}
diff --git a/source/hos/hos_config.h b/source/hos/hos_config.h
deleted file mode 100644
index f835302..0000000
--- a/source/hos/hos_config.h
+++ /dev/null
@@ -1,26 +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 _HOS_CONFIG_H_
-#define _HOS_CONFIG_H_
-
-#include "hos.h"
-
-int parse_boot_config(launch_ctxt_t *ctxt);
-int config_kip1patch(launch_ctxt_t *ctxt, const char *value);
-
-#endif
-
diff --git a/source/hos/pkg1.c b/source/hos/pkg1.c
index 86ed842..b1768f8 100644
--- a/source/hos/pkg1.c
+++ b/source/hos/pkg1.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk
- * Copyright (c) 2018-2020 CTCaer
+ * Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,135 +20,29 @@
#include
#include "pkg1.h"
-#include "../gfx/gfx.h"
-#include "../mem/heap.h"
#include "../sec/se.h"
-#include "../utils/aarch64_util.h"
-#define _NOPv7() 0xE320F000
-
-#define SM_100_ADR 0x4002B020
-PATCHSET_DEF(_secmon_1_patchset,
- // Patch the relocator to be able to run from SM_100_ADR.
- { 0x1E0, _ADRP(0, 0x7C013000 - _PAGEOFF(SM_100_ADR)) },
- //Patch package2 decryption and signature/hash checks.
- { 0x9F0 + 0xADC, _NOP() }, //Header signature.
- { 0x9F0 + 0xB8C, _NOP() }, //Version.
- { 0x9F0 + 0xBB0, _NOP() } //Sections SHA2.
-);
-
-PATCHSET_DEF(_secmon_2_patchset,
- // Patch package2 decryption and signature/hash checks.
- { 0xAC8 + 0xAAC, _NOP() }, //Header signature.
- { 0xAC8 + 0xB3C, _NOP() }, //Version.
- { 0xAC8 + 0xB58, _NOP() } //Sections SHA2.
-);
-
-PATCHSET_DEF(_secmon_3_patchset,
- // Patch package2 decryption and signature/hash checks.
- { 0xAC8 + 0xA30, _NOP() }, //Header signature.
- { 0xAC8 + 0xAB4, _NOP() }, //package2 structure.
- { 0xAC8 + 0xAC0, _NOP() }, //Version.
- { 0xAC8 + 0xADC, _NOP() } //Sections SHA2.
-);
-
-PATCHSET_DEF(_secmon_4_patchset,
- // Patch package2 decryption and signature/hash checks.
- { 0x2300 + 0x5D80, _NOP() }, //package2 structure.
- { 0x2300 + 0x5D8C, _NOP() }, //Version.
- { 0x2300 + 0x5EFC, _NOP() }, //Header signature.
- { 0xAC8 + 0xA2C, _NOP() } //Sections SHA2.
-);
-
-PATCHSET_DEF(_secmon_5_patchset,
- // Patch package2 decryption and signature/hash checks.
- { 0xDA8 + 0x9D8, _NOP() }, //package2 structure.
- { 0xDA8 + 0x9E4, _NOP() }, //Version.
- { 0xDA8 + 0xC9C, _NOP() }, //Header signature.
- { 0xDA8 + 0x1038, _NOP() } //Sections SHA2.
-);
-
-PATCHSET_DEF(_secmon_6_patchset,
- // Patch package2 decryption and signature/hash checks.
- { 0xDC8 + 0x820, _NOP() }, //package2 structure.
- { 0xDC8 + 0x82C, _NOP() }, //Version.
- { 0xDC8 + 0xE90, _NOP() }, //Header signature.
- { 0xDC8 + 0x112C, _NOP() } //Sections SHA2.
- // Fix sleep mode for debug.
- // { 0x1A68 + 0x3854, 0x94000E45 }, //gpio_config_for_uart.
- // { 0x1A68 + 0x3858, 0x97FFFC0F }, //clkrst_reboot_uarta.
- // { 0x1A68 + 0x385C, 0x52A00021 }, //MOV W1, #0x10000 ; baudrate.
- // { 0x1A68 + 0x3860, 0x2A1F03E0 }, //MOV W0, WZR ; uart_port -> A.
- // { 0x1A68 + 0x3864, 0x72984001 }, //MOVK W1, #0xC200 ; baudrate.
- // { 0x1A68 + 0x3868, 0x94000C8C }, //uart_configure.
- // { 0x1A68 + 0x3A6C, _NOP() } // warmboot UARTA cfg.
-);
-
-PATCHSET_DEF(_secmon_620_patchset,
- // Patch package2 decryption and signature/hash checks.
- { 0xDC8 + 0x604, _NOP() }, //package2 structure.
- { 0xDC8 + 0x610, _NOP() }, //Version.
- { 0xDC8 + 0xC74, _NOP() }, //Header signature.
- { 0xDC8 + 0xF10, _NOP() } //Sections SHA2.
- // Fix sleep mode for debug.
- // { 0x2AC8 + 0x3854, 0x94000F42 }, //gpio_config_for_uart.
- // { 0x2AC8 + 0x3858, 0x97FFFC0F }, //clkrst_reboot_uarta.
- // { 0x2AC8 + 0x385C, 0x52A00021 }, //MOV W1, #0x10000 ; baudrate.
- // { 0x2AC8 + 0x3860, 0x2A1F03E0 }, //MOV W0, WZR ; uart_port -> A.
- // { 0x2AC8 + 0x3864, 0x72984001 }, //MOVK W1, #0xC200 ; baudrate.
- // { 0x2AC8 + 0x3868, 0x94000D89 }, //uart_configure.
- // { 0x2AC8 + 0x3A6C, _NOP() } // warmboot UARTA cfg.
-);
-
-PATCHSET_DEF(_warmboot_1_patchset,
- { 0x4DC, _NOPv7() } // Fuse check.
-);
-
-PATCHSET_DEF(_warmboot_2_patchset,
- { 0x4DC, _NOPv7() } // Fuse check.
-);
-
-PATCHSET_DEF(_warmboot_3_patchset,
- { 0x4DC, _NOPv7() }, // Fuse check.
- { 0x4F0, _NOPv7() } // Segment id check.
-);
-
-PATCHSET_DEF(_warmboot_4_patchset,
- { 0x544, _NOPv7() }, // Fuse check.
- { 0x558, _NOPv7() } // Segment id check.
-);
-
-
-/*
- * package1.1 header:
- * package1.1 layout:
- * 1.0: {sm, ldr, wb} { 2, 1, 0 }
- * 2.0: {wb, ldr, sm} { 0, 1, 2 }
- * 3.0: {wb, ldr, sm} { 0, 1, 2 }
- * 3.1: {wb, ldr, sm} { 0, 1, 2 }
- * 4.0: {ldr, sm, wb} { 1, 2, 0 }
- * 5.0: {ldr, sm, wb} { 1, 2, 0 }
- * 6.0: {ldr, sm, wb} { 1, 2, 0 }
- * 6.2: {ldr, sm, wb} { 1, 2, 0 }
- * 7.0: {ldr, sm, wb} { 1, 2, 0 }
- */
+#define HASH_ORDER_100_100 {2, 3, 4, 0, 5, 6, 1}
+#define HASH_ORDER_200_510 {2, 3, 4, 0, 5, 7, 10, 12, 11, 6, 8, 1}
+#define HASH_ORDER_600_620 {6, 5, 10, 7, 8, 2, 3, 4, 0, 12, 11, 1}
+#define HASH_ORDER_700_10x {6, 5, 10, 7, 8, 2, 3, 4, 0, 12, 11, 9, 1}
static const pkg1_id_t _pkg1_ids[] = {
- { "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, true, _secmon_1_patchset, _warmboot_1_patchset }, //1.0.0 (Patched relocator)
- { "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_2_patchset, _warmboot_2_patchset }, //2.0.0 - 2.3.0
- { "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.0
- { "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.1 - 3.0.2
- { "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_4_patchset, _warmboot_4_patchset }, //4.0.0 - 4.1.0
- { "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_5_patchset, _warmboot_4_patchset }, //5.0.0 - 5.1.0
- { "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_6_patchset, _warmboot_4_patchset }, //6.0.0 - 6.1.0
- { "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_620_patchset, _warmboot_4_patchset }, //6.2.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
- { "20190314172056", 7, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.0.0 - 8.0.1
- { "20190531152432", 8, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.1.0
- { "20190809135709", 9, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //9.0.0 - 9.0.1
- { "20191021113848", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //9.1.0
- { "20200303104606", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //10.0.0
+ { "20161121183008", 0, {0x1b517, 0x125bc2, 1, 16, 6, HASH_ORDER_100_100, 0, 0x449dc} }, //1.0.0
+ { "20170210155124", 0, {0x1d226, 0x26fe, 0, 16, 11, HASH_ORDER_200_510, 0x557b, 0x3d41a} }, //2.0.0 - 2.3.0
+ { "20170519101410", 1, {0x1ffa6, 0x298b, 0, 16, 11, HASH_ORDER_200_510, 0x552d, 0x3cb81} }, //3.0.0
+ { "20170710161758", 2, {0x20026, 0x29ab, 0, 16, 11, HASH_ORDER_200_510, 0x552d, 0x3cb81} }, //3.0.1 - 3.0.2
+ { "20170921172629", 3, {0x1c64c, 0x37eb, 0, 16, 11, HASH_ORDER_200_510, 0x5382, 0x3711c} }, //4.0.0 - 4.1.0
+ { "20180220163747", 4, {0x1f3b4, 0x465b, 0, 16, 11, HASH_ORDER_200_510, 0x5a63, 0x37901} }, //5.0.0 - 5.1.0
+ { "20180802162753", 5, {0x27350, 0x17ff5, 1, 8, 11, HASH_ORDER_600_620, 0x5674, 0x1d5be} }, //6.0.0 - 6.1.0
+ { "20181107105733", 6, {0x27350, 0x17ff5, 1, 8, 11, HASH_ORDER_600_620, 0x5674, 0x1d5be} }, //6.2.0
+ { "20181218175730", 7, {0x29c50, 0x6a73, 0, 8, 12, HASH_ORDER_700_10x, 0x5563, 0x1d437} }, //7.0.0
+ { "20190208150037", 7, {0x29c50, 0x6a73, 0, 8, 12, HASH_ORDER_700_10x, 0x5563, 0x1d437} }, //7.0.1
+ { "20190314172056", 7, {0x29c50, 0x6a73, 0, 8, 12, HASH_ORDER_700_10x, 0x5563, 0x1d437} }, //8.0.0 - 8.0.1
+ { "20190531152432", 8, {0x29c50, 0x6a73, 0, 8, 12, HASH_ORDER_700_10x, 0x5563, 0x1d437} }, //8.1.0
+ { "20190809135709", 9, {0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_10x, 0x6495, 0x1d807} }, //9.0.0 - 9.0.1
+ { "20191021113848", 10,{0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_10x, 0x6495, 0x1d807} }, //9.1.0
+ { "20200303104606", 10,{0x30ea0, 0x5e4b, 0, 1, 12, HASH_ORDER_700_10x, 0x663c, 0x1d9a4} }, //10.0.0
{ NULL } //End.
};
@@ -159,31 +53,3 @@ const pkg1_id_t *pkg1_identify(u8 *pkg1)
return &_pkg1_ids[i];
return NULL;
}
-
-void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1)
-{
- // Decrypt package1.
- u8 *pkg11 = pkg1 + id->pkg11_off;
- u32 pkg11_size = *(u32 *)pkg11;
- se_aes_crypt_ctr(11, pkg11 + 0x20, pkg11_size, pkg11 + 0x20, pkg11_size, pkg11 + 0x10);
-}
-
-void pkg1_unpack(void *warmboot_dst, void *secmon_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1)
-{
- pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + id->pkg11_off + 0x20);
-
- u32 sec_size[3] = { hdr->wb_size, hdr->ldr_size, hdr->sm_size };
- //u32 sec_off[3] = { hdr->wb_off, hdr->ldr_off, hdr->sm_off };
-
- u8 *pdata = (u8 *)hdr + sizeof(pk11_hdr_t);
- for (u32 i = 0; i < 3; i++)
- {
- if (id->sec_map[i] == 0 && warmboot_dst)
- memcpy(warmboot_dst, pdata, sec_size[id->sec_map[i]]);
- else if (id->sec_map[i] == 1 && ldr_dst)
- memcpy(ldr_dst, pdata, sec_size[id->sec_map[i]]);
- else if (id->sec_map[i] == 2 && secmon_dst)
- memcpy(secmon_dst, pdata, sec_size[id->sec_map[i]]);
- pdata += sec_size[id->sec_map[i]];
- }
-}
diff --git a/source/hos/pkg1.h b/source/hos/pkg1.h
index 455d746..1d1e4ad 100644
--- a/source/hos/pkg1.h
+++ b/source/hos/pkg1.h
@@ -19,46 +19,25 @@
#include "../utils/types.h"
-typedef struct _patch_t
+typedef struct _key_info_t
{
- u32 off;
- u32 val;
-} patch_t;
-
-#define PATCHSET_DEF(name, ...) \
- patch_t name[] = { \
- __VA_ARGS__, \
- { 0xFFFFFFFF, 0xFFFFFFFF } \
- }
+ u32 start_offset;
+ u32 hks_offset;
+ bool hks_offset_is_from_end;
+ u32 alignment;
+ u32 hash_max;
+ u8 hash_order[13];
+ u32 es_offset;
+ u32 ssl_offset;
+} key_info_t;
typedef struct _pkg1_id_t
{
const char *id;
u32 kb;
- u32 tsec_off;
- u32 pkg11_off;
- u32 sec_map[3];
- u32 secmon_base;
- u32 warmboot_base;
- bool set_warmboot;
- patch_t *secmon_patchset;
- patch_t *warmboot_patchset;
+ key_info_t key_info;
} pkg1_id_t;
-typedef struct _pk11_hdr_t
-{
- u32 magic;
- u32 wb_size;
- u32 wb_off;
- u32 pad;
- u32 ldr_size;
- u32 ldr_off;
- u32 sm_size;
- u32 sm_off;
-} pk11_hdr_t;
-
const pkg1_id_t *pkg1_identify(u8 *pkg1);
-void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1);
-void pkg1_unpack(void *warmboot_dst, void *secmon_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1);
#endif
diff --git a/source/hos/pkg2.c b/source/hos/pkg2.c
index 1512a2e..bc77d1e 100644
--- a/source/hos/pkg2.c
+++ b/source/hos/pkg2.c
@@ -18,758 +18,18 @@
#include
-#include "hos.h"
#include "pkg2.h"
-#include "pkg2_ini_kippatch.h"
-
-#include "../config/config.h"
-#include "../libs/compr/blz.h"
-#include "../libs/fatfs/ff.h"
+#include "../utils/aarch64_util.h"
#include "../mem/heap.h"
#include "../sec/se.h"
-#include "../storage/emummc.h"
-#include "../storage/nx_sd.h"
-#include "../utils/aarch64_util.h"
+#include "../libs/compr/blz.h"
#include "../gfx/gfx.h"
-extern hekate_config h_cfg;
-extern const u8 package2_keyseed[];
-
-#ifdef KIP1_PATCH_DEBUG
- #include "../utils/util.h"
- #define DPRINTF(...) gfx_printf(__VA_ARGS__)
- #define DEBUG_PRINTING
-#else
- #define DPRINTF(...)
-#endif
-
-//TODO: Replace hardcoded AArch64 instructions with instruction macros.
-//TODO: Reduce hardcoded values without searching kernel for patterns?
-// The process ID send/receive kernel patches were taken from Atmosphère's kernel patches.
-// They should only be used when running Atmosphère.
-#define FREE_CODE_OFF_1ST_100 0x4797C
-#define FREE_CODE_OFF_1ST_200 0x6486C
-#define FREE_CODE_OFF_1ST_300 0x494A4
-#define FREE_CODE_OFF_1ST_302 0x494BC
-#define FREE_CODE_OFF_1ST_400 0x52890
-#define FREE_CODE_OFF_1ST_500 0x5C020
-#define FREE_CODE_OFF_1ST_600 0x5EE00
-#define FREE_CODE_OFF_1ST_700 0x5FEC0
-#define FREE_CODE_OFF_1ST_800 0x607F0
-#define FREE_CODE_OFF_1ST_900 0x65780
-#define FREE_CODE_OFF_1ST_1000 0x67790
-
-#define ID_SND_OFF_100 0x23CC0
-#define ID_SND_OFF_200 0x3F134
-#define ID_SND_OFF_300 0x26080
-#define ID_SND_OFF_302 0x26080
-#define ID_SND_OFF_400 0x2AF64
-#define ID_SND_OFF_500 0x2AD34
-#define ID_SND_OFF_600 0x2BB8C
-#define ID_SND_OFF_700 0x2D044
-#define ID_SND_OFF_800 0x2F1FC
-#define ID_SND_OFF_900 0x329A0
-#define ID_SND_OFF_1000 0x34404
-
-#define ID_RCV_OFF_100 0x219F0
-#define ID_RCV_OFF_200 0x3D1A8
-#define ID_RCV_OFF_300 0x240F0
-#define ID_RCV_OFF_302 0x240F0
-#define ID_RCV_OFF_400 0x28F6C
-#define ID_RCV_OFF_500 0x28DAC
-#define ID_RCV_OFF_600 0x29B6C
-#define ID_RCV_OFF_700 0x2B23C
-#define ID_RCV_OFF_800 0x2D424
-#define ID_RCV_OFF_900 0x309B4
-#define ID_RCV_OFF_1000 0x322F8
-
-static u32 PRC_ID_SND_100[] =
-{
- 0xA9BF2FEA, 0x2A0E03EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
- 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9412948, 0xA8C12FEA
-};
-#define FREE_CODE_OFF_2ND_100 (FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100) + sizeof(u32))
-static u32 PRC_ID_RCV_100[] =
-{
- 0xA9BF2FEA, 0x2A1C03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
- 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9412968, 0xA8C12FEA
-};
-
-static u32 PRC_ID_SND_200[] =
-{
- 0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
- 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9413148, 0xA8C12FEA
-};
-#define FREE_CODE_OFF_2ND_200 (FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200) + sizeof(u32))
-static u32 PRC_ID_RCV_200[] =
-{
- 0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
- 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9413168, 0xA8C12FEA
-};
-
-static u32 PRC_ID_SND_300[] =
-{
- 0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
- 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA
-};
-#define FREE_CODE_OFF_2ND_300 (FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300) + sizeof(u32))
-static u32 PRC_ID_RCV_300[] =
-{
- 0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
- 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415568, 0xA8C12FEA
-};
-
-#define FREE_CODE_OFF_2ND_302 (FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_300) + sizeof(u32))
-
-static u32 PRC_ID_SND_400[] =
-{
- 0x2A1703EA, 0xD37EF54A, 0xF86A6B8A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9,
- 0xEB09015F, 0x54000060, 0xF94053EA, 0xF9415948, 0xF94053EA
-};
-#define FREE_CODE_OFF_2ND_400 (FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400) + sizeof(u32))
-static u32 PRC_ID_RCV_400[] =
-{
- 0xF9403BED, 0x2A0E03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
- 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B28, 0xD503201F
-};
-
-static u32 PRC_ID_SND_500[] =
-{
- 0x2A1703EA, 0xD37EF54A, 0xF86A6B6A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9,
- 0xEB09015F, 0x54000060, 0xF94043EA, 0xF9415948, 0xF94043EA
-};
-#define FREE_CODE_OFF_2ND_500 (FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500) + sizeof(u32))
-static u32 PRC_ID_RCV_500[] =
-{
- 0xF9403BED, 0x2A1503EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
- 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B08, 0xF9406FEA
-};
-
-static u32 PRC_ID_SND_600[] =
-{
- 0xA9BF2FEA, 0xF94037EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
- 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
- 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
-};
-#define FREE_CODE_OFF_2ND_600 (FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600) + sizeof(u32))
-static u32 PRC_ID_RCV_600[] =
-{
- 0xA9BF2FEA, 0xF94043EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
- 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
- 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
-};
-
-static u32 PRC_ID_SND_700[] =
-{
- 0xA9BF2FEA, 0xF9403BEB, 0x2A1903EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
- 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0,
- 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
-};
-#define FREE_CODE_OFF_2ND_700 (FREE_CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700) + sizeof(u32))
-static u32 PRC_ID_RCV_700[] =
-{
- 0xA9BF2FEA, 0xF9404FEB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
- 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0,
- 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
-};
-
-#define FREE_CODE_OFF_2ND_800 (FREE_CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700) + sizeof(u32))
-
-static u32 PRC_ID_SND_900[] =
-{
- 0xA9BF2FEA, 0xF94037EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
- 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0,
- 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
-};
-#define FREE_CODE_OFF_2ND_900 (FREE_CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900) + sizeof(u32))
-static u32 PRC_ID_RCV_900[] =
-{
- 0xA9BF2FEA, 0xF9404BEB, 0x2A1703EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
- 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0,
- 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
-};
-
-static u32 PRC_ID_SND_1000[] =
-{
- 0xA9BF2FEA, 0xF94063EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
- 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0,
- 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
-};
-#define FREE_CODE_OFF_2ND_1000 (FREE_CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000) + sizeof(u32))
-static u32 PRC_ID_RCV_1000[] =
-{
- 0xA9BF2FEA, 0xF94067EB, 0x2A1A03EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
- 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0,
- 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
-};
-
-// Include kernel patches here, so we can utilize pkg1 id
-KERNEL_PATCHSET_DEF(_kernel_1_patchset,
- { SVC_VERIFY_DS, 0x3764C, _NOP(), NULL }, // Disable SVC verifications
- { DEBUG_MODE_EN, 0x44074, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
- // Atmosphère kernel patches.
- { ATM_GEN_PATCH, ID_SND_OFF_100, _B(ID_SND_OFF_100, FREE_CODE_OFF_1ST_100), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_100, sizeof(PRC_ID_SND_100) >> 2, PRC_ID_SND_100}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), // Branch back and skip 1 instruction.
- _B(FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), ID_SND_OFF_100 + sizeof(u32)), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_100, _B(ID_RCV_OFF_100, FREE_CODE_OFF_2ND_100), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_100, sizeof(PRC_ID_RCV_100) >> 2, PRC_ID_RCV_100}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), // Branch back and skip 1 instruction.
- _B(FREE_CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), ID_RCV_OFF_100 + sizeof(u32)), NULL}
-);
-
-KERNEL_PATCHSET_DEF(_kernel_2_patchset,
- { SVC_VERIFY_DS, 0x54834, _NOP(), NULL }, // Disable SVC verifications
- { DEBUG_MODE_EN, 0x6086C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
- // Atmosphère kernel patches.
- { ATM_GEN_PATCH, ID_SND_OFF_200, _B(ID_SND_OFF_200, FREE_CODE_OFF_1ST_200), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_200, sizeof(PRC_ID_SND_200) >> 2, PRC_ID_SND_200}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), // Branch back and skip 1 instruction.
- _B(FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), ID_SND_OFF_200 + sizeof(u32)), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_200, _B(ID_RCV_OFF_200, FREE_CODE_OFF_2ND_200), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_200, sizeof(PRC_ID_RCV_200) >> 2, PRC_ID_RCV_200}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), // Branch back and skip 1 instruction.
- _B(FREE_CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), ID_RCV_OFF_200 + sizeof(u32)), NULL}
-);
-
-KERNEL_PATCHSET_DEF(_kernel_3_patchset,
- { SVC_VERIFY_DS, 0x3BD24, _NOP(), NULL }, // Disable SVC verifications
- { DEBUG_MODE_EN, 0x483FC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
- // Atmosphère kernel patches.
- { ATM_GEN_PATCH, ID_SND_OFF_300, _B(ID_SND_OFF_300, FREE_CODE_OFF_1ST_300), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_300, sizeof(PRC_ID_SND_300) >> 2, PRC_ID_SND_300}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), // Branch back and skip 1 instruction.
- _B(FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), ID_SND_OFF_300 + sizeof(u32)), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_300, _B(ID_RCV_OFF_300, FREE_CODE_OFF_2ND_300), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_300, sizeof(PRC_ID_RCV_300) >> 2, PRC_ID_RCV_300}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), // Branch back and skip 1 instruction.
- _B(FREE_CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), ID_RCV_OFF_300 + sizeof(u32)), NULL}
-);
-
-KERNEL_PATCHSET_DEF(_kernel_302_patchset,
- { SVC_VERIFY_DS, 0x3BD24, _NOP(), NULL }, // Disable SVC verifications
- { DEBUG_MODE_EN, 0x48414, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
- // Atmosphère kernel patches.
- { ATM_GEN_PATCH, ID_SND_OFF_302, _B(ID_SND_OFF_302, FREE_CODE_OFF_1ST_302), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_302, sizeof(PRC_ID_SND_300) >> 2, PRC_ID_SND_300}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_300), // Branch back and skip 1 instruction.
- _B(FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_300), ID_SND_OFF_302 + sizeof(u32)), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_302, _B(ID_RCV_OFF_302, FREE_CODE_OFF_2ND_302), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_302, sizeof(PRC_ID_RCV_300) >> 2, PRC_ID_RCV_300}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_300), // Branch back and skip 1 instruction.
- _B(FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_300), ID_RCV_OFF_302 + sizeof(u32)), NULL}
-);
-
-KERNEL_PATCHSET_DEF(_kernel_4_patchset,
- { SVC_VERIFY_DS, 0x41EB4, _NOP(), NULL }, // Disable SVC verifications
- { DEBUG_MODE_EN, 0x4EBFC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
- // Atmosphère kernel patches.
- { ATM_GEN_PATCH, ID_SND_OFF_400, _B(ID_SND_OFF_400, FREE_CODE_OFF_1ST_400), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_400, sizeof(PRC_ID_SND_400) >> 2, PRC_ID_SND_400}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), // Branch back and skip 2 instructions.
- _B(FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), ID_SND_OFF_400 + sizeof(u32) * 2), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_400, _B(ID_RCV_OFF_400, FREE_CODE_OFF_2ND_400), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_400, sizeof(PRC_ID_RCV_400) >> 2, PRC_ID_RCV_400}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), // Branch back and skip 1 instruction.
- _B(FREE_CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), ID_RCV_OFF_400 + sizeof(u32)), NULL}
-);
-
-KERNEL_PATCHSET_DEF(_kernel_5_patchset,
- { SVC_GENERIC, 0x38C2C, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
- { SVC_VERIFY_DS, 0x45E6C, _NOP(), NULL }, // Disable SVC verifications
- { DEBUG_MODE_EN, 0x5513C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
- // Atmosphère kernel patches.
- { ATM_SYSM_INCR, 0x54E30, _MOVZW(8, 0x1E00, LSL16), NULL }, // System memory pool increase.
- { ATM_GEN_PATCH, ID_SND_OFF_500, _B(ID_SND_OFF_500, FREE_CODE_OFF_1ST_500), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_500, sizeof(PRC_ID_SND_500) >> 2, PRC_ID_SND_500}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), // Branch back and skip 2 instructions.
- _B(FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), ID_SND_OFF_500 + sizeof(u32) * 2), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_500, _B(ID_RCV_OFF_500, FREE_CODE_OFF_2ND_500), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_500, sizeof(PRC_ID_RCV_500) >> 2, PRC_ID_RCV_500}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), // Branch back and skip 2 instructions.
- _B(FREE_CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), ID_RCV_OFF_500 + sizeof(u32) * 2), NULL}
-);
-
-KERNEL_PATCHSET_DEF(_kernel_6_patchset,
- { SVC_GENERIC, 0x3A8CC, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
- { SVC_VERIFY_DS, 0x47EA0, _NOP(), NULL }, // Disable SVC verifications
- { DEBUG_MODE_EN, 0x57548, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
- // Atmosphère kernel patches.
- { ATM_SYSM_INCR, 0x57330, _MOVZW(8, 0x1D80, LSL16), NULL }, // System memory pool increase.
- { ATM_GEN_PATCH, ID_SND_OFF_600, _B(ID_SND_OFF_600, FREE_CODE_OFF_1ST_600), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_600, sizeof(PRC_ID_SND_600) >> 2, PRC_ID_SND_600}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), // Branch back and skip 4 instructions.
- _B(FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), ID_SND_OFF_600 + sizeof(u32) * 4), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_600, _B(ID_RCV_OFF_600, FREE_CODE_OFF_2ND_600), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_600, sizeof(PRC_ID_RCV_600) >> 2, PRC_ID_RCV_600}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), // Branch back and skip 4 instructions.
- _B(FREE_CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), ID_RCV_OFF_600 + sizeof(u32) * 4), NULL}
-);
-
-KERNEL_PATCHSET_DEF(_kernel_7_patchset,
- { SVC_GENERIC, 0x3C6E0, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
- { SVC_VERIFY_DS, 0x49E5C, _NOP(), NULL }, // Disable SVC verifications
- { DEBUG_MODE_EN, 0x581B0, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
- // Atmosphère kernel patches.
- { ATM_SYSM_INCR, 0x57F98, _MOVZW(8, 0x1D80, LSL16), NULL }, // System memory pool increase.
- { ATM_GEN_PATCH, ID_SND_OFF_700, _B(ID_SND_OFF_700, FREE_CODE_OFF_1ST_700), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_700, sizeof(PRC_ID_SND_700) >> 2, PRC_ID_SND_700}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700), // Branch back and skip 4 instructions.
- _B(FREE_CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700), ID_SND_OFF_700 + sizeof(u32) * 4), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_700, _B(ID_RCV_OFF_700, FREE_CODE_OFF_2ND_700), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_700, sizeof(PRC_ID_RCV_700) >> 2, PRC_ID_RCV_700}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_700 + sizeof(PRC_ID_RCV_700), // Branch back and skip 4 instructions.
- _B(FREE_CODE_OFF_2ND_700 + sizeof(PRC_ID_RCV_700), ID_RCV_OFF_700 + sizeof(u32) * 4), NULL}
-);
-
-KERNEL_PATCHSET_DEF(_kernel_8_patchset,
- { SVC_GENERIC, 0x3FAD0, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
- { SVC_VERIFY_DS, 0x4D15C, _NOP(), NULL }, // Disable SVC verifications
- { DEBUG_MODE_EN, 0x5BFAC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
- // Atmosphère kernel patches.
- { ATM_SYSM_INCR, 0x5F9A4, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
- { ATM_GEN_PATCH, ID_SND_OFF_800, _B(ID_SND_OFF_800, FREE_CODE_OFF_1ST_800), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_800, sizeof(PRC_ID_SND_700) >> 2, PRC_ID_SND_700}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700), // Branch back and skip 4 instructions.
- _B(FREE_CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700), ID_SND_OFF_800 + sizeof(u32) * 4), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_800, _B(ID_RCV_OFF_800, FREE_CODE_OFF_2ND_800), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_800, sizeof(PRC_ID_RCV_700) >> 2, PRC_ID_RCV_700}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_800 + sizeof(PRC_ID_RCV_700), // Branch back and skip 4 instructions.
- _B(FREE_CODE_OFF_2ND_800 + sizeof(PRC_ID_RCV_700), ID_RCV_OFF_800 + sizeof(u32) * 4), NULL}
-);
-
-KERNEL_PATCHSET_DEF(_kernel_9_patchset,
- { SVC_GENERIC, 0x43DFC, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
- { SVC_VERIFY_DS, 0x50628, _NOP(), NULL }, // Disable SVC verifications
- { DEBUG_MODE_EN, 0x609E8, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
- // Atmosphère kernel patches.
- { ATM_SYSM_INCR, 0x6493C, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
- { ATM_GEN_PATCH, ID_SND_OFF_900, _B(ID_SND_OFF_900, FREE_CODE_OFF_1ST_900), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_900, sizeof(PRC_ID_SND_900) >> 2, PRC_ID_SND_900}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900), // Branch back and skip 4 instructions.
- _B(FREE_CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900), ID_SND_OFF_900 + sizeof(u32) * 4), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_900, _B(ID_RCV_OFF_900, FREE_CODE_OFF_2ND_900), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_900, sizeof(PRC_ID_RCV_900) >> 2, PRC_ID_RCV_900}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_900 + sizeof(PRC_ID_RCV_900), // Branch back and skip 4 instructions.
- _B(FREE_CODE_OFF_2ND_900 + sizeof(PRC_ID_RCV_900), ID_RCV_OFF_900 + sizeof(u32) * 4), NULL}
-);
-
-KERNEL_PATCHSET_DEF(_kernel_10_patchset,
- { SVC_GENERIC, 0x45DAC, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
- { SVC_VERIFY_DS, 0x523E4, _NOP(), NULL }, // Disable SVC verifications.
- { DEBUG_MODE_EN, 0x62B14, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch.
- // Atmosphère kernel patches.
- { ATM_SYSM_INCR, 0x66950, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
- { ATM_GEN_PATCH, ID_SND_OFF_1000, _B(ID_SND_OFF_1000, FREE_CODE_OFF_1ST_1000), NULL}, // Send process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_1000, sizeof(PRC_ID_SND_1000) >> 2, PRC_ID_SND_1000}, // Send process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000), // Branch back and skip 4 instructions.
- _B(FREE_CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000), ID_SND_OFF_1000 + sizeof(u32) * 4), NULL},
- { ATM_GEN_PATCH, ID_RCV_OFF_1000, _B(ID_RCV_OFF_1000, FREE_CODE_OFF_2ND_1000), NULL}, // Receive process id branch.
- { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_1000, sizeof(PRC_ID_RCV_1000) >> 2, PRC_ID_RCV_1000}, // Receive process id code.
- { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_1000 + sizeof(PRC_ID_RCV_1000), // Branch back and skip 4 instructions.
- _B(FREE_CODE_OFF_2ND_1000 + sizeof(PRC_ID_RCV_1000), ID_RCV_OFF_1000 + sizeof(u32) * 4), NULL}
-);
-
-// Kernel sha256 hashes.
-static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
-{
- { "\xb8\xc5\x0c\x68\x25\xa9\xb9\x5b", _kernel_1_patchset }, //1.0.0
- { "\x64\x0b\x51\xff\x28\x01\xb8\x30", _kernel_2_patchset }, //2.0.0 - 2.3.0
- { "\x50\x84\x23\xac\x6f\xa1\x5d\x3b", _kernel_3_patchset }, //3.0.0 - 3.0.1
- { "\x81\x9d\x08\xbe\xe4\x5e\x1f\xbb", _kernel_302_patchset }, //3.0.2
- { "\xe6\xc0\xb7\xe3\x2f\xf9\x44\x51", _kernel_4_patchset }, //4.0.0 - 4.1.0
- { "\xb2\x38\x61\xa8\xe1\xe2\xe4\xe4", _kernel_5_patchset }, //5.0.0 - 5.1.0
- { "\x85\x97\x40\xf6\xc0\x3e\x3d\x44", _kernel_6_patchset }, //6.0.0 - 6.2.0
- { "\xa2\x5e\x47\x0c\x8e\x6d\x2f\xd7", _kernel_7_patchset }, //7.0.0 - 7.0.1
- { "\xf1\x5e\xc8\x34\xfd\x68\xf0\xf0", _kernel_8_patchset }, //8.0.0 - 8.1.0. Kernel only.
- { "\x69\x00\x39\xdf\x21\x56\x70\x6b", _kernel_9_patchset }, //9.0.0 - 9.1.0. Kernel only.
- { "\xa2\xe3\xad\x1c\x98\xd8\x7a\x62", _kernel_9_patchset }, //9.2.0. Kernel only.
- { "\x21\xc1\xd7\x24\x8e\xcd\xbd\xa8", _kernel_10_patchset }, //10.0.0. Kernel only.
-};
-
-enum kip_offset_section
-{
- KIP_TEXT = 0,
- KIP_RODATA = 1,
- KIP_DATA = 2,
- KIP_BSS = 3,
- KIP_UNKSEC1 = 4,
- KIP_UNKSEC2 = 5
-};
-
-#define KIP_PATCH_SECTION_SHIFT (29)
-#define KIP_PATCH_SECTION_MASK (7 << KIP_PATCH_SECTION_SHIFT)
-#define KIP_PATCH_OFFSET_MASK (~KIP_PATCH_SECTION_MASK)
-#define GET_KIP_PATCH_SECTION(x) ((x >> KIP_PATCH_SECTION_SHIFT) & 7)
-#define GET_KIP_PATCH_OFFSET(x) (x & KIP_PATCH_OFFSET_MASK)
-#define KPS(x) ((u32)(x) << KIP_PATCH_SECTION_SHIFT)
-
-static kip1_patch_t _fs_emummc[] =
-{
- { KPS(KIP_TEXT) | 1, 0, "", "" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_100[] =
-{
- { "nogc", NULL },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_40x[] =
-{
- { KPS(KIP_TEXT) | 0xA3458, 4, "\x14\x40\x80\x72", "\x14\x80\x80\x72" },
- { KPS(KIP_TEXT) | 0xAAB44, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_40x[] =
-{
- { "nogc", _fs_nogc_40x },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_410[] =
-{
- { KPS(KIP_TEXT) | 0xA34BC, 4, "\x14\x40\x80\x72", "\x14\x80\x80\x72" },
- { KPS(KIP_TEXT) | 0xAABA8, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_410[] =
-{
- { "nogc", _fs_nogc_410 },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_50x[] =
-{
- { KPS(KIP_TEXT) | 0xCF3C4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { KPS(KIP_TEXT) | 0xD73A0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_50x[] =
-{
- { "nogc", _fs_nogc_50x },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_510[] =
-{
- { KPS(KIP_TEXT) | 0xCF794, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { KPS(KIP_TEXT) | 0xD7770, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_510[] =
-{
- { "nogc", _fs_nogc_510 },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_600[] =
-{
- { KPS(KIP_TEXT) | 0x12CC20, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { KPS(KIP_TEXT) | 0x1538F4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_600_exfat[] =
-{
- { KPS(KIP_TEXT) | 0x138320, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { KPS(KIP_TEXT) | 0x15EFF4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_600[] =
-{
- { "nogc", _fs_nogc_600 },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_600_exfat[] =
-{
- { "nogc", _fs_nogc_600_exfat },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_700[] =
-{
- { KPS(KIP_TEXT) | 0x134160, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { KPS(KIP_TEXT) | 0x15BF04, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_700_exfat[] =
-{
- { KPS(KIP_TEXT) | 0x13F710, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { KPS(KIP_TEXT) | 0x1674B4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_700[] =
-{
- { "nogc", _fs_nogc_700 },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_700_exfat[] =
-{
- { "nogc", _fs_nogc_700_exfat },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_800[] =
-{
- { KPS(KIP_TEXT) | 0x136800, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { KPS(KIP_TEXT) | 0x15EB94, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_800_exfat[] =
-{
- { KPS(KIP_TEXT) | 0x141DB0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { KPS(KIP_TEXT) | 0x16A144, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_800[] =
-{
- { "nogc", _fs_nogc_800 },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_800_exfat[] =
-{
- { "nogc", _fs_nogc_800_exfat },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_900[] =
-{
- { KPS(KIP_TEXT) | 0x129420, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { KPS(KIP_TEXT) | 0x143268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_900[] =
-{
- { "nogc", _fs_nogc_900 },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_910[] =
-{
- { KPS(KIP_TEXT) | 0x129430, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { KPS(KIP_TEXT) | 0x143278, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_910[] =
-{
- { "nogc", _fs_nogc_910 },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-static kip1_patch_t _fs_nogc_1000[] =
-{
- { KPS(KIP_TEXT) | 0x13BE90, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
- { KPS(KIP_TEXT) | 0x14DE08, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
- { 0, 0, NULL, NULL }
-};
-
-static kip1_patchset_t _fs_patches_1000[] =
-{
- { "nogc", _fs_nogc_1000 },
- { "emummc", _fs_emummc },
- { NULL, NULL }
-};
-
-// SHA256 hashes.
-static kip1_id_t _kip_ids[] =
-{
- { "FS", "\xde\x9f\xdd\xa4\x08\x5d\xd5\xfe", _fs_patches_100 }, // FS 1.0.0
- { "FS", "\xfc\x3e\x80\x99\x1d\xca\x17\x96", _fs_patches_100 }, // FS 1.0.0 exfat
- { "FS", "\xcd\x7b\xbe\x18\xd6\x13\x0b\x28", _fs_patches_100 }, // FS 2.0.0
- { "FS", "\xe7\x66\x92\xdf\xaa\x04\x20\xe9", _fs_patches_100 }, // FS 2.0.0 exfat
- { "FS", "\x0d\x70\x05\x62\x7b\x07\x76\x7c", _fs_patches_100 }, // FS 2.1.0
- { "FS", "\xdb\xd8\x5f\xca\xcc\x19\x3d\xa8", _fs_patches_100 }, // FS 2.1.0 exfat
- { "FS", "\xa8\x6d\xa5\xe8\x7e\xf1\x09\x7b", _fs_patches_100 }, // FS 3.0.0
- { "FS", "\x98\x1c\x57\xe7\xf0\x2f\x70\xf7", _fs_patches_100 }, // FS 3.0.0 exfat
- { "FS", "\x57\x39\x7c\x06\x3f\x10\xb6\x31", _fs_patches_100 }, // FS 3.0.1
- { "FS", "\x07\x30\x99\xd7\xc6\xad\x7d\x89", _fs_patches_100 }, // FS 3.0.1 exfat
- { "FS", "\x06\xe9\x07\x19\x59\x5a\x01\x0c", _fs_patches_40x }, // FS 4.0.1
- { "FS", "\x54\x9b\x0f\x8d\x6f\x72\xc4\xe9", _fs_patches_40x }, // FS 4.0.1 exfat
- { "FS", "\x80\x96\xaf\x7c\x6a\x35\xaa\x82", _fs_patches_410 }, // FS 4.1.0
- { "FS", "\x02\xd5\xab\xaa\xfd\x20\xc8\xb0", _fs_patches_410 }, // FS 4.1.0 exfat
- { "FS", "\xa6\xf2\x7a\xd9\xac\x7c\x73\xad", _fs_patches_50x }, // FS 5.0.0
- { "FS", "\xce\x3e\xcb\xa2\xf2\xf0\x62\xf5", _fs_patches_50x }, // FS 5.0.0 exfat
- { "FS", "\x76\xf8\x74\x02\xc9\x38\x7c\x0f", _fs_patches_510 }, // FS 5.1.0
- { "FS", "\x10\xb2\xd8\x16\x05\x48\x85\x99", _fs_patches_510 }, // FS 5.1.0 exfat
- { "FS", "\x1b\x82\xcb\x22\x18\x67\xcb\x52", _fs_patches_600 }, // FS 6.0.0-4.0
- { "FS", "\x96\x6a\xdd\x3d\x20\xb6\x27\x13", _fs_patches_600_exfat }, // FS 6.0.0-4.0 exfat
- { "FS", "\x3a\x57\x4d\x43\x61\x86\x19\x1d", _fs_patches_600 }, // FS 6.0.0-5.0
- { "FS", "\x33\x05\x53\xf6\xb5\xfb\x55\xc4", _fs_patches_600_exfat }, // FS 6.0.0-5.0 exfat
- { "FS", "\x2A\xDB\xE9\x7E\x9B\x5F\x41\x77", _fs_patches_700 }, // FS 7.0.0
- { "FS", "\x2C\xCE\x65\x9C\xEC\x53\x6A\x8E", _fs_patches_700_exfat }, // FS 7.0.0 exfat
- { "FS", "\xB2\xF5\x17\x6B\x35\x48\x36\x4D", _fs_patches_800 }, // FS 8.0.0
- { "FS", "\xDB\xD9\x41\xC0\xC5\x3C\x52\xCC", _fs_patches_800_exfat }, // FS 8.0.0 exfat
- { "FS", "\x6B\x09\xB6\x7B\x29\xC0\x20\x24", _fs_patches_800 }, // FS 8.1.0
- { "FS", "\xB4\xCA\xE1\xF2\x49\x65\xD9\x2E", _fs_patches_800_exfat }, // FS 8.1.0 exfat
- { "FS", "\x46\x87\x40\x76\x1E\x19\x3E\xB7", _fs_patches_900 }, // FS 9.0.0
- { "FS", "\x7C\x95\x13\x76\xE5\xC1\x2D\xF8", _fs_patches_900 }, // FS 9.0.0 exfat
- { "FS", "\xB5\xE7\xA6\x4C\x6F\x5C\x4F\xE3", _fs_patches_910 }, // FS 9.1.0
- { "FS", "\xF1\x96\xD1\x44\xD0\x44\x45\xB6", _fs_patches_910 }, // FS 9.1.0 exfat
- { "FS", "\x3E\xEB\xD9\xB7\xBC\xD1\xB5\xE0", _fs_patches_1000 }, // FS 10.0.0
- { "FS", "\x81\x7E\xA2\xB0\xB7\x02\xC1\xF3", _fs_patches_1000 }, // FS 10.0.0 exfat
-};
-
-static kip1_id_t *_kip_id_sets = _kip_ids;
-static u32 _kip_id_sets_cnt = sizeof(_kip_ids) / sizeof(_kip_ids[0]);
-
-void pkg2_get_ids(kip1_id_t **ids, u32 *entries)
-{
- *ids = _kip_id_sets;
- *entries = _kip_id_sets_cnt;
-}
-
-static void parse_external_kip_patches()
-{
- static bool ext_patches_done = false;
-
- if (ext_patches_done)
- return;
-
- u32 curr_kip_idx = 0;
- char path[64];
- strcpy(path, "bootloader/patches.ini");
-
- LIST_INIT(ini_kip_sections);
- if (ini_patch_parse(&ini_kip_sections, path))
- {
- // Copy ids into a new patchset.
- _kip_id_sets = calloc(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* curr_kip = NULL;
- bool found = false;
- for (curr_kip_idx = 0; curr_kip_idx < _kip_id_sets_cnt + 1; curr_kip_idx++)
- {
- curr_kip = &_kip_id_sets[curr_kip_idx];
-
- if (!curr_kip->name)
- break;
-
- if (!strcmp(curr_kip->name, ini_psec->name) && !memcmp(curr_kip->hash, ini_psec->hash, 8))
- {
- found = true;
- break;
- }
- }
-
- if (!curr_kip)
- continue;
-
- // If not found, create a new empty entry.
- if (!found)
- {
- curr_kip->name = ini_psec->name;
- memcpy(curr_kip->hash, ini_psec->hash, 8);
- curr_kip->patchset = calloc(sizeof(kip1_patchset_t), 1);
-
- _kip_id_sets_cnt++;
- }
-
- kip1_patchset_t *patchsets = (kip1_patchset_t *)calloc(sizeof(kip1_patchset_t), 16); // Max 16 patchsets per kip.
-
- u32 curr_patchset_idx;
- for(curr_patchset_idx = 0; curr_kip->patchset[curr_patchset_idx].name != NULL; curr_patchset_idx++)
- {
- patchsets[curr_patchset_idx].name = curr_kip->patchset[curr_patchset_idx].name;
- patchsets[curr_patchset_idx].patches = curr_kip->patchset[curr_patchset_idx].patches;
- }
-
- curr_kip->patchset = patchsets;
- bool first_ext_patch = true;
- u32 curr_patch_idx = 0;
-
- // Parse patches and glue them together to a patchset.
- kip1_patch_t *patches = calloc(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[curr_patchset_idx].name = malloc(strlen(pt->name) + 1);
- strcpy(patchsets[curr_patchset_idx].name, pt->name);
- patchsets[curr_patchset_idx].patches = patches;
- }
- else
- {
- // Check if new patchset name is found and create a new set.
- if (strcmp(pt->name, patchsets[curr_patchset_idx].name))
- {
- curr_patchset_idx++;
- curr_patch_idx = 0;
- patches = calloc(sizeof(kip1_patch_t), 16); // Max 16 patches per set.
-
- patchsets[curr_patchset_idx].name = malloc(strlen(pt->name) + 1);
- strcpy(patchsets[curr_patchset_idx].name, pt->name);
- patchsets[curr_patchset_idx].patches = patches;
- }
- }
-
- if (pt->length)
- {
- patches[curr_patch_idx].offset = pt->offset;
- patches[curr_patch_idx].length = pt->length;
-
- patches[curr_patch_idx].srcData = malloc(pt->length);
- patches[curr_patch_idx].dstData = malloc(pt->length);
- memcpy(patches[curr_patch_idx].srcData, pt->srcData, pt->length);
- memcpy(patches[curr_patch_idx].dstData, pt->dstData, pt->length);
- }
- else
- patches[curr_patch_idx].srcData = malloc(1); // Empty patches check. Keep everything else as 0.
-
- curr_patch_idx++;
- }
- curr_patchset_idx++;
- patchsets[curr_patchset_idx].name = NULL;
- patchsets[curr_patchset_idx].patches = NULL;
- }
- }
-
- ext_patches_done = true;
-}
-
-const pkg2_kernel_id_t *pkg2_identify(u8 *hash)
-{
- for (u32 i = 0; i < (sizeof(_pkg2_kernel_ids) / sizeof(pkg2_kernel_id_t)); i++)
- {
- if (!memcmp(hash, _pkg2_kernel_ids[i].hash, sizeof(_pkg2_kernel_ids[0].hash)))
- return &_pkg2_kernel_ids[i];
- }
- return NULL;
-}
+/*#include "util.h"
+#define DPRINTF(...) gfx_printf(__VA_ARGS__)
+#define DEBUG_PRINTING*/
+#define DPRINTF(...)
static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
{
@@ -806,7 +66,7 @@ void pkg2_get_newkern_info(u8 *kern_data)
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)
{
@@ -842,45 +102,6 @@ DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size);
return true;
}
-int 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;
-}
-
-void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1)
-{
- LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
- {
- if (ki->kip1->tid == tid)
- {
- ki->kip1 = kip1;
- ki->size = _pkg2_calc_kip1_size(kip1);
-DPRINTF("replaced kip %s (new size %08X)\n", kip1->name, ki->size);
- return;
- }
- }
-}
-
-void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1)
-{
- 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);
-DPRINTF("added kip %s (size %08X)\n", kip1->name, ki->size);
- list_append(info, &ki->link);
-}
-
-void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1)
-{
- if (pkg2_has_kip(info, kip1->tid))
- pkg2_replace_kip(info, kip1->tid, kip1);
- else
- pkg2_add_kip(info, kip1);
-}
-
int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp)
{
u32 compClearMask = ~sectsToDecomp;
@@ -922,10 +143,9 @@ int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp)
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);
+ //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_con.mute = false;
gfx_printf("%kERROR decomping sect %d of %s KIP!%k\n", 0xFFFF0000, sectIdx, (char*)hdr.name, 0xFFCCCCCC);
free(newKip);
@@ -951,328 +171,9 @@ int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp)
return 0;
}
-static int _kipm_inject(const char *kipm_path, char *target_name, pkg2_kip1_info_t* ki)
+pkg2_hdr_t *pkg2_decrypt(void *data)
{
- if (!strcmp((const char *)ki->kip1->name, target_name))
- {
- 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 currSectIdx = 0; currSectIdx < KIP1_NUM_SECTIONS - 2; currSectIdx++)
- {
- if(!currSectIdx) // .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 (currSectIdx < 3)
- memcpy(ki->kip1->data + new_offset + inject_size, fs_kip->data + new_offset, fs_kip->sections[currSectIdx].size_comp);
- ki->kip1->sections[currSectIdx].offset += inject_size;
- }
- new_offset += fs_kip->sections[currSectIdx].size_comp;
- }
-
- // 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;
- }
-
- return 1;
-}
-
-static bool ext_patches_parsed = false;
-
-const char* pkg2_patch_kips(link_t *info, char* patchNames)
-{
- if (patchNames == NULL || patchNames[0] == 0)
- return NULL;
-
- if (!ext_patches_parsed)
- {
- parse_external_kip_patches();
- ext_patches_parsed = true;
- }
-
- static const u32 MAX_NUM_PATCHES_REQUESTED = sizeof(u32) * 8;
- char* patches[MAX_NUM_PATCHES_REQUESTED];
-
- u32 numPatches = 1;
- patches[0] = patchNames;
- {
- for (char* p = patchNames; *p != 0; p++)
- {
- if (*p == ',')
- {
- *p = 0;
- patches[numPatches++] = p + 1;
- if (numPatches >= MAX_NUM_PATCHES_REQUESTED)
- return "too_many_patches";
- }
- else if (*p >= 'A' && *p <= 'Z')
- *p += 0x20;
- }
- }
-
- u32 patchesApplied = 0; // Bitset over patches.
- for (u32 i = 0; i < numPatches; i++)
- {
- // Eliminate leading spaces.
- for (const char* p = patches[i]; *p != 0; p++)
- {
- if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
- patches[i]++;
- else
- break;
- }
- int valueLen = strlen(patches[i]);
- if (valueLen == 0)
- continue;
-
- // Eliminate trailing spaces.
- for (int chIdx = valueLen - 1; chIdx >= 0; chIdx--)
- {
- const char* p = patches[i] + chIdx;
- if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
- valueLen = chIdx;
- else
- break;
- }
- patches[i][valueLen] = 0;
-
- DPRINTF("Requested patch: '%s'\n", patches[i]);
- }
-
- u32 shaBuf[32 / sizeof(u32)];
- LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
- {
- shaBuf[0] = 0; // sha256 for this kip not yet calculated.
- for (u32 currKipIdx = 0; currKipIdx < _kip_id_sets_cnt; currKipIdx++)
- {
- if (strncmp((const char*)ki->kip1->name, _kip_id_sets[currKipIdx].name, sizeof(ki->kip1->name)) != 0)
- continue;
-
- u32 bitsAffected = 0;
- kip1_patchset_t* currPatchset = _kip_id_sets[currKipIdx].patchset;
- while (currPatchset != NULL && currPatchset->name != NULL)
- {
- for (u32 i = 0; i < numPatches; i++)
- {
- if (strcmp(currPatchset->name, patches[i]) != 0)
- {
- bitsAffected = i + 1;
- break;
- }
- }
- currPatchset++;
- }
-
- // Dont bother even hashing this KIP if we dont have any patches enabled for it.
- if (bitsAffected == 0)
- continue;
-
- if (shaBuf[0] == 0)
- {
- if (!se_calc_sha256(shaBuf, ki->kip1, ki->size))
- memset(shaBuf, 0, sizeof(shaBuf));
- }
-
- if (memcmp(shaBuf, _kip_id_sets[currKipIdx].hash, sizeof(_kip_id_sets[0].hash)) != 0)
- continue;
-
- // Find out which sections are affected by the enabled patches, to know which to decompress.
- bitsAffected = 0;
- currPatchset = _kip_id_sets[currKipIdx].patchset;
- while (currPatchset != NULL && currPatchset->name != NULL)
- {
- if (currPatchset->patches != NULL)
- {
- for (u32 currEnabIdx = 0; currEnabIdx < numPatches; currEnabIdx++)
- {
- if (strcmp(currPatchset->name, patches[currEnabIdx]))
- continue;
-
- if (!strcmp(currPatchset->name, "emummc"))
- bitsAffected |= 1u << GET_KIP_PATCH_SECTION(currPatchset->patches->offset);
-
- for (const kip1_patch_t* currPatch=currPatchset->patches; currPatch != NULL && (currPatch->length != 0); currPatch++)
- bitsAffected |= 1u << GET_KIP_PATCH_SECTION(currPatch->offset);
- }
- }
- currPatchset++;
- }
-
- // Got patches to apply to this kip, have to decompress it.
-#ifdef DEBUG_PRINTING
- u32 preDecompTime = get_tmr_us();
-#endif
- if (pkg2_decompress_kip(ki, bitsAffected))
- return (const char*)ki->kip1->name; // Failed to decompress.
-
-#ifdef DEBUG_PRINTING
- u32 postDecompTime = get_tmr_us();
- if (!se_calc_sha256(shaBuf, ki->kip1, ki->size))
- memset(shaBuf, 0, sizeof(shaBuf));
-
- DPRINTF("%dms %s KIP1 size %d hash %08X\n", (postDecompTime-preDecompTime) / 1000, ki->kip1->name, (int)ki->size, __builtin_bswap32(shaBuf[0]));
-#endif
-
- currPatchset = _kip_id_sets[currKipIdx].patchset;
- bool emummc_patch_selected = false;
- while (currPatchset != NULL && currPatchset->name != NULL)
- {
- for (u32 currEnabIdx = 0; currEnabIdx < numPatches; currEnabIdx++)
- {
- if (strcmp(currPatchset->name, patches[currEnabIdx]))
- continue;
-
- u32 appliedMask = 1u << currEnabIdx;
-
- if (!strcmp(currPatchset->name, "emummc"))
- {
- emummc_patch_selected = true;
- patchesApplied |= appliedMask;
-
- break;
- }
-
- if (currPatchset->patches == NULL)
- {
- gfx_printf("Patch '%s' not necessary for %s KIP1\n", currPatchset->name, (const char*)ki->kip1->name);
- patchesApplied |= appliedMask;
-
- break;
- }
-
- unsigned char* kipSectData = ki->kip1->data;
- for (u32 currSectIdx = 0; currSectIdx < KIP1_NUM_SECTIONS; currSectIdx++)
- {
- if (bitsAffected & (1u << currSectIdx))
- {
- gfx_printf("Applying patch '%s' on %s KIP1 sect %d\n", currPatchset->name, (const char*)ki->kip1->name, currSectIdx);
- for (const kip1_patch_t* currPatch = currPatchset->patches; currPatch != NULL && currPatch->srcData != 0; currPatch++)
- {
- if (GET_KIP_PATCH_SECTION(currPatch->offset) != currSectIdx)
- continue;
-
- if (!currPatch->length)
- {
- gfx_con.mute = false;
- gfx_printf("%kPatch is empty!%k\n", 0xFFFF0000, 0xFFCCCCCC);
- return currPatchset->name; // MUST stop here as it's not probably intended.
- }
-
- u32 currOffset = GET_KIP_PATCH_OFFSET(currPatch->offset);
- // If source is does not match and is not already patched, throw an error.
- if ((memcmp(&kipSectData[currOffset], currPatch->srcData, currPatch->length) != 0) &&
- (memcmp(&kipSectData[currOffset], currPatch->dstData, currPatch->length) != 0))
- {
- gfx_con.mute = false;
- gfx_printf("%kPatch data mismatch at 0x%x!%k\n", 0xFFFF0000, currOffset, 0xFFCCCCCC);
- return currPatchset->name; // MUST stop here as kip is likely corrupt.
- }
- else
- {
- DPRINTF("Patching %d bytes at offset 0x%x\n", currPatch->length, currOffset);
- memcpy(&kipSectData[currOffset], currPatch->dstData, currPatch->length);
- }
- }
- }
- kipSectData += ki->kip1->sections[currSectIdx].size_comp;
- }
-
- patchesApplied |= appliedMask;
- break;
- }
- currPatchset++;
- }
- if (emummc_patch_selected && !strncmp(_kip_id_sets[currKipIdx].name, "FS", 2))
- {
- emummc_patch_selected = false;
- emu_cfg.fs_ver = currKipIdx;
- if (currKipIdx)
- emu_cfg.fs_ver--;
- if (currKipIdx > 17)
- emu_cfg.fs_ver -= 2;
-
- gfx_printf("Injecting emuMMC. FS ver: %d\n", emu_cfg.fs_ver);
- if (_kipm_inject("/bootloader/sys/emummc.kipm", "FS", ki))
- return "emummc";
- }
- }
- }
-
- for (u32 i = 0; i < numPatches; i++)
- {
- if ((patchesApplied & (1u << i)) == 0)
- return patches[i];
- }
-
- return NULL;
-}
-
-static const u8 mkey_keyseed_8xx[][0x10] =
-{
- // Master key 8 encrypted with 9. (8.1.0 with 9.0.0)
- { 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 },
- // Master key 9 encrypted with 10. (9.0.0 with 9.1.0)
- { 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A }
-};
-
-static bool _pkg2_key_unwrap_validate(pkg2_hdr_t *tmp_test, pkg2_hdr_t *hdr, u8 src_slot, u8 *mkey, const u8 *key_seed)
-{
- // Decrypt older encrypted mkey.
- se_aes_crypt_ecb(src_slot, 0, mkey, 0x10, key_seed, 0x10);
- // Set and unwrap pkg2 key.
- se_aes_key_clear(9);
- se_aes_key_set(9, mkey, 0x10);
- se_aes_unwrap_key(9, 9, package2_keyseed);
-
- // Decrypt header.
- se_aes_crypt_ctr(9, tmp_test, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
-
- // Return if header is valid.
- return (tmp_test->magic == PKG2_MAGIC);
-}
-
-pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb)
-{
- pkg2_hdr_t mkey_test;
u8 *pdata = (u8 *)data;
- u8 keyslot = 8;
// Skip signature.
pdata += 0x100;
@@ -1282,60 +183,8 @@ pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb)
// Skip header.
pdata += sizeof(pkg2_hdr_t);
- //! Check if we need to decrypt with newer mkeys. Valid for sept for 8.1.0 and up.
- se_aes_crypt_ctr(8, &mkey_test, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
-
- if (mkey_test.magic == PKG2_MAGIC)
- goto key_found;
-
- // Decrypt older pkg2 via new mkeys.
- if ((kb >= KB_FIRMWARE_VERSION_810) && (kb < KB_FIRMWARE_VERSION_MAX))
- {
- u8 tmp_mkey[0x10];
- u8 decr_slot = 12; // Sept mkey.
- u8 mkey_seeds_cnt = sizeof(mkey_keyseed_8xx) / 0x10;
- u8 mkey_seeds_idx = mkey_seeds_cnt; // Real index + 1.
- u8 mkey_seeds_min_idx = mkey_seeds_cnt - (KB_FIRMWARE_VERSION_MAX - kb);
-
- while (mkey_seeds_cnt)
- {
- // Decrypt and validate mkey.
- int res = _pkg2_key_unwrap_validate(&mkey_test, hdr, decr_slot,
- tmp_mkey, mkey_keyseed_8xx[mkey_seeds_idx - 1]);
-
- if (res)
- {
- keyslot = 9;
- goto key_found;
- }
- else
- {
- // Set current mkey in order to decrypt a lower mkey.
- mkey_seeds_idx--;
- se_aes_key_clear(9);
- se_aes_key_set(9, tmp_mkey, 0x10);
-
- decr_slot = 9; // Temp key.
-
- // Check if we tried last key for that pkg2 version.
- // And start with a lower mkey in case sept is older.
- if (mkey_seeds_idx == mkey_seeds_min_idx)
- {
- mkey_seeds_cnt--;
- mkey_seeds_idx = mkey_seeds_cnt;
- decr_slot = 12; // Sept mkey.
- }
-
- // Out of keys. pkg2 is latest or process failed.
- if (!mkey_seeds_cnt)
- se_aes_key_clear(9);
- }
- }
- }
-
-key_found:
// Decrypt header.
- se_aes_crypt_ctr(keyslot, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
+ 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)
@@ -1347,94 +196,11 @@ DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]);
if (!hdr->sec_size[i])
continue;
- se_aes_crypt_ctr(keyslot, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]);
+ 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];
}
- if (keyslot != 8)
- se_aes_key_clear(9);
-
return hdr;
}
-
-static u32 _pkg2_ini1_build(u8 *pdst, pkg2_hdr_t *hdr, link_t *kips_info, bool new_pkg2)
-{
- u32 ini1_size = sizeof(pkg2_ini1_t);
- pkg2_ini1_t *ini1 = (pkg2_ini1_t *)pdst;
- memset(ini1, 0, sizeof(pkg2_ini1_t));
- ini1->magic = INI1_MAGIC;
- pdst += sizeof(pkg2_ini1_t);
- LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link)
- {
-DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->size);
- memcpy(pdst, ki->kip1, ki->size);
- pdst += ki->size;
- ini1_size += ki->size;
- ini1->num_procs++;
- }
- ini1_size = ALIGN(ini1_size, 4);
- ini1->size = ini1_size;
- if (!new_pkg2)
- {
- hdr->sec_size[PKG2_SEC_INI1] = ini1_size;
- hdr->sec_off[PKG2_SEC_INI1] = 0x14080000;
- se_aes_crypt_ctr(8, ini1, ini1_size, ini1, ini1_size, &hdr->sec_ctr[PKG2_SEC_INI1 * 0x10]);
- }
- else
- {
- hdr->sec_size[PKG2_SEC_INI1] = 0;
- hdr->sec_off[PKG2_SEC_INI1] = 0;
- }
-
- return ini1_size;
-}
-
-void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info, bool new_pkg2)
-{
- u8 *pdst = (u8 *)dst;
-
- // Signature.
- memset(pdst, 0, 0x100);
- pdst += 0x100;
-
- // Header.
- pkg2_hdr_t *hdr = (pkg2_hdr_t *)pdst;
- memset(hdr, 0, sizeof(pkg2_hdr_t));
- pdst += sizeof(pkg2_hdr_t);
- hdr->magic = PKG2_MAGIC;
- if (!new_pkg2)
- hdr->base = 0x10000000;
- else
- hdr->base = 0x60000;
-DPRINTF("kernel @ %08X (%08X)\n", (u32)kernel, kernel_size);
-
- // Kernel.
- memcpy(pdst, kernel, kernel_size);
- if (!new_pkg2)
- hdr->sec_off[PKG2_SEC_KERNEL] = 0x10000000;
- else
- {
- // Set new INI1 offset to kernel.
- *(u32 *)(pdst + pkg2_newkern_ini1_val) = kernel_size;
- kernel_size += _pkg2_ini1_build(pdst + kernel_size, hdr, kips_info, new_pkg2);
- hdr->sec_off[PKG2_SEC_KERNEL] = 0x60000;
- }
- hdr->sec_size[PKG2_SEC_KERNEL] = kernel_size;
- se_aes_crypt_ctr(8, pdst, kernel_size, pdst, kernel_size, &hdr->sec_ctr[PKG2_SEC_KERNEL * 0x10]);
- pdst += kernel_size;
-DPRINTF("kernel encrypted\n");
-
- // INI1.
- u32 ini1_size = 0;
- if (!new_pkg2)
- ini1_size = _pkg2_ini1_build(pdst, hdr, kips_info, new_pkg2);
-DPRINTF("INI1 encrypted\n");
-
- //Encrypt header.
- *(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
- se_aes_crypt_ctr(8, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
- memset(hdr->ctr, 0 , 0x10);
- *(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
-}
diff --git a/source/hos/pkg2.h b/source/hos/pkg2.h
index 891ab5d..ba6a8a0 100644
--- a/source/hos/pkg2.h
+++ b/source/hos/pkg2.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2020 CTCaer
+ * 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,
@@ -26,41 +26,12 @@
#define PKG2_SEC_KERNEL 0
#define PKG2_SEC_INI1 1
-#define INI1_MAGIC 0x31494E49
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // Offset of OP + 12 is the INI1 offset.
-#define PKG2_NEWKERN_START 0x800
u32 pkg2_newkern_ini1_val;
u32 pkg2_newkern_ini1_start;
u32 pkg2_newkern_ini1_end;
-typedef struct _kernel_patch_t
-{
- u32 id;
- u32 off;
- u32 val;
- u32 *ptr;
-} kernel_patch_t;
-
-#define KERNEL_PATCHSET_DEF(name, ...) \
- kernel_patch_t name[] = { \
- __VA_ARGS__, \
- {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32 *)0xFFFFFFFF} \
- }
-
-enum
-{
- // Always applied.
- SVC_GENERIC = 0,
- // Generic instruction patches.
- SVC_VERIFY_DS = 0x10,
- DEBUG_MODE_EN = 0x11,
- ATM_GEN_PATCH = 0x12,
- ATM_SYSM_INCR = ATM_GEN_PATCH,
- // >4 bytes patches. Value is a pointer of a u32 array.
- ATM_ARR_PATCH = 0x13,
-};
-
typedef struct _pkg2_hdr_t
{
u8 ctr[0x10];
@@ -116,44 +87,8 @@ typedef struct _pkg2_kip1_info_t
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;
-
-typedef struct _kip1_patch_t
-{
- u32 offset; // section+offset of patch to apply.
- u32 length; // In bytes, 0 means last patch.
- char* srcData; // That must match.
- char* dstData; // That it gets replaced by.
-} kip1_patch_t;
-
-typedef struct _kip1_patchset_t
-{
- char* name; // NULL means end.
- kip1_patch_t* patches; // NULL means not necessary.
-} kip1_patchset_t;
-
-typedef struct _kip1_id_t
-{
- const char* name;
- u8 hash[8];
- kip1_patchset_t* patchset;
-} kip1_id_t;
-
-void pkg2_get_newkern_info(u8 *kern_data);
bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2);
-int 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);
-void pkg2_get_ids(kip1_id_t **ids, u32 *entries);
-const char* pkg2_patch_kips(link_t *info, char* patchNames);
-
-const pkg2_kernel_id_t *pkg2_identify(u8 *hash);
-pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb);
-void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info, 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/hos/pkg2_ini_kippatch.c b/source/hos/pkg2_ini_kippatch.c
deleted file mode 100644
index fba2635..0000000
--- a/source/hos/pkg2_ini_kippatch.c
+++ /dev/null
@@ -1,156 +0,0 @@
-#include
-#include
-
-#include "pkg2_ini_kippatch.h"
-#include "../libs/fatfs/ff.h"
-#include "../mem/heap.h"
-
-#define KPS(x) ((u32)(x) << 29)
-
-static u8 *_htoa(u8 *result, const char *ptr, u8 byte_len)
-{
- char ch = *ptr;
- u32 ascii_len = byte_len * 2;
- if (!result)
- result = malloc(byte_len);
- u8 *dst = result;
-
- while (ch == ' ' || ch == '\t')
- ch = *(++ptr);
-
- bool shift = true;
- while (ascii_len)
- {
- u8 tmp = 0;
- if (ch >= '0' && ch <= '9')
- tmp = (ch - '0');
- else if (ch >= 'A' && ch <= 'F')
- tmp = (ch - 'A' + 10);
- else if (ch >= 'a' && ch <= 'f')
- tmp = (ch - 'a' + 10);
-
- if (shift)
- *dst = (tmp << 4) & 0xF0;
- else
- {
- *dst |= (tmp & 0x0F);
- dst++;
- }
-
- ascii_len--;
- ch = *(++ptr);
- shift = !shift;
- }
-
- return result;
-}
-
-static char *_strdup(char *str)
-{
- if (!str)
- return NULL;
- if (str[0] == ' ' && (strlen(str) > 1))
- str++;
- char *res = (char *)malloc(strlen(str) + 1);
- strcpy(res, str);
- if (res[strlen(res) - 1] == ' ' && (strlen(res) > 1))
- res[strlen(res) - 1] = 0;
-
- return res;
-}
-
-static u32 _find_patch_section_name(char *lbuf, u32 lblen, char schar)
-{
- u32 i;
- for (i = 0; i < lblen && lbuf[i] != schar && lbuf[i] != '\n' && lbuf[i] != '\r'; i++)
- ;
- lbuf[i] = 0;
-
- return i;
-}
-
-static ini_kip_sec_t *_ini_create_kip_section(link_t *dst, ini_kip_sec_t *ksec, char *name)
-{
- if (ksec)
- list_append(dst, &ksec->link);
-
- ksec = (ini_kip_sec_t *)calloc(sizeof(ini_kip_sec_t), 1);
- u32 i = _find_patch_section_name(name, strlen(name), ':') + 1;
- ksec->name = _strdup(name);
-
- // Get hash section.
- _htoa(ksec->hash, &name[i], 8);
-
- return ksec;
-}
-
-int ini_patch_parse(link_t *dst, char *ini_path)
-{
- u32 lblen;
- char lbuf[512];
- FIL fp;
- ini_kip_sec_t *ksec = NULL;
-
- // Open ini.
- if (f_open(&fp, ini_path, FA_READ) != FR_OK)
- return 0;
-
- do
- {
- // Fetch one line.
- lbuf[0] = 0;
- f_gets(lbuf, 512, &fp);
- lblen = strlen(lbuf);
-
- // Remove trailing newline. Depends on 'FF_USE_STRFUNC 2' that removes \r.
- if (lblen && lbuf[lblen - 1] == '\n')
- lbuf[lblen - 1] = 0;
-
- if (lblen > 2 && lbuf[0] == '[') // Create new section.
- {
- _find_patch_section_name(lbuf, lblen, ']');
-
- ksec = _ini_create_kip_section(dst, ksec, &lbuf[1]);
- list_init(&ksec->pts);
- }
- else if (ksec && lbuf[0] == '.') //Extract key/value.
- {
- u32 tmp = 0;
- u32 i = _find_patch_section_name(lbuf, lblen, '=');
-
- ini_patchset_t *pt = (ini_patchset_t *)calloc(sizeof(ini_patchset_t), 1);
-
- pt->name = _strdup(&lbuf[1]);
-
- u8 kip_sidx = lbuf[i + 1] - '0';
-
- if (kip_sidx < 6)
- {
- pt->offset = KPS(kip_sidx);
- tmp = _find_patch_section_name(&lbuf[i + 3], lblen, ':');
- pt->offset |= strtol(&lbuf[i + 3], NULL, 16);
-
- i += tmp + 4;
-
- tmp = _find_patch_section_name(&lbuf[i], lblen, ':');
- pt->length = strtol(&lbuf[i], NULL, 16);
-
- i += tmp + 1;
-
- tmp = _find_patch_section_name(&lbuf[i], lblen, ',');
- pt->srcData = _htoa(NULL, &lbuf[i], pt->length);
- i += tmp + 1;
- pt->dstData = _htoa(NULL, &lbuf[i], pt->length);
- }
-
- list_append(&ksec->pts, &pt->link);
- }
- } while (!f_eof(&fp));
-
- f_close(&fp);
-
- if (ksec)
- list_append(dst, &ksec->link);
-
- return 1;
-}
diff --git a/source/hos/pkg2_ini_kippatch.h b/source/hos/pkg2_ini_kippatch.h
deleted file mode 100644
index f459c3c..0000000
--- a/source/hos/pkg2_ini_kippatch.h
+++ /dev/null
@@ -1,43 +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 _INIPATCH_H_
-#define _INIPATCH_H_
-
-#include "../utils/types.h"
-#include "../utils/list.h"
-
-typedef struct _ini_patchset_t
-{
- char *name;
- u32 offset; // section + offset of patch to apply.
- u32 length; // In bytes, 0 means last patch.
- u8 *srcData; // That must match.
- u8 *dstData; // Gets replaced with.
- link_t link;
-} ini_patchset_t;
-
-typedef struct _ini_kip_sec_t
-{
- char *name;
- u8 hash[8];
- link_t pts;
- link_t link;
-} ini_kip_sec_t;
-
-int ini_patch_parse(link_t *dst, char *ini_path);
-
-#endif
diff --git a/source/hos/secmon_exo.c b/source/hos/secmon_exo.c
deleted file mode 100644
index 60e062b..0000000
--- a/source/hos/secmon_exo.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (c) 2018-2020 CTCaer
- * Copyright (c) 2019 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
-
-#include "hos.h"
-#include "../config/config.h"
-#include "../gfx/di.h"
-#include "../gfx/gfx.h"
-#include "../libs/fatfs/ff.h"
-#include "../mem/heap.h"
-#include "../soc/fuse.h"
-#include "../storage/emummc.h"
-#include "../storage/nx_sd.h"
-#include "../storage/sdmmc.h"
-#include "../utils/btn.h"
-#include "../utils/util.h"
-#include "../utils/types.h"
-
-extern hekate_config h_cfg;
-
-enum emuMMC_Type
-{
- emuMMC_None = 0,
- emuMMC_Partition,
- emuMMC_File,
- emuMMC_MAX
-};
-
-/* "EFS0" */
-#define EMUMMC_MAGIC 0x30534645
-#define EMUMMC_FILE_PATH_MAX 0x80
-
-typedef struct
-{
- u32 magic;
- u32 type;
- u32 id;
- u32 fs_ver;
-} emummc_base_config_t;
-
-typedef struct
-{
- u64 start_sector;
-} emummc_partition_config_t;
-
-typedef struct
-{
- char path[EMUMMC_FILE_PATH_MAX];
-} emummc_file_config_t;
-
-typedef struct
-{
- emummc_base_config_t base_cfg;
- union
- {
- emummc_partition_config_t partition_cfg;
- emummc_file_config_t file_cfg;
- };
- char nintendo_path[EMUMMC_FILE_PATH_MAX];
-} exo_emummc_config_t;
-
-typedef struct _exo_cfg_t
-{
- u32 magic;
- u32 fwno;
- u32 flags;
- u32 reserved[5];
- exo_emummc_config_t emummc_cfg;
-} exo_cfg_t;
-
-typedef struct _atm_meta_t
-{
- u32 magic;
- u32 fwno;
-} wb_cfg_t;
-
-// Atmosphère reboot-to-fatal-error.
-typedef struct _atm_fatal_error_ctx
-{
- u32 magic;
- u32 error_desc;
- u64 title_id;
- union
- {
- u64 gprs[32];
- struct
- {
- u64 _gprs[29];
- u64 fp;
- u64 lr;
- u64 sp;
- };
- };
- u64 pc;
- u64 module_base;
- u32 pstate;
- u32 afsr0;
- u32 afsr1;
- u32 esr;
- u64 far;
- u64 report_identifier; // Normally just system tick.
- u64 stack_trace_size;
- u64 stack_dump_size;
- u64 stack_trace[0x20];
- u8 stack_dump[0x100];
- u8 tls[0x100];
-} atm_fatal_error_ctx;
-
-#define ATM_FATAL_ERR_CTX_ADDR 0x4003E000
-#define ATM_FATAL_MAGIC 0x30454641 // AFE0
-
-#define ATM_WB_HEADER_OFF 0x244
-#define ATM_WB_MAGIC 0x30544257
-
-// Exosphère mailbox defines.
-#define EXO_CFG_ADDR 0x8000F000
-#define EXO_MAGIC_VAL 0x304F5845
-#define EXO_FLAG_DBG_PRIV (1 << 1)
-#define EXO_FLAG_DBG_USER (1 << 2)
-#define EXO_FLAG_NO_USER_EXC (1 << 3)
-#define EXO_FLAG_USER_PMU (1 << 4)
-#define EXO_FLAG_CAL0_BLANKING (1 << 5)
-#define EXO_FLAG_CAL0_WRITES_SYS (1 << 6)
-
-void config_exosphere(launch_ctxt_t *ctxt)
-{
- u32 exoFwNo = 0;
- u32 exoFlags = 0;
- u32 kb = ctxt->pkg1_id->kb;
- bool user_debug = false;
- bool cal0_blanking = false;
- bool cal0_allow_writes_sys = false;
-
- memset((exo_cfg_t *)EXO_CFG_ADDR, 0, sizeof(exo_cfg_t));
-
- volatile exo_cfg_t *exo_cfg = (exo_cfg_t *)EXO_CFG_ADDR;
-
- switch (kb)
- {
- case KB_FIRMWARE_VERSION_100_200:
- if (!strcmp(ctxt->pkg1_id->id, "20161121183008"))
- exoFwNo = 1;
- else
- exoFwNo = 2;
- break;
- case KB_FIRMWARE_VERSION_300:
- exoFwNo = 3;
- break;
- default:
- exoFwNo = kb + 1;
- if (!strcmp(ctxt->pkg1_id->id, "20190314172056") || (kb >= KB_FIRMWARE_VERSION_810))
- exoFwNo++; // ATM_TARGET_FW_800/810/900/910.
- if (!strcmp(ctxt->pkg1_id->id, "20200303104606"))
- exoFwNo++; // ATM_TARGET_FW_1000.
- break;
- }
-
- if (!ctxt->stock)
- {
- // Parse exosphere.ini.
- LIST_INIT(ini_sections);
- if (ini_parse(&ini_sections, "exosphere.ini", false))
- {
- LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
- {
- // Only parse exosphere section.
- if (!(ini_sec->type == INI_CHOICE) || strcmp(ini_sec->name, "exosphere"))
- continue;
-
- LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
- {
- if (!strcmp("debugmode_user", kv->key))
- user_debug = atoi(kv->val);
- else if (emu_cfg.enabled && !h_cfg.emummc_force_disable)
- {
- if (!strcmp("blank_prodinfo_emummc", kv->key))
- cal0_blanking = atoi(kv->val);
- }
- else
- {
- if (!strcmp("blank_prodinfo_sysmmc", kv->key))
- cal0_blanking = atoi(kv->val);
- else if (!strcmp("allow_writing_to_cal_sysmmc", kv->key))
- cal0_allow_writes_sys = atoi(kv->val);
- }
- }
- break;
- }
- }
- }
-
- // To avoid problems, make private debug mode always on if not semi-stock.
- if (!ctxt->stock || (emu_cfg.enabled && !h_cfg.emummc_force_disable))
- exoFlags |= EXO_FLAG_DBG_PRIV;
-
- // Enable user debug.
- if (user_debug)
- exoFlags |= EXO_FLAG_DBG_USER;
-
- // Disable proper failure handling.
- if (ctxt->exo_cfg.no_user_exceptions)
- exoFlags |= EXO_FLAG_NO_USER_EXC;
-
- // Enable user access to PMU.
- if (ctxt->exo_cfg.user_pmu)
- exoFlags |= EXO_FLAG_USER_PMU;
-
- // Check if exo ini value is overridden and enable prodinfo blanking.
- if ((ctxt->exo_cfg.cal0_blank && *ctxt->exo_cfg.cal0_blank)
- || (!ctxt->exo_cfg.cal0_blank && cal0_blanking))
- exoFlags |= EXO_FLAG_CAL0_BLANKING;
-
- // Check if exo ini value is overridden and allow prodinfo writes.
- if ((ctxt->exo_cfg.cal0_allow_writes_sys && *ctxt->exo_cfg.cal0_allow_writes_sys)
- || (!ctxt->exo_cfg.cal0_allow_writes_sys && cal0_allow_writes_sys))
- exoFlags |= EXO_FLAG_CAL0_WRITES_SYS;
-
- // Set mailbox values.
- exo_cfg->magic = EXO_MAGIC_VAL;
- exo_cfg->fwno = exoFwNo;
- exo_cfg->flags = exoFlags;
-
- // If warmboot is lp0fw, add in RSA modulus.
- volatile wb_cfg_t *wb_cfg = (wb_cfg_t *)(ctxt->pkg1_id->warmboot_base + ATM_WB_HEADER_OFF);
-
- if (wb_cfg->magic == ATM_WB_MAGIC)
- {
- wb_cfg->fwno = exoFwNo;
-
- sdmmc_storage_t storage;
- sdmmc_t sdmmc;
-
- // Set warmboot binary rsa modulus.
- u8 *rsa_mod = (u8 *)malloc(512);
-
- sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400);
- sdmmc_storage_set_mmc_partition(&storage, EMMC_BOOT0);
- sdmmc_storage_read(&storage, 1, 1, rsa_mod);
- sdmmc_storage_end(&storage);
-
- // Patch AutoRCM out.
- if ((fuse_read_odm(4) & 3) != 3)
- rsa_mod[0x10] = 0xF7;
- else
- rsa_mod[0x10] = 0x37;
-
- memcpy((void *)(ctxt->pkg1_id->warmboot_base + 0x10), rsa_mod + 0x10, 0x100);
- }
-
- if (emu_cfg.enabled && !h_cfg.emummc_force_disable)
- {
- exo_cfg->emummc_cfg.base_cfg.magic = EMUMMC_MAGIC;
- exo_cfg->emummc_cfg.base_cfg.type = emu_cfg.sector ? emuMMC_Partition : emuMMC_File;
- exo_cfg->emummc_cfg.base_cfg.fs_ver = emu_cfg.fs_ver;
- exo_cfg->emummc_cfg.base_cfg.id = emu_cfg.id;
-
- if (emu_cfg.sector)
- exo_cfg->emummc_cfg.partition_cfg.start_sector = emu_cfg.sector;
- else
- strcpy((char *)exo_cfg->emummc_cfg.file_cfg.path, emu_cfg.path);
-
- if (emu_cfg.nintendo_path && !ctxt->stock)
- strcpy((char *)exo_cfg->emummc_cfg.nintendo_path, emu_cfg.nintendo_path);
- else if (ctxt->stock)
- strcpy((char *)exo_cfg->emummc_cfg.nintendo_path, "Nintendo");
- else
- exo_cfg->emummc_cfg.nintendo_path[0] = 0;
- }
-}
-
-static const char *get_error_desc(u32 error_desc)
-{
- switch (error_desc)
- {
- case 0x100:
- return "Instruction Abort";
- case 0x101:
- return "Data Abort";
- case 0x102:
- return "PC Misalignment";
- case 0x103:
- return "SP Misalignment";
- case 0x104:
- return "Trap";
- case 0x106:
- return "SError";
- case 0x301:
- return "Bad SVC";
- case 0xFFE:
- return "std::abort()";
- default:
- return "Unknown";
- }
-}
-
-void secmon_exo_check_panic()
-{
- volatile atm_fatal_error_ctx *rpt = (atm_fatal_error_ctx *)ATM_FATAL_ERR_CTX_ADDR;
-
- // Mask magic to maintain compatibility with any AFE version, thanks to additive struct members.
- if ((rpt->magic & 0xF0FFFFFF) != ATM_FATAL_MAGIC)
- return;
-
- gfx_clear_grey(0x1B);
- gfx_con_setpos(0, 0);
-
- WPRINTF("Panic occurred while running Atmosphere.\n\n");
- WPRINTFARGS("Title ID: %08X%08X", (u32)((u64)rpt->title_id >> 32), (u32)rpt->title_id);
- WPRINTFARGS("Error Desc: %s (0x%x)\n", get_error_desc(rpt->error_desc), rpt->error_desc);
-
- // Save context to the SD card.
- char filepath[0x40];
- f_mkdir("atmosphere/fatal_errors");
- strcpy(filepath, "/atmosphere/fatal_errors/report_");
- itoa((u32)((u64)rpt->report_identifier >> 32), filepath + strlen(filepath), 16);
- itoa((u32)(rpt->report_identifier), filepath + strlen(filepath), 16);
- strcat(filepath, ".bin");
-
- sd_save_to_file((void *)rpt, sizeof(atm_fatal_error_ctx), filepath);
-
- gfx_con.fntsz = 8;
- WPRINTFARGS("Report saved to %s\n", filepath);
-
- // Change magic to invalid, to prevent double-display of error/bootlooping.
- rpt->magic = 0x0;
-
- gfx_con.fntsz = 16;
- gfx_printf("\n\nPress POWER to continue.\n");
-
- display_backlight_brightness(100, 1000);
- msleep(1000);
-
- u32 btn = btn_wait();
- while (!(btn & BTN_POWER))
- btn = btn_wait();
-
- display_backlight_brightness(0, 1000);
- gfx_con_setpos(0, 0);
-}
diff --git a/source/hos/secmon_exo.h b/source/hos/secmon_exo.h
deleted file mode 100644
index 2ff0ee3..0000000
--- a/source/hos/secmon_exo.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2018-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 _SECMON_EXO_H_
-#define _SECMON_EXO_H_
-
-#include "../utils/types.h"
-
-void config_exosphere(launch_ctxt_t *ctxt);
-void secmon_exo_check_panic();
-
-#endif
diff --git a/source/hos/sept.c b/source/hos/sept.c
index d2b726c..1858533 100644
--- a/source/hos/sept.c
+++ b/source/hos/sept.c
@@ -16,27 +16,20 @@
#include
-#include "hos.h"
-#include "fss.h"
#include "sept.h"
-#include "../config/config.h"
#include "../gfx/di.h"
-#include "../ianos/ianos.h"
#include "../libs/fatfs/ff.h"
#include "../mem/heap.h"
#include "../soc/hw_init.h"
#include "../soc/pmc.h"
#include "../soc/t210.h"
-#include "../storage/emummc.h"
#include "../storage/nx_emmc.h"
-#include "../storage/nx_sd.h"
#include "../storage/sdmmc.h"
#include "../utils/btn.h"
#include "../utils/types.h"
#include "../gfx/gfx.h"
-#define RELOC_META_OFF 0x7C
#define PATCHED_RELOC_SZ 0x94
#define WB_RST_ADDR 0x40010ED0
@@ -57,178 +50,75 @@ u8 warmboot_reboot[] = {
#define SEPT_PRI_ADDR 0x4003F000
#define SEPT_PK1T_ADDR 0xC0400000
+#define SEPT_PK1T_STACK 0x40008000
#define SEPT_TCSZ_ADDR (SEPT_PK1T_ADDR - 0x4)
#define SEPT_STG1_ADDR (SEPT_PK1T_ADDR + 0x2E100)
#define SEPT_STG2_ADDR (SEPT_PK1T_ADDR + 0x60E0)
#define SEPT_PKG_SZ (0x2F100 + WB_RST_SIZE)
+extern u32 color_idx;
extern boot_cfg_t b_cfg;
-extern hekate_config h_cfg;
-extern const volatile ipl_ver_meta_t ipl_ver;
-
-extern bool is_ipl_updated(void *buf);
+extern void sd_unmount();
extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size);
-void check_sept(ini_sec_t *cfg_sec)
-{
- hos_eks_get();
-
- // Check if non-hekate payload is used for sept and restore it.
- if (h_cfg.sept_run)
- {
- if (!f_stat("sept/payload.bak", NULL))
- {
- f_unlink("sept/payload.bin");
- f_rename("sept/payload.bak", "sept/payload.bin");
- }
-
- return;
- }
-
- u8 *pkg1 = (u8 *)calloc(1, 0x40000);
-
- sdmmc_storage_t storage;
- sdmmc_t sdmmc;
- int res = emummc_storage_init_mmc(&storage, &sdmmc);
- if (res)
- {
- if (res == 2)
- EPRINTF("Failed to init eMMC");
- else
- EPRINTF("Failed to init emuMMC");
-
- goto out_free;
- }
-
- emummc_storage_set_mmc_partition(&storage, EMMC_BOOT0);
-
- // Read package1.
- emummc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
- const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
- if (!pkg1_id)
- {
- gfx_con.fntsz = 16;
- EPRINTF("Unknown pkg1 version.");
- goto out_free;
- }
-
- if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
- {
- u8 key_idx = pkg1_id->kb - KB_FIRMWARE_VERSION_700;
- if (h_cfg.eks && (h_cfg.eks->enabled & (1 << key_idx)))
- {
- h_cfg.sept_run = true;
- EMC(EMC_SCRATCH0) |= EMC_SEPT_RUN;
- goto out_free;
- }
-
- sdmmc_storage_end(&storage);
- reboot_to_sept((u8 *)pkg1 + pkg1_id->tsec_off, pkg1_id->kb, cfg_sec);
- }
-
-out_free:
- free(pkg1);
- sdmmc_storage_end(&storage);
-}
-
-int reboot_to_sept(const u8 *tsec_fw, u32 kb, ini_sec_t *cfg_sec)
+int reboot_to_sept(const u8 *tsec_fw, const u32 tsec_size, const u32 kb)
{
FIL fp;
- bool fss0_sept_used = false;
// Copy warmboot reboot code and TSEC fw.
- u32 tsec_fw_size = 0x3000;
- if (kb > KB_FIRMWARE_VERSION_700)
- tsec_fw_size = 0x3300;
memcpy((u8 *)(SEPT_PK1T_ADDR - WB_RST_SIZE), (u8 *)warmboot_reboot, sizeof(warmboot_reboot));
- memcpy((void *)SEPT_PK1T_ADDR, tsec_fw, tsec_fw_size);
- *(vu32 *)SEPT_TCSZ_ADDR = tsec_fw_size;
+ memcpy((void *)SEPT_PK1T_ADDR, tsec_fw, tsec_size);
+ *(vu32 *)SEPT_TCSZ_ADDR = tsec_size;
- if (cfg_sec)
+ // Copy sept-primary.
+ if (f_open(&fp, "sd:/sept/sept-primary.bin", FA_READ))
+ goto error;
+
+ if (f_read(&fp, (u8 *)SEPT_STG1_ADDR, f_size(&fp), NULL))
{
- fss0_sept_t sept_ctxt;
- sept_ctxt.kb = kb;
- sept_ctxt.cfg_sec = cfg_sec;
- sept_ctxt.sept_primary = (void *)SEPT_STG1_ADDR;
- sept_ctxt.sept_secondary = (void *)SEPT_STG2_ADDR;
-
- fss0_sept_used = load_sept_from_ffs0(&sept_ctxt);
- }
-
- if (!fss0_sept_used)
- {
- // Copy sept-primary.
- if (f_open(&fp, "sept/sept-primary.bin", FA_READ))
- goto error;
-
- if (f_read(&fp, (u8 *)SEPT_STG1_ADDR, f_size(&fp), NULL))
- {
- f_close(&fp);
- goto error;
- }
f_close(&fp);
+ goto error;
+ }
+ f_close(&fp);
- // Copy sept-secondary.
- if (kb < KB_FIRMWARE_VERSION_810)
- {
- if (f_open(&fp, "sept/sept-secondary_00.enc", FA_READ))
- if (f_open(&fp, "sept/sept-secondary.enc", FA_READ)) // Try the deprecated version.
- goto error;
- }
- else
- {
- if (f_open(&fp, "sept/sept-secondary_01.enc", FA_READ))
+ // Copy sept-secondary.
+ if (kb < KB_FIRMWARE_VERSION_810)
+ {
+ if (f_open(&fp, "sd:/sept/sept-secondary_00.enc", FA_READ))
+ if (f_open(&fp, "sd:/sept/sept-secondary.enc", FA_READ)) // Try the deprecated version.
goto error;
- }
-
- if (f_read(&fp, (u8 *)SEPT_STG2_ADDR, f_size(&fp), NULL))
- {
- f_close(&fp);
+ }
+ else
+ {
+ if (f_open(&fp, "sd:/sept/sept-secondary_01.enc", FA_READ))
goto error;
- }
- f_close(&fp);
}
- b_cfg.boot_cfg |= (BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_SEPT_RUN);
-
- bool update_sept_payload = true;
- if (!f_open(&fp, "sept/payload.bin", FA_READ | FA_WRITE))
+ if (f_read(&fp, (u8 *)SEPT_STG2_ADDR, f_size(&fp), NULL))
{
- ipl_ver_meta_t tmp_ver;
- f_lseek(&fp, PATCHED_RELOC_SZ + sizeof(boot_cfg_t));
- f_read(&fp, &tmp_ver, sizeof(ipl_ver_meta_t), NULL);
-
- if (tmp_ver.magic == ipl_ver.magic)
- {
- if (tmp_ver.version == ipl_ver.version)
- {
- // Save auto boot config to sept payload, if any.
- boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
- memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t));
- f_lseek(&fp, PATCHED_RELOC_SZ);
- f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
- update_sept_payload = false;
- }
-
- f_close(&fp);
- }
- else
- {
- f_close(&fp);
- f_rename("sept/payload.bin", "sept/payload.bak"); // Backup foreign payload.
- }
- }
-
- if (update_sept_payload)
- {
- volatile reloc_meta_t *reloc = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
- f_mkdir("sept");
- f_open(&fp, "sept/payload.bin", FA_WRITE | FA_CREATE_ALWAYS);
- f_write(&fp, (u8 *)reloc->start, reloc->end - reloc->start, NULL);
f_close(&fp);
+ goto error;
}
+ f_close(&fp);
+
+ // Save auto boot config to sept payload, if any.
+ boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
+ memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t));
+
+ tmp_cfg->boot_cfg |= BOOT_CFG_SEPT_RUN;
+
+ if (f_open(&fp, "sd:/sept/payload.bin", FA_READ | FA_WRITE)) {
+ free(tmp_cfg);
+ goto error;
+ }
+
+ f_lseek(&fp, PATCHED_RELOC_SZ);
+ f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
+
+ f_close(&fp);
sd_unmount();
+ gfx_printf("\n%kPress Power or Vol +/-\n to Reboot to Sept...", colors[(color_idx++) % 6]);
u32 pk1t_sept = SEPT_PK1T_ADDR - (ALIGN(PATCHED_RELOC_SZ, 0x10) + WB_RST_SIZE);
@@ -248,8 +138,8 @@ int reboot_to_sept(const u8 *tsec_fw, u32 kb, ini_sec_t *cfg_sec)
(*sept)();
error:
- gfx_con.mute = false;
- EPRINTF("Failed to run sept\n");
+ EPRINTF("\nSept files not found in sd:/sept!\nPlace appropriate files and try again.");
+ display_backlight_brightness(100, 1000);
btn_wait();
diff --git a/source/hos/sept.h b/source/hos/sept.h
index 8cfc8af..01bd845 100644
--- a/source/hos/sept.h
+++ b/source/hos/sept.h
@@ -19,7 +19,6 @@
#include "../utils/types.h"
-void check_sept(ini_sec_t *cfg_sec);
-int reboot_to_sept(const u8 *tsec_fw, u32 kb, ini_sec_t *cfg_sec);
+int reboot_to_sept(const u8 *tsec_fw, const u32 tsec_size, const u32 kb);
#endif
diff --git a/source/sec/se.c b/source/sec/se.c
index 57c0958..6eb4700 100644
--- a/source/sec/se.c
+++ b/source/sec/se.c
@@ -1,6 +1,8 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ * Copyright (c) 2019-2020 shchmue
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -31,6 +33,9 @@ typedef struct _se_ll_t
vu32 size;
} se_ll_t;
+static u32 _se_rsa_mod_sizes[TEGRA_SE_RSA_KEYSLOT_COUNT];
+static u32 _se_rsa_exp_sizes[TEGRA_SE_RSA_KEYSLOT_COUNT];
+
static void _gf256_mul_x(void *block)
{
u8 *pdata = (u8 *)block;
@@ -47,6 +52,22 @@ static void _gf256_mul_x(void *block)
pdata[0xF] ^= 0x87;
}
+static void _gf256_mul_x_le(void *block)
+{
+ u8 *pdata = (u8 *)block;
+ u32 carry = 0;
+
+ for (u32 i = 0; i < 0x10; i++)
+ {
+ u8 b = pdata[i];
+ pdata[i] = (b << 1) | carry;
+ carry = b >> 7;
+ }
+
+ if (carry)
+ pdata[0x0] ^= 0x87;
+}
+
static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size)
{
ll->num = 0;
@@ -73,17 +94,15 @@ static int _se_wait()
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
{
- se_ll_t *ll_dst = NULL, *ll_src = NULL;
+ se_ll_t *ll_dst = (se_ll_t *)0xECFFFFE0, *ll_src = (se_ll_t *)0xECFFFFF0;
if (dst)
{
- ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));
_se_ll_init(ll_dst, (u32)dst, dst_size);
}
if (src)
{
- ll_src = (se_ll_t *)malloc(sizeof(se_ll_t));
_se_ll_init(ll_src, (u32)src, src_size);
}
@@ -99,11 +118,6 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
- if (src)
- free(ll_src);
- if (dst)
- free(ll_dst);
-
return res;
}
@@ -142,6 +156,66 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags)
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs);
}
+// se_rsa_key_set() was derived from Atmosphère's set_rsa_keyslot
+void se_rsa_key_set(u32 ks, const void *mod, u32 mod_size, const void *exp, u32 exp_size)
+{
+ u32 *data = (u32 *)mod;
+ for (u32 i = 0; i < mod_size / 4; i++)
+ {
+ SE(SE_RSA_KEYTABLE_ADDR) = RSA_KEY_NUM(ks) | RSA_KEY_TYPE(RSA_KEY_TYPE_MOD) | i;
+ SE(SE_RSA_KEYTABLE_DATA) = byte_swap_32(data[mod_size / 4 - i - 1]);
+ }
+
+ data = (u32 *)exp;
+ for (u32 i = 0; i < exp_size / 4; i++)
+ {
+ SE(SE_RSA_KEYTABLE_ADDR) = RSA_KEY_NUM(ks) | RSA_KEY_TYPE(RSA_KEY_TYPE_EXP) | i;
+ SE(SE_RSA_KEYTABLE_DATA) = byte_swap_32(data[exp_size / 4 - i - 1]);
+ }
+
+ _se_rsa_mod_sizes[ks] = mod_size;
+ _se_rsa_exp_sizes[ks] = exp_size;
+}
+
+// se_rsa_key_clear() was derived from Atmosphère's clear_rsa_keyslot
+void se_rsa_key_clear(u32 ks)
+{
+ for (u32 i = 0; i < TEGRA_SE_RSA2048_DIGEST_SIZE / 4; i++)
+ {
+ SE(SE_RSA_KEYTABLE_ADDR) = RSA_KEY_NUM(ks) | RSA_KEY_TYPE(RSA_KEY_TYPE_MOD) | i;
+ SE(SE_RSA_KEYTABLE_DATA) = 0;
+ }
+ for (u32 i = 0; i < TEGRA_SE_RSA2048_DIGEST_SIZE / 4; i++)
+ {
+ SE(SE_RSA_KEYTABLE_ADDR) = RSA_KEY_NUM(ks) | RSA_KEY_TYPE(RSA_KEY_TYPE_EXP) | i;
+ SE(SE_RSA_KEYTABLE_DATA) = 0;
+ }
+}
+
+// se_rsa_exp_mod() was derived from Atmosphère's se_synchronous_exp_mod and se_get_exp_mod_output
+int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
+{
+ int res;
+ u8 stack_buf[TEGRA_SE_RSA2048_DIGEST_SIZE];
+
+ for (u32 i = 0; i < src_size; i++)
+ stack_buf[i] = *((u8 *)src + src_size - i - 1);
+
+ SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_RSA) | SE_CONFIG_DST(DST_RSAREG);
+ SE(SE_RSA_CONFIG) = RSA_KEY_SLOT(ks);
+ SE(SE_RSA_KEY_SIZE_REG_OFFSET) = (_se_rsa_mod_sizes[ks] >> 6) - 1;
+ SE(SE_RSA_EXP_SIZE_REG_OFFSET) = _se_rsa_exp_sizes[ks] >> 2;
+
+ res = _se_execute(OP_START, NULL, 0, stack_buf, src_size);
+
+ // Copy output hash.
+ u32 *dst32 = (u32 *)dst;
+ for (u32 i = 0; i < dst_size / 4; i++)
+ dst32[dst_size / 4 - i - 1] = byte_swap_32(SE(SE_RSA_OUTPUT + (i << 2)));
+
+ return res;
+}
+
void se_key_acc_ctrl(u32 ks, u32 flags)
{
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
@@ -150,7 +224,7 @@ void se_key_acc_ctrl(u32 ks, u32 flags)
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks);
}
-void se_aes_key_set(u32 ks, void *key, u32 size)
+void se_aes_key_set(u32 ks, const void *key, u32 size)
{
u32 *data = (u32 *)key;
for (u32 i = 0; i < size / 4; i++)
@@ -160,6 +234,16 @@ void se_aes_key_set(u32 ks, void *key, u32 size)
}
}
+void se_aes_key_read(u32 ks, void *key, u32 size)
+{
+ u32 *data = (u32 *)key;
+ for (u32 i = 0; i < size / 4; i++)
+ {
+ SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
+ data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET);
+ }
+}
+
void se_aes_key_clear(u32 ks)
{
for (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++)
@@ -169,6 +253,15 @@ void se_aes_key_clear(u32 ks)
}
}
+void se_aes_key_iv_clear(u32 ks)
+{
+ for (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++)
+ {
+ SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | 8 | i;
+ SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
+ }
+}
+
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
{
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTAB);
@@ -195,24 +288,6 @@ int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src,
return _se_execute(OP_START, dst, dst_size, src, src_size);
}
-int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
-{
- if (enc)
- {
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVAHB) |
- SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
- }
- else
- {
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVAHB) |
- SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
- }
- SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
- return _se_execute(OP_START, dst, dst_size, src, src_size);
-}
-
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src)
{
return se_aes_crypt_ecb(ks, enc, dst, 0x10, src, 0x10);
@@ -223,7 +298,8 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
SE(SE_SPARE_0_REG_OFFSET) = 1;
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
- SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_VAL(1);
+ SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_VAL(1) |
+ SE_CRYPTO_VCTRAM_SEL(VCTRAM_AHB);
_se_aes_ctr_set(ctr);
u32 src_size_aligned = src_size & 0xFFFFFFF0;
@@ -244,7 +320,7 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
return 1;
}
-int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
+int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, const void *src, u32 secsize)
{
int res = 0;
u8 *tweak = (u8 *)malloc(0x10);
@@ -269,7 +345,7 @@ int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *sr
goto out;
for (u32 j = 0; j < 0x10; j++)
pdst[j] = pdst[j] ^ tweak[j];
- _gf256_mul_x(tweak);
+ _gf256_mul_x_le(tweak);
psrc += 0x10;
pdst += 0x10;
}
@@ -281,7 +357,7 @@ out:;
return res;
}
-int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)
+int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, const void *src, u32 secsize, u32 num_secs)
{
u8 *pdst = (u8 *)dst;
u8 *psrc = (u8 *)src;
@@ -293,6 +369,58 @@ int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u
return 1;
}
+// se_aes_cmac() was derived from Atmosphère's se_compute_aes_cmac
+int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
+{
+ int res = 0;
+ u8 *key = (u8 *)calloc(0x10, 1);
+ u8 *last_block = (u8 *)calloc(0x10, 1);
+
+ // generate derived key
+ if (!se_aes_crypt_block_ecb(ks, 1, key, key))
+ goto out;
+ _gf256_mul_x(key);
+ if (src_size & 0xF)
+ _gf256_mul_x(key);
+
+ SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
+ SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_AHB) |
+ SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
+ SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
+ se_aes_key_iv_clear(ks);
+
+ u32 num_blocks = (src_size + 0xf) >> 4;
+ if (num_blocks > 1) {
+ SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 2;
+ if (!_se_execute(OP_START, NULL, 0, src, src_size))
+ goto out;
+ SE(SE_CRYPTO_REG_OFFSET) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
+ }
+
+ if (src_size & 0xf) {
+ memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf);
+ last_block[src_size & 0xf] = 0x80;
+ } else if (src_size >= 0x10) {
+ memcpy(last_block, src + src_size - 0x10, 0x10);
+ }
+
+ for (u32 i = 0; i < 0x10; i++)
+ last_block[i] ^= key[i];
+
+ SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
+ res = _se_execute(OP_START, NULL, 0, last_block, 0x10);
+
+ u32 *dst32 = (u32 *)dst;
+ for (u32 i = 0; i < (dst_size >> 2); i++)
+ dst32[i] = SE(SE_HASH_RESULT_REG_OFFSET + (i << 2));
+
+out:;
+ free(key);
+ free(last_block);
+ return res;
+}
+
+// se_calc_sha256() was derived from Atmosphère's se_calculate_sha256.
int se_calc_sha256(void *dst, const void *src, u32 src_size)
{
int res;
@@ -319,76 +447,45 @@ int se_calc_sha256(void *dst, const void *src, u32 src_size)
return res;
}
-int se_gen_prng128(void *dst)
-{
- // Setup config for X931 PRNG.
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_HASH(HASH_DISABLE) | SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
+int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size) {
+ int res = 0;
+ u8 *secret = (u8 *)malloc(0x40);
+ u8 *ipad = (u8 *)malloc(0x40 + src_size);
+ u8 *opad = (u8 *)malloc(0x60);
- SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_NORMAL);
- //SE(SE_RNG_SRC_CONFIG_REG_OFFSET) =
- // SE_RNG_SRC_CONFIG_ENT_SRC(RNG_SRC_RO_ENT_ENABLE) | SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(RNG_SRC_RO_ENT_LOCK_ENABLE);
- SE(SE_RNG_RESEED_INTERVAL_REG_OFFSET) = 1;
-
- SE(SE_BLOCK_COUNT_REG_OFFSET) = (16 >> 4) - 1;
-
- // Trigger the operation.
- return _se_execute(OP_START, dst, 16, NULL, 0);
-}
-
-void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
-{
- u8 *aligned_buf = (u8 *)ALIGN((u32)buf, 0x40);
-
- // Set Secure Random Key.
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
- SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_FORCE_RESEED);
- SE(SE_CRYPTO_LAST_BLOCK) = 0;
- _se_execute(OP_START, NULL, 0, NULL, 0);
-
- // Save AES keys.
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
-
- for (u32 i = 0; i < TEGRA_SE_KEYSLOT_COUNT; i++)
+ if (key_size > 0x40)
{
- SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) |
- (i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_0_3);
-
- SE(SE_CRYPTO_LAST_BLOCK) = 0;
- _se_execute(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
- memcpy(keys + i * keysize, aligned_buf, 0x10);
-
- if (keysize > 0x10)
- {
- SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) |
- (i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_4_7);
-
- SE(SE_CRYPTO_LAST_BLOCK) = 0;
- _se_execute(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
- memcpy(keys + i * keysize + 0x10, aligned_buf, 0x10);
- }
+ if (!se_calc_sha256(secret, key, key_size))
+ goto out;
+ memset(secret + 0x20, 0, 0x20);
+ }
+ else
+ {
+ memcpy(secret, key, key_size);
+ memset(secret + key_size, 0, 0x40 - key_size);
}
- // Save SRK to PMC secure scratches.
- SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(SRK);
- SE(0x80) = 0; // SE_CRYPTO_LAST_BLOCK
- _se_execute(OP_CTX_SAVE, NULL, 0, NULL, 0);
+ u32 *secret32 = (u32 *)secret;
+ u32 *ipad32 = (u32 *)ipad;
+ u32 *opad32 = (u32 *)opad;
+ for (u32 i = 0; i < 0x10; i++)
+ {
+ ipad32[i] = secret32[i] ^ 0x36363636;
+ opad32[i] = secret32[i] ^ 0x5C5C5C5C;
+ }
- // End context save.
- SE(SE_CONFIG_REG_OFFSET) = 0;
- _se_execute(OP_CTX_SAVE, NULL, 0, NULL, 0);
+ memcpy(ipad + 0x40, src, src_size);
+ if (!se_calc_sha256(dst, ipad, 0x40 + src_size))
+ goto out;
+ memcpy(opad + 0x40, dst, 0x20);
+ if (!se_calc_sha256(dst, opad, 0x60))
+ goto out;
- // Get SRK.
- u32 srk[4];
- srk[0] = PMC(0xC0);
- srk[1] = PMC(0xC4);
- srk[2] = PMC(0x224);
- srk[3] = PMC(0x228);
+ res = 1;
- // Decrypt context.
- se_aes_key_clear(3);
- se_aes_key_set(3, srk, 0x10);
- se_aes_crypt_cbc(3, 0, keys, TEGRA_SE_KEYSLOT_COUNT * keysize, keys, TEGRA_SE_KEYSLOT_COUNT * keysize);
- se_aes_key_clear(3);
+out:;
+ free(secret);
+ free(ipad);
+ free(opad);
+ return res;
}
diff --git a/source/sec/se.h b/source/sec/se.h
index 7d12207..0d517c7 100644
--- a/source/sec/se.h
+++ b/source/sec/se.h
@@ -20,15 +20,21 @@
#include "../utils/types.h"
void se_rsa_acc_ctrl(u32 rs, u32 flags);
+void se_rsa_key_set(u32 ks, const void *mod, u32 mod_size, const void *exp, u32 exp_size);
+void se_rsa_key_clear(u32 ks);
+int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
void se_key_acc_ctrl(u32 ks, u32 flags);
-void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize);
-void se_aes_key_set(u32 ks, void *key, u32 size);
+void se_aes_key_set(u32 ks, const void *key, u32 size);
+void se_aes_key_read(u32 ks, void *key, u32 size);
void se_aes_key_clear(u32 ks);
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
+int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, const void *src, u32 secsize);
+int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, const void *src, u32 secsize, u32 num_secs);
+int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_calc_sha256(void *dst, const void *src, u32 src_size);
-int se_gen_prng128(void *dst);
+int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size);
#endif
diff --git a/source/sec/tsec.c b/source/sec/tsec.c
index 7c9f1e6..5a1f85e 100644
--- a/source/sec/tsec.c
+++ b/source/sec/tsec.c
@@ -29,7 +29,6 @@
#include "../mem/heap.h"
#include "../mem/mc.h"
#include "../utils/util.h"
-#include "../hos/hos.h"
// #include "../gfx/gfx.h"
diff --git a/source/tegraexplorer/emmc/emmc.c b/source/tegraexplorer/emmc/emmc.c
index 2fb3bd0..afea163 100644
--- a/source/tegraexplorer/emmc/emmc.c
+++ b/source/tegraexplorer/emmc/emmc.c
@@ -217,6 +217,7 @@ int dump_biskeys(){
//sdmmc_storage_set_mmc_partition(&storage, 0);
//nx_emmc_gpt_parse(&sys_gpt, &storage);
+
se_aes_key_set(8, bis_key[2] + 0x00, 0x10);
se_aes_key_set(9, bis_key[2] + 0x10, 0x10);