From 1f8f08d48a903f85871d1bac3b62cb12c6128459 Mon Sep 17 00:00:00 2001 From: Saleem Rashid Date: Sun, 11 Feb 2018 22:10:12 +0000 Subject: [PATCH] setup: Enable MPU Disable code execution from SRAM and reconfiguration of the MPU. Prevents almost all code execution attacks. --- firmware/trezor.c | 5 ++++ setup.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++- setup.h | 2 ++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/firmware/trezor.c b/firmware/trezor.c index 9bb013e..e7e011f 100644 --- a/firmware/trezor.c +++ b/firmware/trezor.c @@ -102,6 +102,11 @@ int main(void) } #endif +#ifdef APPVER + // enable MPU (Memory Protection Unit) + mpu_config(); +#endif + timer_init(); #if DEBUG_LINK diff --git a/setup.c b/setup.c index 28a9fc6..4fb75c5 100644 --- a/setup.c +++ b/setup.c @@ -17,16 +17,32 @@ * along with this library. If not, see . */ +#include +#include #include #include #include #include -#include +#include #include "rng.h" #include "layout.h" +#include "memory.h" #include "util.h" +#define MPU_RASR_SIZE_32B (0x04UL << MPU_RASR_SIZE_LSB) +#define MPU_RASR_SIZE_32KB (0x0EUL << MPU_RASR_SIZE_LSB) +#define MPU_RASR_SIZE_64KB (0x0FUL << MPU_RASR_SIZE_LSB) +#define MPU_RASR_SIZE_128KB (0x10UL << MPU_RASR_SIZE_LSB) +#define MPU_RASR_SIZE_256KB (0x11UL << MPU_RASR_SIZE_LSB) +#define MPU_RASR_SIZE_512KB (0x12UL << MPU_RASR_SIZE_LSB) +#define MPU_RASR_SIZE_512MB (0x1CUL << MPU_RASR_SIZE_LSB) + +// http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BABDJJGF.html +#define MPU_RASR_ATTR_FLASH (MPU_RASR_ATTR_C) +#define MPU_RASR_ATTR_SRAM (MPU_RASR_ATTR_S | MPU_RASR_ATTR_C) +#define MPU_RASR_ATTR_PERIPH (MPU_RASR_ATTR_S | MPU_RASR_ATTR_B) + uint32_t __stack_chk_guard; static inline void __attribute__((noreturn)) fault_handler(const char *line1) { @@ -46,6 +62,14 @@ void nmi_handler(void) } } +void hard_fault_handler(void) { + fault_handler("Hard fault"); +} + +void mem_manage_handler(void) { + fault_handler("Memory fault"); +} + void setup(void) { // set SCB_CCR STKALIGN bit to make sure 8-byte stack alignment on exception entry is in effect. @@ -130,3 +154,43 @@ void setupApp(void) gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO10); gpio_set_af(GPIOA, GPIO_AF10, GPIO10); } + +// Never use in bootloader! Disables access to PPB (including MPU, NVIC, SCB) +void mpu_config(void) +{ + // Enable memory fault handler + SCB_SHCSR |= SCB_SHCSR_MEMFAULTENA; + + // Disable MPU + MPU_CTRL = 0; + + // Bootloader (read-only, execute never) + MPU_RBAR = 0x08000000 | MPU_RBAR_VALID | (0 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_32KB | MPU_RASR_ATTR_AP_PRO_URO | MPU_RASR_ATTR_XN; + + // Metadata (read-write, execute never) + MPU_RBAR = 0x08008000 | MPU_RBAR_VALID | (1 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_32KB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN; + + // Firmware (read-only) + MPU_RBAR = 0x08010000 | MPU_RBAR_VALID | (2 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_64KB | MPU_RASR_ATTR_AP_PRO_URO; + MPU_RBAR = 0x08020000 | MPU_RBAR_VALID | (3 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_128KB | MPU_RASR_ATTR_AP_PRO_URO; + MPU_RBAR = 0x08040000 | MPU_RBAR_VALID | (4 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_256KB | MPU_RASR_ATTR_AP_PRO_URO; + + // SRAM (read-write, execute never) + MPU_RBAR = 0x20000000 | MPU_RBAR_VALID | (5 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_SRAM | MPU_RASR_SIZE_128KB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN; + + // Peripherals (read-write, execute never) + MPU_RBAR = PERIPH_BASE | MPU_RBAR_VALID | (6 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_PERIPH | MPU_RASR_SIZE_512MB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN; + + // Enable MPU + MPU_CTRL = MPU_CTRL_ENABLE; + + __asm__ volatile("dsb"); + __asm__ volatile("isb"); +} diff --git a/setup.h b/setup.h index c5236fc..34b88aa 100644 --- a/setup.h +++ b/setup.h @@ -27,4 +27,6 @@ extern uint32_t __stack_chk_guard; void setup(void); void setupApp(void); +void mpu_config(void); + #endif