Add single source of truth for target firmwares.

This commit is contained in:
Michael Scire 2018-12-17 12:39:35 -08:00
parent fc4912ef54
commit e0f1e637f7
31 changed files with 855 additions and 171 deletions

View file

@ -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)

View file

@ -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);

View file

@ -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.*/

View file

@ -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;

View file

@ -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 {