diff --git a/common/include/atmosphere/target_fw.h b/common/include/atmosphere/target_fw.h
index 4f944b293..4e368c44f 100644
--- a/common/include/atmosphere/target_fw.h
+++ b/common/include/atmosphere/target_fw.h
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#ifndef ATMOSPHERE_TARGET_FIRMWARE_H
#define ATMOSPHERE_TARGET_FIRMWARE_H
@@ -26,11 +26,12 @@
#define ATMOSPHERE_TARGET_FIRMWARE_620 7
#define ATMOSPHERE_TARGET_FIRMWARE_700 8
#define ATMOSPHERE_TARGET_FIRMWARE_800 9
+#define ATMOSPHERE_TARGET_FIRMWARE_810 10
-#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_800
+#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_810
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE_100
-#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_800
+#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_810
/* TODO: What should this be, for release? */
#define ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG ATMOSPHERE_TARGET_FIRMWARE_CURRENT
diff --git a/exosphere/src/exocfg.c b/exosphere/src/exocfg.c
index 7cf9488bd..974766178 100644
--- a/exosphere/src/exocfg.c
+++ b/exosphere/src/exocfg.c
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#include
#include
@@ -34,13 +34,13 @@ unsigned int exosphere_load_config(void) {
generic_panic();
}
g_has_loaded_config = true;
-
+
const unsigned int magic = MAILBOX_EXOSPHERE_CONFIG.magic;
-
+
if (magic == MAGIC_EXOSPHERE_CONFIG) {
g_exosphere_cfg = MAILBOX_EXOSPHERE_CONFIG;
}
-
+
return g_exosphere_cfg.target_firmware;
}
@@ -48,7 +48,7 @@ unsigned int exosphere_get_target_firmware(void) {
if (!g_has_loaded_config) {
generic_panic();
}
-
+
return g_exosphere_cfg.target_firmware;
}
@@ -56,15 +56,15 @@ unsigned int exosphere_should_perform_620_keygen(void) {
if (!g_has_loaded_config) {
generic_panic();
}
-
- return g_exosphere_cfg.target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_620 && EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_PERFORM_620_KEYGEN);
+
+ return false;
}
unsigned int exosphere_should_override_debugmode_priv(void) {
if (!g_has_loaded_config) {
generic_panic();
}
-
+
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV);
}
@@ -72,7 +72,7 @@ unsigned int exosphere_should_override_debugmode_user(void) {
if (!g_has_loaded_config) {
generic_panic();
}
-
+
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_IS_DEBUGMODE_USER);
}
@@ -80,7 +80,7 @@ unsigned int exosphere_should_disable_usermode_exception_handlers(void) {
if (!g_has_loaded_config) {
generic_panic();
}
-
+
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS);
}
diff --git a/exosphere/src/exocfg.h b/exosphere/src/exocfg.h
index 316aa5646..16f37ec19 100644
--- a/exosphere/src/exocfg.h
+++ b/exosphere/src/exocfg.h
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#ifndef EXOSPHERE_EXOSPHERE_CONFIG_H
#define EXOSPHERE_EXOSPHERE_CONFIG_H
@@ -36,7 +36,7 @@
/* Exosphere config in DRAM shares physical/virtual mapping. */
#define MAILBOX_EXOSPHERE_CONFIG_PHYS MAILBOX_EXOSPHERE_CONFIG
-#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u)
+#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN_DEPRECATED (1 << 0u)
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
diff --git a/fusee/fusee-secondary/Makefile b/fusee/fusee-secondary/Makefile
index 844dc8cf0..64fa59ba3 100644
--- a/fusee/fusee-secondary/Makefile
+++ b/fusee/fusee-secondary/Makefile
@@ -99,7 +99,7 @@ SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
KIPFILES := loader.kip pm.kip sm.kip ams_mitm.kip spl.kip boot.kip
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \
exosphere.bin lp0fw.bin rebootstub.bin thermosphere.bin splash_screen.bmp \
- sept-primary.bin sept-secondary.enc emummc.kip \
+ sept-primary.bin sept-secondary_00.enc sept-secondary_01.enc emummc.kip \
$(KIPFILES)
#---------------------------------------------------------------------------------
@@ -198,22 +198,27 @@ fusee_primary.bin.o fusee_primary_bin.h: fusee-primary.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
-
+
sept_primary.bin.o sept_primary_bin.h: sept-primary.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
-
-sept_secondary.enc.o sept_secondary_enc.h: sept-secondary.enc
+
+sept_secondary_00.enc.o sept_secondary_00.h: sept-secondary_00.enc
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
-
+
+sept_secondary_01.enc.o sept_secondary_01_enc.h: sept-secondary_01.enc
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(_bin2o)
+
%.bin.o %_bin.h: %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-
+
%.bmp.o %_bmp.h: %.bmp
#---------------------------------------------------------------------------------
@echo $(notdir $<)
diff --git a/fusee/fusee-secondary/linker.ld b/fusee/fusee-secondary/linker.ld
index 26e8cc445..54a44b73d 100644
--- a/fusee/fusee-secondary/linker.ld
+++ b/fusee/fusee-secondary/linker.ld
@@ -55,7 +55,7 @@ SECTIONS
. = ALIGN(32);
PROVIDE (__chainloader_end__ = ABSOLUTE(.));
} >low_iram :NONE
-
+
.nxboot_loadable :
{
. = ALIGN(32);
@@ -157,7 +157,7 @@ SECTIONS
CONSTRUCTORS
. = ALIGN(32);
} >main
-
+
__data_end__ = ABSOLUTE(.);
PROVIDE (__total_size__ = (__data_end__ - __start__));
@@ -236,8 +236,10 @@ SECTIONS
PROVIDE(__rebootstub_bin_size__ = rebootstub_bin_end - rebootstub_bin);
PROVIDE(__sept_primary_bin_start__ = sept_primary_bin - __start__);
PROVIDE(__sept_primary_bin_size__ = sept_primary_bin_end - sept_primary_bin);
- PROVIDE(__sept_secondary_enc_start__ = sept_secondary_enc - __start__);
- PROVIDE(__sept_secondary_enc_size__ = sept_secondary_enc_end - sept_secondary_enc);
+ PROVIDE(__sept_secondary_00_enc_start__ = sept_secondary_00_enc - __start__);
+ PROVIDE(__sept_secondary_00_enc_size__ = sept_secondary_00_enc_end - sept_secondary_00_enc);
+ PROVIDE(__sept_secondary_01_enc_start__ = sept_secondary_01_enc - __start__);
+ PROVIDE(__sept_secondary_01_enc_size__ = sept_secondary_01_enc_end - sept_secondary_01_enc);
PROVIDE(__sm_kip_start__ = sm_kip - __start__);
PROVIDE(__sm_kip_size__ = sm_kip_end - sm_kip);
PROVIDE(__spl_kip_start__ = spl_kip - __start__);
diff --git a/fusee/fusee-secondary/src/key_derivation.c b/fusee/fusee-secondary/src/key_derivation.c
index 2a13a7c2c..d4de912be 100644
--- a/fusee/fusee-secondary/src/key_derivation.c
+++ b/fusee/fusee-secondary/src/key_derivation.c
@@ -54,7 +54,8 @@ static const uint8_t AL16 masterkey_4x_seed[0x10] = {
0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
};
-static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_CURRENT - MASTERKEY_REVISION_600_610][0x10] = {
+/* TODO: Bother adding 8.1.0 here? We'll never call into here... */
+static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_800 - MASTERKEY_REVISION_600_610][0x10] = {
{0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, /* MasterKek seed 06. */
{0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, /* MasterKek seed 07. */
};
@@ -93,17 +94,17 @@ static int decrypt_keyblob(const nx_keyblob_t *keyblobs, uint32_t revision, uint
if (get_keyblob(&keyblob, revision, keyblobs, available_revision) != 0) {
return -1;
}
-
+
se_aes_ecb_decrypt_block(0xD, work_buffer, 0x10, keyblob_seeds[revision], 0x10);
decrypt_data_into_keyslot(keyslot, 0xE, work_buffer, 0x10);
decrypt_data_into_keyslot(0xB, keyslot, keyblob_mac_seed, 0x10);
-
+
/* Validate keyblob. */
se_compute_aes_128_cmac(0xB, work_buffer, 0x10, keyblob.mac + sizeof(keyblob.mac), sizeof(keyblob) - sizeof(keyblob.mac));
if (safe_memcmp(keyblob.mac, work_buffer, 0x10)) {
return -1;
}
-
+
/* Decrypt keyblob. */
se_aes_ctr_crypt(keyslot, &g_dec_keyblobs[revision], sizeof(g_dec_keyblobs[revision]), keyblob.data, sizeof(keyblob.data), keyblob.ctr, sizeof(keyblob.ctr));
return 0;
@@ -113,7 +114,7 @@ int load_package1_key(uint32_t revision) {
if (revision > MASTERKEY_REVISION_600_610) {
return -1;
}
-
+
set_aes_keyslot(0xB, g_dec_keyblobs[revision].package1_key, 0x10);
return 0;
}
@@ -122,17 +123,17 @@ int load_package1_key(uint32_t revision) {
int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, uint32_t available_revision, const void *tsec_key, void *tsec_root_keys, unsigned int *out_keygen_type) {
uint8_t AL16 work_buffer[0x10];
uint8_t AL16 zeroes[0x10] = {0};
-
+
/* Initialize keygen type. */
*out_keygen_type = 0;
/* TODO: Set keyslot flags properly in preparation of derivation. */
set_aes_keyslot_flags(0xE, 0x15);
set_aes_keyslot_flags(0xD, 0x15);
-
+
/* Set the TSEC key. */
set_aes_keyslot(0xD, tsec_key, 0x10);
-
+
/* Decrypt all keyblobs, setting keyslot 0xF correctly. */
for (unsigned int rev = 0; rev <= MASTERKEY_REVISION_600_610; rev++) {
int ret = decrypt_keyblob(keyblobs, rev, available_revision);
@@ -150,13 +151,16 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
break;
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
- desired_keyblob = MASTERKEY_REVISION_700_CURRENT;
+ desired_keyblob = MASTERKEY_REVISION_700_800;
+ break;
+ case ATMOSPHERE_TARGET_FIRMWARE_810:
+ desired_keyblob = MASTERKEY_REVISION_810_CURRENT;
break;
default:
fatal_error("Unknown target firmware: %02x!", target_firmware);
break;
}
-
+
/* Try emulation result. */
for (unsigned int rev = MASTERKEY_REVISION_620; rev < MASTERKEY_REVISION_MAX; rev++) {
void *tsec_root_key = (void *)((uintptr_t)tsec_root_keys + 0x10 * (rev - MASTERKEY_REVISION_620));
@@ -167,7 +171,7 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
memcpy(g_dec_keyblobs[rev].master_kek, work_buffer, 0x10);
}
}
-
+
if (memcmp(g_dec_keyblobs[desired_keyblob].master_kek, zeroes, 0x10) == 0) {
/* Try reading the keys from a file. */
const char *keyfile = fuse_get_retail_type() != 0 ? "atmosphere/prod.keys" : "atmosphere/dev.keys";
@@ -188,13 +192,13 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
}
}
}
-
-
+
+
if (memcmp(g_dec_keyblobs[available_revision].master_kek, zeroes, 0x10) == 0) {
fatal_error("Error: failed to derive master_kek_%02x!", available_revision);
}
}
-
+
/* Clear the SBK. */
clear_aes_keyslot(0xE);
@@ -225,6 +229,7 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
case ATMOSPHERE_TARGET_FIRMWARE_620:
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
+ case ATMOSPHERE_TARGET_FIRMWARE_810:
decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10);
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
decrypt_data_into_keyslot(0xE, 0xC, masterkey_4x_seed, 0x10);
diff --git a/fusee/fusee-secondary/src/masterkey.c b/fusee/fusee-secondary/src/masterkey.c
index 28b6e3ee4..d2c5a06e7 100644
--- a/fusee/fusee-secondary/src/masterkey.c
+++ b/fusee/fusee-secondary/src/masterkey.c
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#include
#include
#include
@@ -39,6 +39,7 @@ static const uint8_t mkey_vectors_dev[MASTERKEY_REVISION_MAX][0x10] =
{0x78, 0xD5, 0xF1, 0x20, 0x3D, 0x16, 0xE9, 0x30, 0x32, 0x27, 0x34, 0x6F, 0xCF, 0xE0, 0x27, 0xDC}, /* Master key 04 encrypted with Master key 05. */
{0x6F, 0xD2, 0x84, 0x1D, 0x05, 0xEC, 0x40, 0x94, 0x5F, 0x18, 0xB3, 0x81, 0x09, 0x98, 0x8D, 0x4E}, /* Master key 05 encrypted with Master key 06. */
{0x37, 0xAF, 0xAB, 0x35, 0x79, 0x09, 0xD9, 0x48, 0x29, 0xD2, 0xDB, 0xA5, 0xA5, 0xF5, 0x30, 0x19}, /* Master key 06 encrypted with Master key 07. */
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: Master key 07 encrypted with Master key 08. */
};
/* Retail unit keys. */
@@ -52,6 +53,7 @@ static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] =
{0xEB, 0xF5, 0x6F, 0x83, 0x61, 0x9E, 0xF8, 0xFA, 0xE0, 0x87, 0xD7, 0xA1, 0x4E, 0x25, 0x36, 0xEE}, /* Master key 04 encrypted with Master key 05. */
{0x1E, 0x1E, 0x22, 0xC0, 0x5A, 0x33, 0x3C, 0xB9, 0x0B, 0xA9, 0x03, 0x04, 0xBA, 0xDB, 0x07, 0x57}, /* Master key 05 encrypted with Master key 06. */
{0xA4, 0xD4, 0x52, 0x6F, 0xD1, 0xE4, 0x36, 0xAA, 0x9F, 0xCB, 0x61, 0x27, 0x1C, 0x67, 0x65, 0x1F}, /* Master key 06 encrypted with Master key 07. */
+ {0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */
};
static bool check_mkey_revision(unsigned int revision, bool is_retail) {
@@ -80,7 +82,7 @@ int mkey_detect_revision(bool is_retail) {
if (g_determined_mkey_revision) {
generic_panic();
}
-
+
for (unsigned int rev = 0; rev < MASTERKEY_REVISION_MAX; rev++) {
if (check_mkey_revision(rev, is_retail)) {
g_determined_mkey_revision = true;
@@ -88,7 +90,7 @@ int mkey_detect_revision(bool is_retail) {
break;
}
}
-
+
/* We must have determined the master key, or we're not running on a Switch. */
if (!g_determined_mkey_revision) {
return -1;
diff --git a/fusee/fusee-secondary/src/masterkey.h b/fusee/fusee-secondary/src/masterkey.h
index 332dbcec5..0ee44eca4 100644
--- a/fusee/fusee-secondary/src/masterkey.h
+++ b/fusee/fusee-secondary/src/masterkey.h
@@ -13,14 +13,14 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#ifndef FUSEE_MASTERKEY_H
#define FUSEE_MASTERKEY_H
/* This is glue code to enable master key support across versions. */
-/* TODO: Update to 0x8 on release of new master key. */
-#define MASTERKEY_REVISION_MAX 0x8
+/* TODO: Update to 0xA on release of new master key. */
+#define MASTERKEY_REVISION_MAX 0x9
#define MASTERKEY_REVISION_100_230 0x00
#define MASTERKEY_REVISION_300 0x01
@@ -29,7 +29,8 @@
#define MASTERKEY_REVISION_500_510 0x04
#define MASTERKEY_REVISION_600_610 0x05
#define MASTERKEY_REVISION_620 0x06
-#define MASTERKEY_REVISION_700_CURRENT 0x07
+#define MASTERKEY_REVISION_700_800 0x07
+#define MASTERKEY_REVISION_810_CURRENT 0x08
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)
diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c
index cc7f1cacd..2146a7062 100644
--- a/fusee/fusee-secondary/src/nxboot.c
+++ b/fusee/fusee-secondary/src/nxboot.c
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#include
#include
#include
@@ -53,7 +53,8 @@
#define u8 uint8_t
#define u32 uint32_t
#include "exosphere_bin.h"
-#include "sept_secondary_enc.h"
+#include "sept_secondary_00_enc.h"
+#include "sept_secondary_01_enc.h"
#include "lp0fw_bin.h"
#include "emummc_kip.h"
#include "lib/log.h"
@@ -207,8 +208,15 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
}
case 0x0F: /* 7.0.0 - 7.0.1 */
return ATMOSPHERE_TARGET_FIRMWARE_700;
- case 0x10: /* 8.0.0 */
- return ATMOSPHERE_TARGET_FIRMWARE_800;
+ case 0x10: { /* 8.0.0 - 8.1.0 */
+ if (memcmp(package1loader_header->build_timestamp, "20190314", 8) == 0) {
+ return ATMOSPHERE_TARGET_FIRMWARE_800;
+ } else if (memcmp(package1loader_header->build_timestamp, "20190531", 8) == 0) {
+ return ATMOSPHERE_TARGET_FIRMWARE_810;
+ } else {
+ fatal_error("[NXBOOT] Unable to identify package1!\n");
+ }
+ }
default:
fatal_error("[NXBOOT] Unable to identify package1!\n");
}
@@ -216,7 +224,7 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
static bool nxboot_configure_emummc(exo_emummc_config_t *exo_emummc_config) {
emummc_config_t emummc_cfg = {.enabled = false, .id = 0, .sector = -1, .path = "", .nintendo_path = ""};
-
+
char *emummc_ini = calloc(1, 0x10000);
if (!read_from_file(emummc_ini, 0xFFFF, "emummc/emummc.ini")) {
free(emummc_ini);
@@ -237,12 +245,12 @@ static bool nxboot_configure_emummc(exo_emummc_config_t *exo_emummc_config) {
exo_emummc_config->base_cfg.fs_version = FS_VER_1_0_0; /* Will be filled out later. */
strncpy(exo_emummc_config->emu_dir_path, emummc_cfg.nintendo_path, sizeof(exo_emummc_config->emu_dir_path));
exo_emummc_config->emu_dir_path[sizeof(exo_emummc_config->emu_dir_path) - 1] = '\0';
-
+
if (emummc_cfg.enabled) {
if (emummc_cfg.sector != -1) {
exo_emummc_config->base_cfg.type = EMUMMC_TYPE_PARTITION;
exo_emummc_config->partition_cfg.start_sector = emummc_cfg.sector;
-
+
/* Mount emulated NAND from SD card partition. */
if (nxfs_mount_emummc_partition(emummc_cfg.sector) < 0) {
fatal_error("[NXBOOT] Failed to mount EmuMMC from SD card partition!\n");
@@ -258,24 +266,24 @@ static bool nxboot_configure_emummc(exo_emummc_config_t *exo_emummc_config) {
char emummc_boot0_path[0x300 + 1] = {0};
char emummc_boot1_path[0x300 + 1] = {0};
char emummc_rawnand_path[0x300 + 1] = {0};
-
+
/* Prepare base folder path. */
snprintf(emummc_path, sizeof(emummc_path) - 1, "%s/%s", emummc_cfg.path, "eMMC");
-
+
/* Check if eMMC folder is present. */
if (!is_valid_folder(emummc_path)) {
fatal_error("[NXBOOT] Failed to find EmuMMC eMMC folder!\n");
}
-
+
/* Prepare expected file paths. */
snprintf(emummc_boot0_path, sizeof(emummc_boot0_path) - 1, "%s/%s", emummc_path, "boot0");
snprintf(emummc_boot1_path, sizeof(emummc_boot1_path) - 1, "%s/%s", emummc_path, "boot1");
-
+
/* Check if boot0 and boot1 image files are present. */
if (!is_valid_file(emummc_boot0_path) || !is_valid_file(emummc_boot1_path)) {
fatal_error("[NXBOOT] Failed to find EmuMMC boot0/boot1 image files!\n");
}
-
+
/* Find raw image files (single or multi part). */
for (int i = 0; i < 64; i++) {
snprintf(emummc_rawnand_path, sizeof(emummc_rawnand_path) - 1, "%s/%02d", emummc_path, i);
@@ -295,7 +303,7 @@ static bool nxboot_configure_emummc(exo_emummc_config_t *exo_emummc_config) {
if ((num_parts == 0) || (part_limit == 0)) {
fatal_error("[NXBOOT] Failed to find EmuMMC raw image files!\n");
}
-
+
/* Mount emulated NAND from files. */
if (nxfs_mount_emummc_file(emummc_path, num_parts, part_limit) < 0) {
fatal_error("[NXBOOT] Failed to mount EmuMMC from files!\n");
@@ -304,7 +312,7 @@ static bool nxboot_configure_emummc(exo_emummc_config_t *exo_emummc_config) {
fatal_error("[NXBOOT] Invalid EmuMMC setting!\n");
}
}
-
+
return emummc_cfg.enabled;
}
@@ -337,7 +345,7 @@ static void nxboot_configure_stratosphere(uint32_t target_firmware) {
if (ini_parse_string(get_loader_ctx()->bct0, stratosphere_ini_handler, &strat_cfg) < 0) {
fatal_error("[NXBOOT] Failed to parse BCT.ini!\n");
}
-
+
/* Enable NOGC patches if the user requested it, or if the user is booting into 4.0.0+ with 3.0.2- fuses. */
if (strat_cfg.has_nogc_config) {
if (strat_cfg.enable_nogc) {
@@ -353,7 +361,7 @@ static void nxboot_configure_stratosphere(uint32_t target_firmware) {
static void nxboot_set_bootreason(void *bootreason_base) {
boot_reason_t boot_reason = {0};
- FILE *boot0;
+ FILE *boot0;
nvboot_config_table *bct;
nv_bootloader_info *bootloader_info;
@@ -362,7 +370,7 @@ static void nxboot_set_bootreason(void *bootreason_base) {
if (bct == NULL) {
fatal_error("[NXBOOT] Out of memory!\n");
}
-
+
/* Open boot0. */
boot0 = fopen("boot0:/", "rb");
if (boot0 == NULL) {
@@ -373,25 +381,25 @@ static void nxboot_set_bootreason(void *bootreason_base) {
if (fread(bct, sizeof(nvboot_config_table), 1, boot0) == 0) {
fatal_error("[NXBOOT] Failed to read the BCT!\n");
}
-
+
/* Close boot0. */
fclose(boot0);
-
+
/* Populate bootloader parameters. */
bootloader_info = &bct->bootloader[0];
boot_reason.bootloader_version = bootloader_info->version;
boot_reason.bootloader_start_block = bootloader_info->start_blk;
boot_reason.bootloader_start_page = bootloader_info->start_page;
boot_reason.bootloader_attribute = bootloader_info->attribute;
-
+
uint8_t power_key_intr = 0;
uint8_t rtc_intr = 0;
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFIRQ, &power_key_intr, 1);
i2c_query(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_REG_RTCINT, &rtc_intr, 1);
-
+
/* Set PMIC value. */
boot_reason.boot_reason_value = ((rtc_intr << 0x08) | power_key_intr);
-
+
/* TODO: Find out what these mean. */
if (power_key_intr & 0x80)
boot_reason.boot_reason_state = 0x01;
@@ -401,10 +409,10 @@ static void nxboot_set_bootreason(void *bootreason_base) {
boot_reason.boot_reason_state = 0x03;
else if (rtc_intr & 0x04)
boot_reason.boot_reason_state = 0x04;
-
+
/* Set in memory. */
memcpy(bootreason_base, &boot_reason, sizeof(boot_reason));
-
+
/* Clean up. */
free(bct);
}
@@ -414,13 +422,13 @@ static void nxboot_move_bootconfig() {
void *bootconfig;
uint32_t bootconfig_addr;
uint32_t bootconfig_size;
-
+
/* Allocate memory for reading BootConfig. */
bootconfig = memalign(0x1000, 0x4000);
if (bootconfig == NULL) {
fatal_error("[NXBOOT] Out of memory!\n");
}
-
+
/* Get BootConfig from the Package2 partition. */
bcfile = fopen("bcpkg21:/", "rb");
if (bcfile == NULL) {
@@ -431,15 +439,15 @@ static void nxboot_move_bootconfig() {
fatal_error("[NXBOOT] Failed to read BootConfig!\n");
}
fclose(bcfile);
-
+
/* Select the actual BootConfig size and destination address. */
bootconfig_addr = (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_600) ? 0x4003D000 : 0x4003F800;
bootconfig_size = (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) ? 0x3000 : 0x1000;
-
+
/* Copy the BootConfig into IRAM. */
memset((void *)bootconfig_addr, 0, bootconfig_size);
memcpy((void *)bootconfig_addr, bootconfig, bootconfig_size);
-
+
/* Clean up. */
free(bootconfig);
}
@@ -459,6 +467,8 @@ uint32_t nxboot_main(void) {
size_t package2_size;
void *tsec_fw;
size_t tsec_fw_size;
+ const void *sept_secondary_enc = NULL;
+ size_t sept_secondary_enc_size = 0;
void *warmboot_fw;
size_t warmboot_fw_size;
void *warmboot_memaddr;
@@ -470,7 +480,7 @@ uint32_t nxboot_main(void) {
FILE *boot0, *pk2file;
void *exosphere_memaddr;
exo_emummc_config_t exo_emummc_cfg;
-
+
/* Configure emummc or mount the real NAND. */
if (!nxboot_configure_emummc(&exo_emummc_cfg)) {
emummc = NULL;
@@ -542,7 +552,7 @@ uint32_t nxboot_main(void) {
fatal_error("[NXBOOT] Failed to read Package2!\n");
}
fclose(pk2file);
-
+
/* Read and parse boot0. */
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Reading boot0...\n");
boot0 = fopen("boot0:/", "rb");
@@ -550,7 +560,7 @@ uint32_t nxboot_main(void) {
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
}
fclose(boot0);
-
+
/* Find the system's target firmware. */
uint32_t target_firmware = nxboot_get_target_firmware(package1loader);
if (!target_firmware)
@@ -561,26 +571,42 @@ uint32_t nxboot_main(void) {
/* Read the TSEC firmware from a file, otherwise from PK1L. */
if (loader_ctx->tsecfw_path[0] != '\0') {
tsec_fw_size = get_file_size(loader_ctx->tsecfw_path);
- if ((tsec_fw_size != 0) && (tsec_fw_size != 0xF00 && tsec_fw_size != 0x2900 && tsec_fw_size != 0x3000)) {
+ if ((tsec_fw_size != 0) && (tsec_fw_size != 0xF00 && tsec_fw_size != 0x2900 && tsec_fw_size != 0x3000 && tsec_fw_size != 0x3300)) {
fatal_error("[NXBOOT] TSEC firmware from %s has a wrong size!\n", loader_ctx->tsecfw_path);
} else if (tsec_fw_size == 0) {
fatal_error("[NXBOOT] Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
}
-
+
/* Allocate memory for the TSEC firmware. */
tsec_fw = memalign(0x100, tsec_fw_size);
-
+
if (tsec_fw == NULL) {
fatal_error("[NXBOOT] Out of memory!\n");
}
if (read_from_file(tsec_fw, tsec_fw_size, loader_ctx->tsecfw_path) != tsec_fw_size) {
fatal_error("[NXBOOT] Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
}
+
+ if (tsec_fw_size == 0x3000) {
+ sept_secondary_enc = sept_secondary_00_enc;
+ sept_secondary_enc_size = sept_secondary_00_enc_size;
+ } else if (tsec_fw_size == 0x3300) {
+ sept_secondary_enc = sept_secondary_01_enc;
+ sept_secondary_enc_size = sept_secondary_01_enc_size;
+ } else {
+ fatal_error("[NXBOOT] Unable to identify sept revision to run.");
+ }
} else {
if (!package1_get_tsec_fw(&tsec_fw, package1loader, package1loader_size)) {
fatal_error("[NXBOOT] Failed to read the TSEC firmware from Package1loader!\n");
}
- if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_700) {
+ if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_810) {
+ sept_secondary_enc = sept_secondary_01_enc;
+ sept_secondary_enc_size = sept_secondary_01_enc_size;
+ tsec_fw_size = 0x3300;
+ } else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_700) {
+ sept_secondary_enc = sept_secondary_00_enc;
+ sept_secondary_enc_size = sept_secondary_00_enc_size;
tsec_fw_size = 0x3000;
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_620) {
tsec_fw_size = 0x2900;
@@ -606,10 +632,10 @@ uint32_t nxboot_main(void) {
get_and_clear_has_run_sept();
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_620) {
uint8_t tsec_keys[0x20] = {0};
-
+
/* Emulate the TSEC payload on 6.2.0+. */
smmu_emulate_tsec((void *)tsec_keys, package1loader, package1loader_size, package1loader);
-
+
/* Copy back the keys. */
memcpy((void *)tsec_key, (void *)tsec_keys, 0x10);
memcpy((void *)tsec_root_keys, (void *)tsec_keys + 0x10, 0x10);
@@ -619,11 +645,11 @@ uint32_t nxboot_main(void) {
fatal_error("[NXBOOT] Failed to get TSEC key!\n");
}
}
-
+
//fatal_error("Ran sept!");
/* Display splash screen. */
display_splash_screen_bmp(loader_ctx->custom_splash_path, (void *)0xC0000000);
-
+
/* Derive keydata. If on 7.0.0+, sept has already derived keys for us. */
unsigned int keygen_type = 0;
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) {
@@ -665,27 +691,27 @@ uint32_t nxboot_main(void) {
if (warmboot_fw == NULL) {
fatal_error("[NXBOOT] Out of memory!\n");
}
-
+
memcpy(warmboot_fw, lp0fw_bin, warmboot_fw_size);
-
+
if (warmboot_fw_size == 0) {
fatal_error("[NXBOOT] Could not read the warmboot firmware from Package1!\n");
}
}
-
+
/* Patch warmboot firmware for atmosphere. */
if (warmboot_fw != NULL && warmboot_fw_size >= sizeof(warmboot_ams_header_t)) {
warmboot_ams_header_t *ams_header = (warmboot_ams_header_t *)warmboot_fw;
if (ams_header->ams_metadata.magic == WARMBOOT_MAGIC) {
/* Set target firmware */
ams_header->ams_metadata.target_firmware = target_firmware;
-
+
/* Set RSA modulus */
const uint8_t *pkc_modulus = fuse_get_retail_type() != 0 ? retail_pkc_modulus : dev_pkc_modulus;
memcpy(ams_header->rsa_modulus, pkc_modulus, sizeof(ams_header->rsa_modulus));
}
}
-
+
/* Select the right address for the warmboot firmware. */
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
@@ -708,7 +734,7 @@ uint32_t nxboot_main(void) {
}
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Rebuilding package2...\n");
-
+
/* Parse stratosphere config. */
nxboot_configure_stratosphere(MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware);
@@ -770,10 +796,10 @@ uint32_t nxboot_main(void) {
free(package2);
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Powering on the CCPLEX...\n");
-
+
/* Unmount everything. */
nxfs_end();
-
+
/* Return the memory address for booting CPU0. */
return (uint32_t)exosphere_memaddr;
}
diff --git a/fusee/fusee-secondary/src/package2.c b/fusee/fusee-secondary/src/package2.c
index de7af5b70..d9bd92ddc 100644
--- a/fusee/fusee-secondary/src/package2.c
+++ b/fusee/fusee-secondary/src/package2.c
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#include
#include
#include
@@ -66,7 +66,7 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm
if (thermosphere_size != 0 && package2->metadata.section_sizes[PACKAGE2_SECTION_UNUSED] != 0) {
fatal_error(u8"Error: Package2 has no unused section for Thermosphère!\n");
}
-
+
/* Load Kernel from SD, if possible. */
{
size_t sd_kernel_size = get_file_size("atmosphere/kernel.bin");
@@ -88,13 +88,13 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm
/* Perform any patches we want to the NX kernel. */
package2_patch_kernel(kernel, kernel_size, is_sd_kernel, (void *)&orig_ini1);
-
+
/* Ensure we know where embedded INI is if present, and we don't if not. */
- if ((target_firmware < ATMOSPHERE_TARGET_FIRMWARE_800 && orig_ini1 != NULL) ||
+ if ((target_firmware < ATMOSPHERE_TARGET_FIRMWARE_800 && orig_ini1 != NULL) ||
(target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_800 && orig_ini1 == NULL)) {
fatal_error("Error: inappropriate kernel embedded ini context");
}
-
+
print(SCREEN_LOG_LEVEL_DEBUG, "Rebuilding the INI1 section...\n");
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_800) {
package2_get_src_section((void *)&orig_ini1, package2, PACKAGE2_SECTION_INI1);
@@ -232,7 +232,7 @@ static bool package2_validate_metadata(package2_meta_t *metadata, uint8_t data[]
/* Perform version checks. */
/* We will be compatible with all package2s released before current, but not newer ones. */
- if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_700_CURRENT) {
+ if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_810_CURRENT) {
return true;
}
diff --git a/fusee/fusee-secondary/src/package2.h b/fusee/fusee-secondary/src/package2.h
index 1b3d6d492..7427ce85c 100644
--- a/fusee/fusee-secondary/src/package2.h
+++ b/fusee/fusee-secondary/src/package2.h
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#ifndef FUSEE_PACKAGE2_H
#define FUSEE_PACKAGE2_H
@@ -36,7 +36,8 @@
#define PACKAGE2_MAXVER_500_510 0x7
#define PACKAGE2_MAXVER_600_610 0x8
#define PACKAGE2_MAXVER_620 0x9
-#define PACKAGE2_MAXVER_700_CURRENT 0xA
+#define PACKAGE2_MAXVER_700_800 0xA
+#define PACKAGE2_MAXVER_810_CURRENT 0xB
#define PACKAGE2_MINVER_100 0x3
#define PACKAGE2_MINVER_200 0x4
@@ -46,7 +47,8 @@
#define PACKAGE2_MINVER_500_510 0x8
#define PACKAGE2_MINVER_600_610 0x9
#define PACKAGE2_MINVER_620 0xA
-#define PACKAGE2_MINVER_700_CURRENT 0xB
+#define PACKAGE2_MINVER_700_800 0xB
+#define PACKAGE2_MINVER_810_CURRENT 0xC
#define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull))
@@ -79,7 +81,7 @@ typedef struct {
/* Package2 can be encrypted or unencrypted for these functions: */
static inline size_t package2_meta_get_size(const package2_meta_t *metadata) {
- return metadata->ctr_dwords[0] ^ metadata->ctr_dwords[2] ^ metadata->ctr_dwords[3];
+ return metadata->ctr_dwords[0] ^ metadata->ctr_dwords[2] ^ metadata->ctr_dwords[3];
}
static inline uint8_t package2_meta_get_header_version(const package2_meta_t *metadata) {
diff --git a/fusee/fusee-secondary/src/start.s b/fusee/fusee-secondary/src/start.s
index f6da2a185..c93b588b1 100644
--- a/fusee/fusee-secondary/src/start.s
+++ b/fusee/fusee-secondary/src/start.s
@@ -14,7 +14,7 @@
* along with this program. If not, see .
*/
#include
-
+
.macro CLEAR_GPR_REG_ITER
mov r\@, #0
.endm
@@ -27,7 +27,7 @@
.type _start, %function
_start:
b _crt0
-
+
.word (_metadata - _start)
_crt0:
@@ -67,7 +67,7 @@ _crt0:
ldr r0, [r0]
ldr r1, [r1]
b main
-
+
/* Fusee-secondary header. */
.align 5
_metadata:
@@ -168,12 +168,20 @@ _content_headers:
.asciz "sept_primary"
.align 5
-/* sept_secondary content header */
-.word __sept_secondary_enc_start__
-.word __sept_secondary_enc_size__
+/* sept_secondary 00 content header */
+.word __sept_secondary_00_enc_start__
+.word __sept_secondary_00_enc_size__
.word CONTENT_TYPE_SP2
.word 0xCCCCCCCC
-.asciz "sept_secondary"
+.asciz "sept_secondary_00"
+.align 5
+
+/* sept_secondary 01 content header */
+.word __sept_secondary_01_enc_start__
+.word __sept_secondary_01_enc_size__
+.word CONTENT_TYPE_SP2
+.word 0xCCCCCCCC
+.asciz "sept_secondary_01"
.align 5
/* sm content header */
diff --git a/sept/sept-secondary/KEYS_template.py b/sept/sept-secondary/KEYS_template.py
index 38cdcb0c4..a3ac39639 100644
--- a/sept/sept-secondary/KEYS_template.py
+++ b/sept/sept-secondary/KEYS_template.py
@@ -1,7 +1,19 @@
-HOVI_ENC_KEY_PRD = bytearray.fromhex('00000000000000000000000000000000')
-HOVI_ENC_KEY_DEV = bytearray.fromhex('00000000000000000000000000000000')
-HOVI_SIG_KEY_PRD = bytearray.fromhex('00000000000000000000000000000000')
-HOVI_SIG_KEY_DEV = bytearray.fromhex('00000000000000000000000000000000')
-HOVI_KEK_KEY_PRD = bytearray.fromhex('00000000000000000000000000000000')
-HOVI_KEK_KEY_DEV = bytearray.fromhex('00000000000000000000000000000000')
-IV = bytearray.fromhex('00000000000000000000000000000000')
+NUM_KEYS = 2
+
+HOVI_ENC_KEY_PRD = [
+ bytearray.fromhex('00000000000000000000000000000000'),
+ bytearray.fromhex('00000000000000000000000000000000'),
+]
+HOVI_SIG_KEY_PRD = [
+ bytearray.fromhex('00000000000000000000000000000000'),
+ bytearray.fromhex('00000000000000000000000000000000'),
+]
+
+IV = [
+ bytearray.fromhex('00000000000000000000000000000000'),
+ bytearray.fromhex('00000000000000000000000000000000'),
+]
+
+assert len(HOVI_ENC_KEY_PRD) == NUM_KEYS
+assert len(HOVI_SIG_KEY_PRD) == NUM_KEYS
+assert len(IV) == NUM_KEYS
\ No newline at end of file
diff --git a/sept/sept-secondary/Makefile b/sept/sept-secondary/Makefile
index 03a8a5f8c..b9721de5f 100644
--- a/sept/sept-secondary/Makefile
+++ b/sept/sept-secondary/Makefile
@@ -137,12 +137,12 @@ clean:
@echo clean ...
@$(MAKE) -C $(AMS)/exosphere/rebootstub clean
@$(MAKE) -C key_derivation clean
- @rm -fr $(BUILD) $(TARGET).bin $(TARGET).enc $(TARGET).elf
+ @rm -fr $(BUILD) $(TARGET).bin $(TARGET)_*.enc $(TARGET).elf
#---------------------------------------------------------------------------------
else
-.PHONY: all
+.PHONY: all $(OUTPUT).bin
DEPENDS := $(OFILES:.o=.d)
diff --git a/sept/sept-secondary/key_derivation/src/key_derivation.c b/sept/sept-secondary/key_derivation/src/key_derivation.c
index 65eb9290b..a94885f71 100644
--- a/sept/sept-secondary/key_derivation/src/key_derivation.c
+++ b/sept/sept-secondary/key_derivation/src/key_derivation.c
@@ -20,7 +20,7 @@
#define AL16 __attribute__((aligned(16)))
-#define DERIVATION_ID_MAX 1
+#define DERIVATION_ID_MAX 2
static const uint8_t AL16 keyblob_seed_00[0x10] = {
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
@@ -44,10 +44,12 @@ static const uint8_t AL16 masterkey_4x_seed[0x10] = {
static const uint8_t AL16 master_kek_seeds[DERIVATION_ID_MAX][0x10] = {
{0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C},
+ {0xDE, 0xDC, 0xE3, 0x39, 0x30, 0x88, 0x16, 0xF8, 0xAE, 0x97, 0xAD, 0xEC, 0x64, 0x2D, 0x41, 0x41},
};
static const uint8_t AL16 master_devkey_seeds[DERIVATION_ID_MAX][0x10] = {
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D},
+ {0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE},
};
void derive_keys(void) {
@@ -101,7 +103,7 @@ void derive_keys(void) {
}
/* Derive master kek. */
- decrypt_data_into_keyslot(0xE, 0xE, master_kek_seeds[0], 0x10);
+ decrypt_data_into_keyslot(0xE, 0xE, master_kek_seeds[derivation_id], 0x10);
/* Derive master key, device master key. */
decrypt_data_into_keyslot(0xC, 0xE, masterkey_seed, 0x10);
@@ -123,7 +125,7 @@ void derive_keys(void) {
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
/* Derive firmware specific device key. */
- se_aes_ecb_decrypt_block(0xA, work_buffer, 0x10, master_devkey_seeds[0], 0x10);
+ se_aes_ecb_decrypt_block(0xA, work_buffer, 0x10, master_devkey_seeds[derivation_id], 0x10);
decrypt_data_into_keyslot(0xE, 0xE, work_buffer, 0x10);
/* Clear work buffer. */
diff --git a/sept/sept-secondary/sept_sign.py b/sept/sept-secondary/sept_sign.py
index ba108c1fc..a5ca66a36 100644
--- a/sept/sept-secondary/sept_sign.py
+++ b/sept/sept-secondary/sept_sign.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-import sys
+import sys, os
from struct import pack as pk, unpack as up
from Crypto.Cipher import AES
from Crypto.Hash import CMAC
@@ -41,7 +41,7 @@ def get_last_block_for_desired_mac(key, data, desired_mac):
return last_block
-def sign_encrypt_code(code, sig_key, enc_key, iv, desired_mac):
+def sign_encrypt_code(code, sig_key, enc_key, iv, desired_mac, version):
# Pad with 0x20 of zeroes.
code = code + bytearray(0x20)
code_len = len(code)
@@ -49,6 +49,9 @@ def sign_encrypt_code(code, sig_key, enc_key, iv, desired_mac):
code_len &= ~0xFFF
code = code + bytearray(code_len - len(code))
+ # Insert version
+ code = code[:8] + pk('
#include
-void derive_keys(void);
+void derive_keys(uint32_t version);
void load_keys(const uint8_t *se_state);
#endif
diff --git a/sept/sept-secondary/src/main.c b/sept/sept-secondary/src/main.c
index 50c4f7285..b1cb458a4 100644
--- a/sept/sept-secondary/src/main.c
+++ b/sept/sept-secondary/src/main.c
@@ -48,7 +48,7 @@ static void set_has_rebooted(bool rebooted) {
}
-static void exfiltrate_keys_and_reboot_if_needed(void) {
+static void exfiltrate_keys_and_reboot_if_needed(uint32_t version) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
uint8_t *enc_se_state = (uint8_t *)0x4003E000;
uint8_t *dec_se_state = (uint8_t *)0x4003F000;
@@ -59,7 +59,7 @@ static void exfiltrate_keys_and_reboot_if_needed(void) {
set_has_rebooted(true);
/* Derive keys. */
- derive_keys();
+ derive_keys(version);
reboot_to_self();
} else {
@@ -135,14 +135,14 @@ static void exit_callback(int rc) {
relocate_and_chainload();
}
-int main(void) {
+int sept_main(uint32_t version) {
const char *stage2_path;
stage2_args_t *stage2_args;
uint32_t stage2_version = 0;
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
/* Extract keys from the security engine, which TSEC FW locked down. */
- exfiltrate_keys_and_reboot_if_needed();
+ exfiltrate_keys_and_reboot_if_needed(version);
/* Override the global logging level. */
log_set_log_level(log_level);
diff --git a/sept/sept-secondary/src/start.s b/sept/sept-secondary/src/start.s
index b79cfce26..73cdf5b10 100644
--- a/sept/sept-secondary/src/start.s
+++ b/sept/sept-secondary/src/start.s
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
.macro CLEAR_GPR_REG_ITER
mov r\@, #0
.endm
@@ -26,13 +26,18 @@
_start:
/* Switch to system mode, mask all interrupts, clear all flags */
msr cpsr_cxsf, #0xDF
+ b begin_relocation_loop
+ _version:
+ .word 0x00000000 /* Version. */
+ .word 0x00000000 /* Reserved. */
+ begin_relocation_loop:
/* Relocate ourselves if necessary */
ldr r2, =__start__
adr r3, _start
cmp r2, r3
beq _relocation_loop_end
-
+
/* If we are relocating, we are not rebooting to ourselves. Note that. */
ldr r0, =0x4003FFFC
mov r1, #0x0
@@ -50,12 +55,12 @@ _start:
ldr r12, =_second_relocation_start
bx r12
-
+
_second_relocation_start:
ldr r4, =__bss_start__
sub r4, r4, r2
mov r1, #0x0
-
+
_second_relocation_loop:
ldmia r3!, {r5-r12}
stmia r2!, {r5-r12}
@@ -67,7 +72,7 @@ _start:
bx r12
_relocation_loop_end:
-
+
/* Set the stack pointer */
ldr sp, =__stack_top__
mov fp, #0
@@ -78,7 +83,9 @@ _start:
CLEAR_GPR_REG_ITER
.endr
ldr lr, =__program_exit
- b main
+ ldr r0, =_version
+ ldr r0, [r0]
+ b sept_main
/* No need to include this in normal programs: */
.section .chainloader.text.start, "ax", %progbits