mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-01 15:28:21 -04:00
Add single source of truth for target firmwares.
This commit is contained in:
parent
fc4912ef54
commit
e0f1e637f7
31 changed files with 855 additions and 171 deletions
|
@ -17,6 +17,8 @@
|
|||
#ifndef FUSEE_EXOSPHERE_CONFIG_H
|
||||
#define FUSEE_EXOSPHERE_CONFIG_H
|
||||
|
||||
#include <atmosphere.h>
|
||||
|
||||
/* This serves to set configuration for *exosphere itself*, separate from the SecMon Exosphere mimics. */
|
||||
|
||||
/* "XBC0" */
|
||||
|
@ -24,16 +26,6 @@
|
|||
/* "XBC1" */
|
||||
#define MAGIC_EXOSPHERE_BOOTCONFIG (0x31434258)
|
||||
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_100 1
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_200 2
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_300 3
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_400 4
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_500 5
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_600 6
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_620 7
|
||||
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_MIN EXOSPHERE_TARGET_FIRMWARE_100
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_MAX EXOSPHERE_TARGET_FIRMWARE_620
|
||||
|
||||
#define EXOSPHERE_FLAGS_DEFAULT 0x00000000
|
||||
#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u)
|
||||
|
|
|
@ -141,7 +141,7 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
|
|||
}
|
||||
|
||||
/* Do 6.2.0+ keygen. */
|
||||
if (target_firmware >= EXOSPHERE_TARGET_FIRMWARE_620) {
|
||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_620) {
|
||||
if (memcmp(tsec_root_key, zeroes, 0x10) != 0) {
|
||||
/* We got a valid key from emulation. */
|
||||
set_aes_keyslot(0xC, tsec_root_key, 0x10);
|
||||
|
@ -185,27 +185,27 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
|
|||
set_aes_keyslot(0xC, g_dec_keyblobs[available_revision].master_kek, 0x10);
|
||||
|
||||
/* Also set the Package1 key for the revision that is stored on the eMMC boot0 partition. */
|
||||
if (target_firmware < EXOSPHERE_TARGET_FIRMWARE_620) {
|
||||
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_620) {
|
||||
load_package1_key(available_revision);
|
||||
}
|
||||
|
||||
/* Derive keys for Exosphere, lock critical keyslots. */
|
||||
switch (target_firmware) {
|
||||
case EXOSPHERE_TARGET_FIRMWARE_100:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_200:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_300:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_100:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_200:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_300:
|
||||
decrypt_data_into_keyslot(0xD, 0xF, devicekey_seed, 0x10);
|
||||
decrypt_data_into_keyslot(0xC, 0xC, masterkey_seed, 0x10);
|
||||
break;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_400:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_400:
|
||||
decrypt_data_into_keyslot(0xD, 0xF, devicekey_4x_seed, 0x10);
|
||||
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
|
||||
decrypt_data_into_keyslot(0xE, 0xC, masterkey_4x_seed, 0x10);
|
||||
decrypt_data_into_keyslot(0xC, 0xC, masterkey_seed, 0x10);
|
||||
break;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_500:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_600:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_620:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_500:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_600:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
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);
|
||||
|
@ -222,11 +222,11 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
|
|||
/* Sets final keyslot flags, for handover to TZ/Exosphere. Setting these will prevent the BPMP from using the device key or master key. */
|
||||
void finalize_nx_keydata(uint32_t target_firmware) {
|
||||
set_aes_keyslot_flags(0xC, 0xFF);
|
||||
set_aes_keyslot_flags((target_firmware >= EXOSPHERE_TARGET_FIRMWARE_400) ? (KEYSLOT_SWITCH_4XOLDDEVICEKEY) : (KEYSLOT_SWITCH_DEVICEKEY), 0xFF);
|
||||
set_aes_keyslot_flags((target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_400) ? (KEYSLOT_SWITCH_4XOLDDEVICEKEY) : (KEYSLOT_SWITCH_DEVICEKEY), 0xFF);
|
||||
}
|
||||
|
||||
static void generate_specific_aes_key(void *dst, const void *wrapped_key, bool should_mask, uint32_t target_firmware) {
|
||||
unsigned int keyslot = (target_firmware >= EXOSPHERE_TARGET_FIRMWARE_400) ? (KEYSLOT_SWITCH_4XOLDDEVICEKEY) : (KEYSLOT_SWITCH_DEVICEKEY);
|
||||
unsigned int keyslot = (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_400) ? (KEYSLOT_SWITCH_4XOLDDEVICEKEY) : (KEYSLOT_SWITCH_DEVICEKEY);
|
||||
if (fuse_get_bootrom_patch_version() < 0x7F) {
|
||||
/* On dev units, use a fixed "all-zeroes" seed. */
|
||||
/* Yes, this data really is all-zero in actual TrustZone .rodata. */
|
||||
|
@ -257,7 +257,7 @@ static void generate_personalized_aes_key_for_bis(void *dst, const void *wrapped
|
|||
0x89, 0x61, 0x5E, 0xE0, 0x5C, 0x31, 0xB6, 0x80, 0x5F, 0xE5, 0x8F, 0x3D, 0xA2, 0x4F, 0x7A, 0xA8
|
||||
};
|
||||
|
||||
unsigned int keyslot = (target_firmware >= EXOSPHERE_TARGET_FIRMWARE_400) ? (KEYSLOT_SWITCH_4XOLDDEVICEKEY) : (KEYSLOT_SWITCH_DEVICEKEY);
|
||||
unsigned int keyslot = (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_400) ? (KEYSLOT_SWITCH_4XOLDDEVICEKEY) : (KEYSLOT_SWITCH_DEVICEKEY);
|
||||
/* Derive kek. */
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, keyslot, kek_source, 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, KEYSLOT_SWITCH_TEMPKEY, wrapped_kek, 0x10);
|
||||
|
|
|
@ -106,20 +106,20 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
|
|||
const package1loader_header_t *package1loader_header = (const package1loader_header_t *)package1loader;
|
||||
switch (package1loader_header->version) {
|
||||
case 0x01: /* 1.0.0 */
|
||||
return EXOSPHERE_TARGET_FIRMWARE_100;
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_100;
|
||||
case 0x02: /* 2.0.0 - 2.3.0 */
|
||||
return EXOSPHERE_TARGET_FIRMWARE_200;
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_200;
|
||||
case 0x04: /* 3.0.0 and 3.0.1 - 3.0.2 */
|
||||
return EXOSPHERE_TARGET_FIRMWARE_300;
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_300;
|
||||
case 0x07: /* 4.0.0 - 4.1.0 */
|
||||
return EXOSPHERE_TARGET_FIRMWARE_400;
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_400;
|
||||
case 0x0B: /* 5.0.0 - 5.1.0 */
|
||||
return EXOSPHERE_TARGET_FIRMWARE_500;
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_500;
|
||||
case 0x0E: { /* 6.0.0 - 6.2.0 */
|
||||
if (memcmp(package1loader_header->build_timestamp, "20180802", 8) == 0) {
|
||||
return EXOSPHERE_TARGET_FIRMWARE_600;
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_600;
|
||||
} else if (memcmp(package1loader_header->build_timestamp, "20181107", 8) == 0) {
|
||||
return EXOSPHERE_TARGET_FIRMWARE_620;
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_620;
|
||||
} else {
|
||||
fatal_error("[NXBOOT]: Unable to identify package1!\n");
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
|
|||
fatal_error("[NXBOOT]: Failed to parse BCT.ini!\n");
|
||||
}
|
||||
|
||||
if ((exo_cfg.target_firmware < EXOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > EXOSPHERE_TARGET_FIRMWARE_MAX)) {
|
||||
if ((exo_cfg.target_firmware < ATMOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX)) {
|
||||
fatal_error("[NXBOOT]: Invalid Exosphere target firmware!\n");
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ static void nxboot_configure_stratosphere(uint32_t target_firmware) {
|
|||
}
|
||||
} else {
|
||||
/* Check if fuses are < 4.0.0, but firmware is >= 4.0.0 */
|
||||
if (target_firmware >= EXOSPHERE_TARGET_FIRMWARE_400 && !(fuse_get_reserved_odm(7) & ~0x0000000F)) {
|
||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_400 && !(fuse_get_reserved_odm(7) & ~0x0000000F)) {
|
||||
kip_patches_set_enable_nogc();
|
||||
}
|
||||
}
|
||||
|
@ -252,8 +252,8 @@ static void nxboot_move_bootconfig() {
|
|||
fclose(bcfile);
|
||||
|
||||
/* Select the actual BootConfig size and destination address. */
|
||||
bootconfig_addr = (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_600) ? 0x4003D000 : 0x4003F800;
|
||||
bootconfig_size = (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) ? 0x3000 : 0x1000;
|
||||
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);
|
||||
|
@ -360,7 +360,7 @@ uint32_t nxboot_main(void) {
|
|||
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 >= EXOSPHERE_TARGET_FIRMWARE_620) {
|
||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_620) {
|
||||
tsec_fw_size = 0x2900;
|
||||
} else {
|
||||
tsec_fw_size = 0xF00;
|
||||
|
@ -372,7 +372,7 @@ uint32_t nxboot_main(void) {
|
|||
/* Get the TSEC keys. */
|
||||
uint8_t tsec_key[0x10] = {0};
|
||||
uint8_t tsec_root_key[0x10] = {0};
|
||||
if (target_firmware >= EXOSPHERE_TARGET_FIRMWARE_620) {
|
||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_620) {
|
||||
uint8_t tsec_keys[0x20] = {0};
|
||||
|
||||
/* Emulate the TSEC payload on 6.2.0+. */
|
||||
|
@ -398,7 +398,7 @@ uint32_t nxboot_main(void) {
|
|||
nxboot_configure_exosphere(target_firmware, keygen_type);
|
||||
|
||||
/* Initialize Boot Reason on older firmware versions. */
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Initializing Boot Reason...\n");
|
||||
nxboot_set_bootreason();
|
||||
}
|
||||
|
@ -420,7 +420,7 @@ uint32_t nxboot_main(void) {
|
|||
fatal_error("[NXBOOT]: Could not read the warmboot firmware from %s!\n", loader_ctx->warmboot_path);
|
||||
}
|
||||
} else {
|
||||
if (target_firmware >= EXOSPHERE_TARGET_FIRMWARE_620) {
|
||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_620) {
|
||||
/* Package1 was decrypted during TSEC emulation. */
|
||||
const uint8_t *package1_hdr = (const uint8_t *)package1loader + 0x7000 - 0x20;
|
||||
package1 = (package1_header_t *)(package1_hdr + 0x20);
|
||||
|
@ -446,9 +446,9 @@ uint32_t nxboot_main(void) {
|
|||
}
|
||||
|
||||
/* Select the right address for the warmboot firmware. */
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
warmboot_memaddr = (void *)0x8000D000;
|
||||
} else if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_600) {
|
||||
} else if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_600) {
|
||||
warmboot_memaddr = (void *)0x4003B000;
|
||||
} else {
|
||||
warmboot_memaddr = (void *)0x4003D800;
|
||||
|
@ -459,7 +459,7 @@ uint32_t nxboot_main(void) {
|
|||
/* Copy the warmboot firmware and set the address in PMC if necessary. */
|
||||
if (warmboot_fw && (warmboot_fw_size > 0)) {
|
||||
memcpy(warmboot_memaddr, warmboot_fw, warmboot_fw_size);
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400)
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400)
|
||||
pmc->scratch1 = (uint32_t)warmboot_memaddr;
|
||||
}
|
||||
|
||||
|
@ -474,7 +474,7 @@ uint32_t nxboot_main(void) {
|
|||
print(SCREEN_LOG_LEVEL_INFO, u8"[NXBOOT]: Reading Exosphère...\n");
|
||||
|
||||
/* Select the right address for Exosphère. */
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
exosphere_memaddr = (void *)0x4002D000;
|
||||
} else {
|
||||
exosphere_memaddr = (void *)0x4002B000;
|
||||
|
@ -502,7 +502,7 @@ uint32_t nxboot_main(void) {
|
|||
nxboot_move_bootconfig();
|
||||
|
||||
/* Set 3.0.0/3.0.1/3.0.2 warmboot security check. */
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware == EXOSPHERE_TARGET_FIRMWARE_300) {
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware == ATMOSPHERE_TARGET_FIRMWARE_300) {
|
||||
const package1loader_header_t *package1loader_header = (const package1loader_header_t *)package1loader;
|
||||
if (!strcmp(package1loader_header->build_timestamp, "20170519101410"))
|
||||
pmc->secure_scratch32 = 0xE3; /* Warmboot 3.0.0 security check.*/
|
||||
|
|
|
@ -36,7 +36,7 @@ void nxboot_finish(uint32_t boot_memaddr) {
|
|||
|
||||
/* Lock keyslots. */
|
||||
set_aes_keyslot_flags(KEYSLOT_SWITCH_MASTERKEY, 0xFF);
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
set_aes_keyslot_flags(KEYSLOT_SWITCH_DEVICEKEY, 0xFF);
|
||||
} else {
|
||||
set_aes_keyslot_flags(KEYSLOT_SWITCH_4XOLDDEVICEKEY, 0xFF);
|
||||
|
@ -62,7 +62,7 @@ void nxboot_finish(uint32_t boot_memaddr) {
|
|||
|
||||
/* Boot up Exosphère. */
|
||||
MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 0;
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_LOADED_PACKAGE2;
|
||||
} else {
|
||||
MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X;
|
||||
|
@ -93,7 +93,7 @@ void nxboot_finish(uint32_t boot_memaddr) {
|
|||
}
|
||||
|
||||
/* Signal Exosphère. */
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_FINISHED;
|
||||
} else {
|
||||
MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_FINISHED_4X;
|
||||
|
|
|
@ -62,7 +62,7 @@ ini1_header_t *stratosphere_get_ini1(uint32_t target_firmware) {
|
|||
return g_stratosphere_ini1;
|
||||
}
|
||||
|
||||
if (target_firmware <= EXOSPHERE_TARGET_FIRMWARE_100) {
|
||||
if (target_firmware <= ATMOSPHERE_TARGET_FIRMWARE_100) {
|
||||
boot_kip = boot_100_kip;
|
||||
boot_kip_size = boot_100_kip_size;
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue