From fa4c219395469abc154e35936227b8182142eda6 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 1 Jun 2018 22:20:04 -0600 Subject: [PATCH] Exosphere: Fix bugs, now boots 5.1.0 successfully. --- exosphere/src/bootconfig.c | 8 ++++++++ exosphere/src/bootconfig.h | 2 ++ exosphere/src/bootup.c | 8 +++++++- exosphere/src/exocfg.h | 2 +- exosphere/src/mc.c | 4 ++-- exosphere/src/package2.c | 17 +++++++++++++++++ exosphere/src/smc_api.c | 20 ++++++++++++++++---- exosphere/src/smc_user.c | 18 +++++++++++------- exosphere/src/titlekey.c | 2 +- exosphere/src/utils.c | 2 +- 10 files changed, 66 insertions(+), 17 deletions(-) diff --git a/exosphere/src/bootconfig.c b/exosphere/src/bootconfig.c index c74f81c1b..dd2cfd870 100644 --- a/exosphere/src/bootconfig.c +++ b/exosphere/src/bootconfig.c @@ -75,6 +75,14 @@ bool bootconfig_take_extabt_serror_to_el3(void) { return (LOADED_BOOTCONFIG->unsigned_config.data[0x10] & 6) != 6; } +uint64_t bootconfig_get_value_for_sysctr0(void) { + if (LOADED_BOOTCONFIG->unsigned_config.data[0x24] & 1) { + return *(volatile uint64_t *)(&(LOADED_BOOTCONFIG->unsigned_config.data[0x30])); + } else { + return 0ULL; + } +} + uint64_t bootconfig_get_memory_arrangement(void) { if (bootconfig_is_debug_mode()) { if (fuse_get_dram_id() == 4) { diff --git a/exosphere/src/bootconfig.h b/exosphere/src/bootconfig.h index 1a69a0c68..f5505f4ab 100644 --- a/exosphere/src/bootconfig.h +++ b/exosphere/src/bootconfig.h @@ -59,6 +59,8 @@ bool bootconfig_is_debug_mode(void); bool bootconfig_take_extabt_serror_to_el3(void); +uint64_t bootconfig_get_value_for_sysctr0(void); + uint64_t bootconfig_get_memory_arrangement(void); uint64_t bootconfig_get_kernel_memory_configuration(void); diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c index bd6c640a9..57e18367b 100644 --- a/exosphere/src/bootup.c +++ b/exosphere/src/bootup.c @@ -231,11 +231,17 @@ void setup_4x_mmio(void) { AHB_ARBITRATION_DISABLE_0 |= 2; /* Set SMMU for BPMP/APB-DMA to point to TZRAM. */ MC_SMMU_PTB_ASID_0 = 1; + (void)(MAKE_MC_REG(0x014)); MC_SMMU_PTB_DATA_0 = 0x70012; MC_SMMU_AVPC_ASID_0 = 0x80000001; MC_SMMU_PPCS1_ASID_0 = 0x80000001; + (void)(MAKE_MC_REG(0x014)); + MAKE_MC_REG(0x34) = 0; + (void)(MAKE_MC_REG(0x014)); + MAKE_MC_REG(0x30) = 0; + (void)(MAKE_MC_REG(0x014)); /* Wait for the BPMP to halt. */ - while ((FLOW_CTLR_HALT_COP_EVENTS_0 >> 28) != 5) { + while ((FLOW_CTLR_HALT_COP_EVENTS_0 >> 29) != 2) { wait(1); } /* If not in a debugging context, setup the activity monitor. */ diff --git a/exosphere/src/exocfg.h b/exosphere/src/exocfg.h index 15fabc8f6..f02aa24e0 100644 --- a/exosphere/src/exocfg.h +++ b/exosphere/src/exocfg.h @@ -18,7 +18,7 @@ #define EXOSPHERE_TARGET_FIRMWARE_500 5 /* TODO: What should this be, for release? */ -#define EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG EXOSPHERE_TARGET_FIRMWARE_100 +#define EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG EXOSPHERE_TARGET_FIRMWARE_500 #define EXOSPHERE_LOOSEN_PACKAGE2_RESTRICTIONS_FOR_DEBUG 1 #define MAILBOX_BASE_PHYS (MMIO_GET_DEVICE_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX)) diff --git a/exosphere/src/mc.c b/exosphere/src/mc.c index bf1259b4b..74e9886ba 100644 --- a/exosphere/src/mc.c +++ b/exosphere/src/mc.c @@ -106,8 +106,8 @@ void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint6 carveout->flags_2 = 0x303C00; carveout->flags_3 = 0xCF0830BB; carveout->flags_4 = 0x3; - carveout->flags_5 = 0; - carveout->flags_6 = 0; + carveout->flags_5 = exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400 && carveout_id == 4 ? 0x8000 : 0; + carveout->flags_6 = exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400 && carveout_id == 4 ? 0x40000 : 0; carveout->flags_7 = 0; carveout->flags_8 = 0; carveout->flags_9 = 0; diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c index 2d131822b..507acb1fa 100644 --- a/exosphere/src/package2.c +++ b/exosphere/src/package2.c @@ -15,6 +15,7 @@ #include "randomcache.h" #include "timers.h" #include "bootconfig.h" +#include "sysctr0.h" #include "exocfg.h" #include "smc_api.h" @@ -406,6 +407,14 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) { /* Setup the Security Engine. */ setup_se(); + + /* Perform initial PMC register writes, if relevant. */ + if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) { + MAKE_REG32(PMC_BASE + 0x0A0) &= 0xFFF3FFFF; + MAKE_REG32(PMC_BASE + 0x818) &= 0xFFFFFFFE; + MAKE_REG32(PMC_BASE + 0x334) |= 0x10; + MAKE_REG32(PMC_BASE + 0x360) = 6; + } wait(1000); @@ -432,6 +441,14 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) { /* Load Boot Config into global. */ setup_boot_config(); + + /* Set sysctr0 registers based on bootconfig. */ + if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) { + uint64_t sysctr0_val = bootconfig_get_value_for_sysctr0(); + MAKE_SYSCTR0_REG(0x8) = (uint32_t)((sysctr0_val >> 0) & 0xFFFFFFFFULL); + MAKE_SYSCTR0_REG(0xC) = (uint32_t)((sysctr0_val >> 32) & 0xFFFFFFFFULL); + MAKE_SYSCTR0_REG(0x0) = 3; + } /* Synchronize with NX BOOTLOADER. */ if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) { diff --git a/exosphere/src/smc_api.c b/exosphere/src/smc_api.c index 6e07b4e91..23c5cb728 100644 --- a/exosphere/src/smc_api.c +++ b/exosphere/src/smc_api.c @@ -233,17 +233,29 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) { if ((smc_handler = g_smc_tables[handler_id].handlers[smc_id].handler) == NULL) { generic_panic(); } + + bool is_aes_kek = handler_id == SMC_HANDLER_USER && args->X[0] == 0xC3000007; -#if DEBUG_LOG_SMCS +#if DEBUG_LOG_SMCS + uint64_t num; if (handler_id == SMC_HANDLER_USER) { - uint64_t num = atomic_fetch_add(&num_smcs_called, 1); - *(volatile smc_args_t *)(get_iram_address_for_debug() + 0x100 + ((0x40 * num) & 0x3FFF)) = *args; + num = atomic_fetch_add(&num_smcs_called, 1); + *(volatile smc_args_t *)(get_iram_address_for_debug() + 0x100 + ((0x80 * num) & 0x3FFF)) = *args; } #endif /* Call function. */ args->X[0] = smc_handler(args); - if (args->X[0]) +#if DEBUG_LOG_SMCS + if (handler_id == SMC_HANDLER_USER) { + *(volatile smc_args_t *)(get_iram_address_for_debug() + 0x100 + ((0x80 * num + 0x40) & 0x3FFF)) = *args; + /*if (num >= 0x69) { + panic(PANIC_REBOOT); + }*/ + } +#endif + + if (args->X[0] && (!is_aes_kek || args->X[3] <= EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG)) { MAKE_REG32(get_iram_address_for_debug() + 0x4FF0) = handler_id; MAKE_REG32(get_iram_address_for_debug() + 0x4FF4) = smc_id; diff --git a/exosphere/src/smc_user.c b/exosphere/src/smc_user.c index 1d649f773..7cc8103de 100644 --- a/exosphere/src/smc_user.c +++ b/exosphere/src/smc_user.c @@ -113,7 +113,7 @@ uint32_t user_generate_aes_kek(smc_args_t *args) { master_key_rev -= 1; /* GenerateAesKek offsets by one. */ } - if (master_key_rev >= MASTERKEY_REVISION_MAX) { + if (master_key_rev >= MASTERKEY_REVISION_MAX || master_key_rev > mkey_get_revision()) { return 2; } @@ -628,8 +628,10 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) { master_key_rev -= 1; } - if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300 && master_key_rev >= MASTERKEY_REVISION_MAX) { - return 2; + if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300) { + if (master_key_rev >= MASTERKEY_REVISION_MAX) { + return 2; + } } else { master_key_rev = 0; } @@ -690,8 +692,10 @@ uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args) { if (master_key_rev > 0) { master_key_rev -= 1; } - if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300 && master_key_rev >= MASTERKEY_REVISION_MAX) { - return 2; + if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300) { + if (master_key_rev >= MASTERKEY_REVISION_MAX) { + return 2; + } } else { master_key_rev = 0; } @@ -782,8 +786,8 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) { size_t size; upage_ref_t page_ref; - /* This function no longer exists in 5.x+. */ - if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) { + /* This function only exists in 5.x+. */ + if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_500) { generic_panic(); } diff --git a/exosphere/src/titlekey.c b/exosphere/src/titlekey.c index 0c5cb7cf1..4c46ed226 100644 --- a/exosphere/src/titlekey.c +++ b/exosphere/src/titlekey.c @@ -133,7 +133,7 @@ size_t tkey_rsa_oaep_unwrap(void *dst, size_t dst_size, void *src, size_t src_si /* Extract the wrapped key. */ memcpy(dst, &db[wrapped_key_offset_in_db], wrapped_titlekey_size); - return wrapped_key_offset_in_db; + return wrapped_titlekey_size; } void tkey_aes_unwrap(void *dst, size_t dst_size, const void *src, size_t src_size) { diff --git a/exosphere/src/utils.c b/exosphere/src/utils.c index 5a8697c14..2f60fbfe1 100644 --- a/exosphere/src/utils.c +++ b/exosphere/src/utils.c @@ -27,7 +27,7 @@ __attribute__ ((noreturn)) void panic(uint32_t code) { /* For now, just use NX BOOTLOADER's panic. */ fuse_disable_programming(); APBDEV_PMC_CRYPTO_OP_0 = 1; /* Disable all SE operations. */ - while (1) { } + // while (1) { } watchdog_reboot(); }