sept: validate ccplex reset vector

This commit is contained in:
Michael Scire 2019-06-19 00:32:04 -07:00
parent 6829572556
commit b82d8aaba9
4 changed files with 29 additions and 68 deletions

View file

@ -138,6 +138,11 @@ void cluster_boot_cpu0(uint32_t entry)
MAKE_EXCP_VEC_REG(0x100) = 0; MAKE_EXCP_VEC_REG(0x100) = 0;
/* Check for reset vector lock. */
if (SB_CSR_0 & 2) {
generic_panic();
}
/* Set reset vector. */ /* Set reset vector. */
SB_AA64_RESET_LOW_0 = (entry | 1); SB_AA64_RESET_LOW_0 = (entry | 1);
SB_AA64_RESET_HIGH_0 = 0; SB_AA64_RESET_HIGH_0 = 0;
@ -146,6 +151,15 @@ void cluster_boot_cpu0(uint32_t entry)
SB_CSR_0 = 2; SB_CSR_0 = 2;
(void)SB_CSR_0; (void)SB_CSR_0;
/* Validate reset vector lock + RESET_LOW/HIGH values. */
if (!(SB_CSR_0 & 2)) {
generic_panic();
}
if (SB_AA64_RESET_LOW_0 != (entry | 1) || SB_AA64_RESET_HIGH_0 != 0) {
generic_panic();
}
/* Set CPU_STRICT_TZ_APERTURE_CHECK. */ /* Set CPU_STRICT_TZ_APERTURE_CHECK. */
/* NOTE: [4.0.0+] This was added, but it breaks Exosphère. */ /* NOTE: [4.0.0+] This was added, but it breaks Exosphère. */
/* MAKE_MC_REG(MC_TZ_SECURITY_CTRL) = 1; */ /* MAKE_MC_REG(MC_TZ_SECURITY_CTRL) = 1; */

View file

@ -22,6 +22,7 @@
#include "se.h" #include "se.h"
#include "pmc.h" #include "pmc.h"
#include "emc.h" #include "emc.h"
#include "sysreg.h"
#include "key_derivation.h" #include "key_derivation.h"
#include "timers.h" #include "timers.h"
#include "fs_utils.h" #include "fs_utils.h"
@ -96,9 +97,6 @@ static void setup_env(void) {
/* Initialize hardware. */ /* Initialize hardware. */
nx_hwinit(); nx_hwinit();
/* Check for panics. */
check_and_display_panic();
/* Zero-fill the framebuffer and register it as printk provider. */ /* Zero-fill the framebuffer and register it as printk provider. */
video_init(g_framebuffer); video_init(g_framebuffer);
@ -141,6 +139,11 @@ int sept_main(uint32_t version) {
uint32_t stage2_version = 0; uint32_t stage2_version = 0;
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE; ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
/* Validate that we can safely boot the CCPLEX. */
if (SB_CSR_0 & 2) {
generic_panic();
}
/* Extract keys from the security engine, which TSEC FW locked down. */ /* Extract keys from the security engine, which TSEC FW locked down. */
exfiltrate_keys_and_reboot_if_needed(version); exfiltrate_keys_and_reboot_if_needed(version);

View file

@ -13,76 +13,17 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdint.h>
#include <stddef.h>
#include "panic.h" #include "panic.h"
#include "di.h" #include "di.h"
#include "pmc.h" #include "pmc.h"
#include "se.h"
#include "fuse.h" #include "fuse.h"
#include "utils.h" #include "utils.h"
static uint32_t g_panic_code = 0; static uint32_t g_panic_code = 0;
void check_and_display_panic(void) {
/* We also handle our own panics. */
/* In the case of our own panics, we assume that the display has already been initialized. */
bool has_panic = APBDEV_PMC_RST_STATUS_0 != 0 || g_panic_code != 0;
uint32_t code = g_panic_code == 0 ? APBDEV_PMC_SCRATCH200_0 : g_panic_code;
has_panic = has_panic && !(APBDEV_PMC_RST_STATUS_0 != 1 && code == PANIC_CODE_SAFEMODE);
if (has_panic) {
uint32_t color;
/* Check for predefined codes: */
switch (code & MASK(20)) {
case 0x01: /* Package2 signature verification failed. */
case 0x02: /* Package2 meta verification failed. */
case 0x03: /* Package2 version check failed. */
case 0x04: /* Package2 payload verification failed. */
color = PANIC_COLOR_KERNEL;
break;
case 0x05: /* Unknown SMC. */
case 0x06: /* Unknown Abort. */
color = PANIC_COLOR_SECMON_GENERIC;
break;
case 0x07: /* Invalid CPU context. */
case 0x08: /* Invalid SE state. */
case 0x09: /* CPU is already awake (2.0.0+). */
color = PANIC_COLOR_SECMON_DEEPSLEEP;
break;
case 0x10: /* Unknown exception. */
color = PANIC_COLOR_SECMON_EXCEPTION;
break;
case 0x30: /* General bootloader error. */
case 0x31: /* Invalid DRAM ID. */
case 0x32: /* Invalid size. */
case 0x33: /* Invalid arguement. */
case 0x34: /* Bad GPT. */
case 0x35: /* Failed to boot SafeMode. */
case 0x36: /* Activity monitor fired (4.0.0+). */
color = PANIC_COLOR_BOOTLOADER_GENERIC;
break;
case 0x40: /* Kernel panic. */
color = PANIC_COLOR_KERNEL;
break;
default:
color = code >> 20;
color |= color << 4;
break;
}
if (g_panic_code == 0) {
display_init();
}
display_color_screen(color);
wait_for_button_and_reboot();
} else {
g_panic_code = 0;
APBDEV_PMC_SCRATCH200_0 = 0;
}
}
__attribute__ ((noreturn)) void panic(uint32_t code) { __attribute__ ((noreturn)) void panic(uint32_t code) {
/* Set panic code. */ /* Set panic code. */
if (g_panic_code == 0) { if (g_panic_code == 0) {
@ -90,9 +31,13 @@ __attribute__ ((noreturn)) void panic(uint32_t code) {
APBDEV_PMC_SCRATCH200_0 = code; APBDEV_PMC_SCRATCH200_0 = code;
} }
/* Clear all keyslots. */
for (size_t i = 0; i < 0x10; i++) {
clear_aes_keyslot(i);
}
fuse_disable_programming(); fuse_disable_programming();
APBDEV_PMC_CRYPTO_OP_0 = 1; /* Disable all SE operations. */ APBDEV_PMC_CRYPTO_OP_0 = 1; /* Disable all SE operations. */
check_and_display_panic();
while(true); while(true);
} }

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef FUSEE_PANIC_H #ifndef FUSEE_PANIC_H
#define FUSEE_PANIC_H #define FUSEE_PANIC_H
@ -28,7 +28,6 @@
#define PANIC_CODE_SAFEMODE 0x00000020 #define PANIC_CODE_SAFEMODE 0x00000020
void check_and_display_panic(void);
__attribute__ ((noreturn)) void panic(uint32_t code); __attribute__ ((noreturn)) void panic(uint32_t code);
#endif #endif