1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-14 03:30:02 +00:00

bootloader: enable MPU, introduce delays to USB stack

This commit is contained in:
Pavol Rusnak 2019-02-21 09:52:28 +01:00
parent 5560a35af7
commit 828ba7b5b0
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
13 changed files with 110 additions and 21 deletions

View File

@ -83,6 +83,7 @@ SOURCE_TREZORHAL = [
'embed/trezorhal/image.c', 'embed/trezorhal/image.c',
'embed/trezorhal/flash.c', 'embed/trezorhal/flash.c',
'embed/trezorhal/mini_printf.c', 'embed/trezorhal/mini_printf.c',
'embed/trezorhal/mpu.c',
'embed/trezorhal/rng.c', 'embed/trezorhal/rng.c',
'embed/trezorhal/stm32.c', 'embed/trezorhal/stm32.c',
'embed/trezorhal/touch.c', 'embed/trezorhal/touch.c',

View File

@ -21,6 +21,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "common.h" #include "common.h"
#include "mpu.h"
#include "image.h" #include "image.h"
#include "flash.h" #include "flash.h"
#include "display.h" #include "display.h"
@ -224,6 +225,8 @@ static void check_bootloader_version(void)
int main(void) int main(void)
{ {
mpu_config_bootloader();
main_start: main_start:
display_clear(); display_clear();
@ -379,9 +382,10 @@ main_start:
ui_fadeout(); ui_fadeout();
} }
// mpu_config(); // mpu_config_firmware();
// jump_to_unprivileged(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE); // jump_to_unprivileged(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE);
mpu_config_off();
jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE); jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE);
return 0; return 0;

View File

@ -54,7 +54,7 @@ int main(void)
#if TREZOR_MODEL == T #if TREZOR_MODEL == T
check_and_replace_bootloader(); check_and_replace_bootloader();
// Enable MPU // Enable MPU
mpu_config(); mpu_config_firmware();
#endif #endif
// Init peripherals // Init peripherals

View File

@ -29,7 +29,8 @@
#include "stm32f4xx_ll_utils.h" #include "stm32f4xx_ll_utils.h"
void shutdown(void); // from util.s
extern void shutdown(void);
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00) #define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
@ -115,6 +116,24 @@ void hal_delay(uint32_t ms)
HAL_Delay(ms); HAL_Delay(ms);
} }
void delay_random(void)
{
int wait = rng_get() & 0xff;
volatile int i = 0;
volatile int j = wait;
while (i < wait) {
if (i + j != wait) {
shutdown();
}
++i;
--j;
}
// Double-check loop completion.
if (i != wait || j != 0) {
shutdown();
}
}
// reference RM0090 section 35.12.1 Figure 413 // reference RM0090 section 35.12.1 Figure 413
#define USB_OTG_HS_DATA_FIFO_RAM (USB_OTG_HS_PERIPH_BASE + 0x20000U) #define USB_OTG_HS_DATA_FIFO_RAM (USB_OTG_HS_PERIPH_BASE + 0x20000U)
#define USB_OTG_HS_DATA_FIFO_SIZE (4096U) #define USB_OTG_HS_DATA_FIFO_SIZE (4096U)

View File

@ -26,11 +26,14 @@
#define XSTR(s) STR(s) #define XSTR(s) STR(s)
#define STR(s) #s #define STR(s) #s
#ifndef MIN_8bits
#define MIN_8bits(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? (_a & 0xFF) : (_b & 0xFF); })
#endif
#ifndef MIN #ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
#endif #endif
#ifndef MAX #ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MAX(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; })
#endif #endif
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func); void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func);
@ -40,6 +43,8 @@ void __attribute__((noreturn)) error_shutdown(const char *line1, const char *lin
void hal_delay(uint32_t ms); void hal_delay(uint32_t ms);
void delay_random(void);
void clear_otg_hs_memory(void); void clear_otg_hs_memory(void);
extern uint32_t __stack_chk_guard; extern uint32_t __stack_chk_guard;

View File

@ -27,10 +27,61 @@
#define MPU_SUBREGION_DISABLE(X) ((X) << MPU_RASR_SRD_Pos) #define MPU_SUBREGION_DISABLE(X) ((X) << MPU_RASR_SRD_Pos)
void mpu_config(void) void mpu_config_off(void)
{ {
// Disable MPU // Disable MPU
HAL_MPU_Disable(); HAL_MPU_Disable();
}
void mpu_config_bootloader(void)
{
// Disable MPU
HAL_MPU_Disable();
// Note: later entries overwrite previous ones
// Flash (0x08000000 - 0x081FFFFF, 2 MiB, read-write)
MPU->RBAR = FLASH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER0;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_2MB | LL_MPU_REGION_PRIV_RO_URO;
// Flash (0x0800C000 - 0x0800FFFF, 16 KiB, no access)
MPU->RBAR = FLASH_BASE | 0xC000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER1;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS;
// Flash (0x0810C000 - 0x0810FFFF, 16 KiB, no access)
MPU->RBAR = FLASH_BASE | 0x10C000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER2;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS;
// SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end, read-write, execute never)
MPU->RBAR = SRAM_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER3;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0);
// Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never)
// External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never)
MPU->RBAR = PERIPH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER4;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
#ifdef STM32F427xx
// CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never)
MPU->RBAR = CCMDATARAM_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER5;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
#elif STM32F405xx
// no CCMRAM
#else
#error Unsupported MCU
#endif
// Enable MPU
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
void mpu_config_firmware(void)
{
// Disable MPU
HAL_MPU_Disable();
// Note: later entries overwrite previous ones
/* /*
// Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never) // Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never)
@ -77,5 +128,5 @@ void mpu_config(void)
#endif #endif
// Enable MPU // Enable MPU
HAL_MPU_Enable(0); HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
} }

View File

@ -20,6 +20,8 @@
#ifndef __MPU_H__ #ifndef __MPU_H__
#define __MPU_H__ #define __MPU_H__
void mpu_config(void); void mpu_config_off(void);
void mpu_config_bootloader(void);
void mpu_config_firmware(void);
#endif #endif

View File

@ -79,7 +79,8 @@ void SysTick_Handler(void)
uwTick++; uwTick++;
} }
void shutdown(void); // from util.s
extern void shutdown(void);
void PVD_IRQHandler(void) void PVD_IRQHandler(void)
{ {

View File

@ -314,6 +314,7 @@ static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
#define USB_WEBUSB_URL_SCHEME_HTTPS 1 #define USB_WEBUSB_URL_SCHEME_HTTPS 1
static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *req) { static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *req) {
delay_random();
if (((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_CLASS) && if (((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_CLASS) &&
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) && ((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) &&
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_VENDOR)) { ((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_VENDOR)) {
@ -330,7 +331,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
USB_WEBUSB_URL_SCHEME_HTTPS, // uint8_t bScheme USB_WEBUSB_URL_SCHEME_HTTPS, // uint8_t bScheme
't', 'r', 'e', 'z', 'o', 'r', '.', 'i', 'o', '/', 's', 't', 'a', 'r', 't', // char URL[] 't', 'r', 'e', 'z', 'o', 'r', '.', 'i', 'o', '/', 's', 't', 'a', 'r', 't', // char URL[]
}; };
USBD_CtlSendData(dev, UNCONST(webusb_url), MIN(req->wLength, sizeof(webusb_url))); USBD_CtlSendData(dev, UNCONST(webusb_url), MIN_8bits(req->wLength, sizeof(webusb_url)));
return USBD_OK; return USBD_OK;
} else { } else {
USBD_CtlError(dev, req); USBD_CtlError(dev, req);
@ -354,7 +355,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleId 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleId
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
}; };
USBD_CtlSendData(dev, UNCONST(winusb_wcid), MIN(req->wLength, sizeof(winusb_wcid))); USBD_CtlSendData(dev, UNCONST(winusb_wcid), MIN_8bits(req->wLength, sizeof(winusb_wcid)));
return USBD_OK; return USBD_OK;
} else { } else {
USBD_CtlError(dev, req); USBD_CtlError(dev, req);
@ -380,7 +381,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength 0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength
'{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00, '4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00, '8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00, '8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00, '-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00, 'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00, 'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData '{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00, '4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00, '8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00, '8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00, '-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00, 'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00, 'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData
}; };
USBD_CtlSendData(dev, UNCONST(winusb_guid), MIN(req->wLength, sizeof(winusb_guid))); USBD_CtlSendData(dev, UNCONST(winusb_guid), MIN_8bits(req->wLength, sizeof(winusb_guid)));
return USBD_OK; return USBD_OK;
} else { } else {
USBD_CtlError(dev, req); USBD_CtlError(dev, req);
@ -410,6 +411,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
} }
static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) { static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
delay_random();
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) { switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID: case USB_IFACE_TYPE_HID:
@ -429,6 +431,7 @@ static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
} }
static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) { static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
delay_random();
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) { switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID: case USB_IFACE_TYPE_HID:
@ -448,6 +451,7 @@ static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
} }
static uint8_t usb_class_sof(USBD_HandleTypeDef *dev) { static uint8_t usb_class_sof(USBD_HandleTypeDef *dev) {
delay_random();
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) { switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_VCP: case USB_IFACE_TYPE_VCP:

View File

@ -254,7 +254,6 @@ static void usb_hid_class_deinit(USBD_HandleTypeDef *dev, usb_hid_state_t *state
} }
static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) { static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) {
switch (req->bmRequest & USB_REQ_TYPE_MASK) { switch (req->bmRequest & USB_REQ_TYPE_MASK) {
// Class request // Class request
@ -302,11 +301,11 @@ static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
switch (req->wValue >> 8) { switch (req->wValue >> 8) {
case USB_DESC_TYPE_HID: case USB_DESC_TYPE_HID:
USBD_CtlSendData(dev, UNCONST(&state->desc_block->hid), MIN(req->wLength, sizeof(state->desc_block->hid))); USBD_CtlSendData(dev, UNCONST(&state->desc_block->hid), MIN_8bits(req->wLength, sizeof(state->desc_block->hid)));
return USBD_OK; return USBD_OK;
case USB_DESC_TYPE_REPORT: case USB_DESC_TYPE_REPORT:
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN(req->wLength, state->report_desc_len)); USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN_8bits(req->wLength, state->report_desc_len));
return USBD_OK; return USBD_OK;
default: default:

View File

@ -364,13 +364,13 @@ static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,
if ((req->bmRequest & USB_REQ_DIR_MASK) == USB_REQ_DIR_D2H) { if ((req->bmRequest & USB_REQ_DIR_MASK) == USB_REQ_DIR_D2H) {
if (req->bRequest == USB_CDC_GET_LINE_CODING) { if (req->bRequest == USB_CDC_GET_LINE_CODING) {
USBD_CtlSendData(dev, UNCONST(&line_coding), MIN(req->wLength, sizeof(line_coding))); USBD_CtlSendData(dev, UNCONST(&line_coding), MIN_8bits(req->wLength, sizeof(line_coding)));
} else { } else {
USBD_CtlSendData(dev, state->cmd_buffer, MIN(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN)); USBD_CtlSendData(dev, state->cmd_buffer, MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
} }
} else { // USB_REQ_DIR_H2D } else { // USB_REQ_DIR_H2D
if (req->wLength > 0) { if (req->wLength > 0) {
USBD_CtlPrepareRx(dev, state->cmd_buffer, MIN(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN)); USBD_CtlPrepareRx(dev, state->cmd_buffer, MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
} }
} }

View File

@ -263,9 +263,12 @@ typedef struct _USBD_HandleTypeDef
#define LOBYTE(x) ((uint8_t)(x & 0x00FF)) #define LOBYTE(x) ((uint8_t)(x & 0x00FF))
#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) #define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8))
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#if defined ( __GNUC__ ) #if defined ( __GNUC__ )
#ifndef __weak #ifndef __weak

View File

@ -27,10 +27,10 @@
#define STR(s) #s #define STR(s) #s
#ifndef MIN #ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
#endif #endif
#ifndef MAX #ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MAX(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; })
#endif #endif
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func); void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func);