refactor(core/embed): introduce new mpu driver

[no changelog]
tychovrahe/coresplit/merged
cepetr 2 weeks ago
parent d8475ad145
commit b42572a1bc

@ -150,6 +150,7 @@ SOURCE_TREZORHAL = [
'embed/trezorhal/unix/fault_handlers.c',
'embed/trezorhal/unix/flash.c',
'embed/trezorhal/unix/flash_otp.c',
'embed/trezorhal/unix/mpu.c',
'embed/trezorhal/unix/monoctr.c',
'embed/trezorhal/unix/random_delays.c',
'embed/trezorhal/unix/rng.c',

@ -423,6 +423,7 @@ SOURCE_UNIX = [
'embed/trezorhal/unix/flash_otp.c',
'embed/trezorhal/unix/flash.c',
'embed/trezorhal/unix/fwutils.c',
'embed/trezorhal/unix/mpu.c',
'embed/trezorhal/unix/random_delays.c',
'embed/trezorhal/unix/rng.c',
'embed/trezorhal/unix/systick.c',

@ -262,8 +262,6 @@ int main(void) {
clear_otg_hs_memory();
#endif
mpu_config_boardloader();
fault_handlers_init();
#ifdef USE_SDRAM
@ -335,7 +333,7 @@ int main(void) {
ensure_compatible_settings();
#endif
mpu_config_off();
mpu_reconfig(MPU_MODE_DISABLED);
// g_boot_command is preserved on STM32U5
jump_to(IMAGE_CODE_ALIGN(BOOTLOADER_START + IMAGE_HEADER_SIZE));

@ -170,10 +170,6 @@ __attribute__((noreturn)) int main(int argc, char **argv) {
jump_to(0);
}
void mpu_config_bootloader(void) {}
void mpu_config_off(void) {}
void jump_to(uint32_t address) {
bool storage_is_erased =
storage_empty(&STORAGE_AREAS[0]) && storage_empty(&STORAGE_AREAS[1]);

@ -13,8 +13,6 @@ extern uint8_t *FIRMWARE_START;
void emulator_poll_events(void);
void set_core_clock(int);
void mpu_config_bootloader(void);
void mpu_config_off(void);
__attribute__((noreturn)) void jump_to(uint32_t address);
#endif

@ -251,6 +251,7 @@ static usb_result_t bootloader_usb_loop(const vendor_header *const vhdr,
}
static secbool check_vendor_header_lock(const vendor_header *const vhdr) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_OTP);
uint8_t lock[FLASH_OTP_BLOCK_SIZE];
ensure(flash_otp_read(FLASH_OTP_BLOCK_VENDOR_HEADER_LOCK, 0, lock,
FLASH_OTP_BLOCK_SIZE),
@ -260,10 +261,12 @@ static secbool check_vendor_header_lock(const vendor_header *const vhdr) {
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
FLASH_OTP_BLOCK_SIZE)) {
mpu_restore(mpu_mode);
return sectrue;
}
uint8_t hash[32];
vendor_header_hash(vhdr, hash);
mpu_restore(mpu_mode);
return sectrue * (0 == memcmp(lock, hash, 32));
}
@ -338,7 +341,8 @@ void real_jump_to_firmware(void) {
ensure_compatible_settings();
#endif
mpu_config_off();
mpu_reconfig(MPU_MODE_DISABLED);
jump_to(IMAGE_CODE_ALIGN(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE));
}
@ -398,8 +402,6 @@ int bootloader_main(void) {
ui_screen_boot_stage_1(false);
mpu_config_bootloader();
fault_handlers_init();
#ifdef TREZOR_EMULATOR

@ -215,8 +215,6 @@ int main(void) {
hash_processor_init();
#endif
mpu_config_bootloader();
#if PRODUCTION
check_bootloader_version();
#endif
@ -296,7 +294,8 @@ int main(void) {
// do not check any trust flags on header, proceed
mpu_config_off();
mpu_reconfig(MPU_MODE_DISABLED);
jump_to(IMAGE_CODE_ALIGN(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE));
return 0;

@ -176,15 +176,12 @@ int main(void) {
secbool secret_ok = secret_optiga_get(secret);
#endif
mpu_config_firmware_initial();
entropy_init();
#if PRODUCTION || BOOTLOADER_QA
check_and_replace_bootloader();
#endif
// Enable MPU
mpu_config_firmware();
#endif
// Init peripherals

@ -5,6 +5,7 @@
#include "common.h"
#include "flash.h"
#include "model.h"
#include "mpu.h"
bool translations_write(const uint8_t* data, uint32_t offset, uint32_t len) {
uint32_t size = translations_area_bytesize();
@ -12,12 +13,17 @@ bool translations_write(const uint8_t* data, uint32_t offset, uint32_t len) {
return false;
}
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_ASSETS);
ensure(flash_unlock_write(), "translations_write unlock");
// todo consider alignment
ensure(flash_area_write_data_padded(&TRANSLATIONS_AREA, offset, data, len,
0xFF, FLASH_ALIGN(len)),
"translations_write write");
ensure(flash_lock_write(), "translations_write lock");
mpu_restore(mpu_mode);
return true;
}
@ -30,7 +36,9 @@ const uint8_t* translations_read(uint32_t* len, uint32_t offset) {
}
void translations_erase(void) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_ASSETS);
ensure(flash_area_erase(&TRANSLATIONS_AREA, NULL), "translations erase");
mpu_restore(mpu_mode);
}
uint32_t translations_area_bytesize(void) {

@ -2,6 +2,7 @@
#include "flash_otp.h"
#include "model.h"
#include "mpu.h"
#include "unit_variant.h"
#include TREZOR_BOARD
@ -51,6 +52,8 @@ static int16_t unit_variant_get_build_year(void) {
}
void unit_variant_init(void) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_OTP);
uint8_t data[FLASH_OTP_BLOCK_SIZE];
secbool result = flash_otp_read(FLASH_OTP_BLOCK_DEVICE_VARIANT, 0, data,
@ -67,6 +70,8 @@ void unit_variant_init(void) {
break;
}
}
mpu_restore(mpu_mode);
}
uint8_t unit_variant_get_color(void) { return unit_variant_color; }

@ -813,15 +813,12 @@ int main(void) {
uint32_t bootloader_version = read_bootloader_version();
const boardloader_version_t *boardloader_version = read_boardloader_version();
mpu_config_prodtest_initial();
#ifdef USE_OPTIGA
optiga_init();
optiga_open_application();
pair_optiga();
#endif
mpu_config_prodtest();
fault_handlers_init();
display_clear();

@ -17,15 +17,48 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __MPU_H__
#define __MPU_H__
#ifndef TREZORHAL_MPU_H
#define TREZORHAL_MPU_H
void mpu_config_off(void);
void mpu_config_boardloader(void);
void mpu_config_bootloader(void);
void mpu_config_firmware_initial(void);
void mpu_config_firmware(void);
void mpu_config_prodtest_initial(void);
void mpu_config_prodtest(void);
// The MPU driver can be set to on of the following modes.
//
// In each mode, the MPU is configured to allow access to specific
// memory regions.
//
// The `MPU_MODE_DEFAULT` mode is the most restrictive and serves as
// a base for other modes.
typedef enum {
MPU_MODE_DISABLED, // MPU is disabled
MPU_MODE_DEFAULT, // Default
MPU_MODE_BOARDCAPS, // + boardloader capabilities (privileged RO)
MPU_MODE_BOOTUPDATE, // + bootloader area (privileged RW)
MPU_MODE_OTP, // + OTP (privileged RW)
MPU_MODE_FSMC_REGS, // + FSMC control registers (privileged RW)
MPU_MODE_FLASHOB, // + Option bytes mapping (privileged RW)
MPU_MODE_SECRET, // + secret area (priviledeg RW)
MPU_MODE_STORAGE, // + both storage areas (privilehed RW)
MPU_MODE_ASSETS, // + assets (privileged RW)
MPU_MODE_APP, // + unprivileged DMA2D (RW) & Assets (RO)
} mpu_mode_t;
#endif
// Initializes the MPU and sets it to MPU_MODE_DISABLED.
//
// This function should be called before any other MPU function.
void mpu_init(void);
// Returns the current MPU mode.
//
// If the MPU is not initialized, returns MPU_MODE_DISABLED.
mpu_mode_t mpu_get_mode(void);
// Reconfigures the MPU to the given mode and returns the previous mode.
//
// If the MPU is not initialized, does nothing and returns MPU_MODE_DISABLED.
mpu_mode_t mpu_reconfig(mpu_mode_t mode);
// Restores the MPU to the given mode.
//
// Same as `mpu_reconfig()`, but with a more descriptive name.
void mpu_restore(mpu_mode_t mode);
#endif // TREZORHAL_MPU_H

@ -17,10 +17,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "board_capabilities.h"
#include <string.h>
#include "board_capabilities.h"
#include "common.h"
#include "model.h"
#include "mpu.h"
static uint32_t board_name = 0;
@ -33,11 +35,14 @@ const boardloader_version_t *get_boardloader_version() {
}
void parse_boardloader_capabilities() {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_BOARDCAPS);
const uint8_t *pos = (const uint8_t *)BOARD_CAPABILITIES_ADDR;
const uint8_t *end =
(const uint8_t *)(BOARD_CAPABILITIES_ADDR + BOARD_CAPABILITIES_SIZE);
if (memcmp(pos, CAPABILITIES_HEADER, 4) != 0) {
mpu_restore(mpu_mode);
return;
}
@ -70,6 +75,7 @@ void parse_boardloader_capabilities() {
memcpy(&boardloader_version, pos, length);
break;
case TAG_TERMINATOR:
mpu_restore(mpu_mode);
return;
default:
break;
@ -77,4 +83,6 @@ void parse_boardloader_capabilities() {
pos += length;
}
mpu_restore(mpu_mode);
}

@ -91,7 +91,9 @@ reboot_with_args(boot_command_t command, const void* args, size_t args_size) {
#ifdef ENSURE_COMPATIBLE_SETTINGS
ensure_compatible_settings();
#endif
mpu_config_bootloader();
mpu_reconfig(MPU_MODE_DISABLED);
jump_to_with_flag(BOOTLOADER_START + IMAGE_HEADER_SIZE, g_boot_command);
for (;;)
;

@ -22,6 +22,7 @@
#include "entropy.h"
#include "flash_otp.h"
#include "model.h"
#include "mpu.h"
#include "rand.h"
#include "stm32f4xx_ll_utils.h"
@ -29,6 +30,8 @@
static uint8_t g_hw_entropy[HW_ENTROPY_LEN];
void entropy_init(void) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_OTP);
// collect entropy from UUID
uint32_t w = LL_GetUID_Word0();
memcpy(g_hw_entropy, &w, 4);
@ -50,6 +53,8 @@ void entropy_init(void) {
ensure(flash_otp_read(FLASH_OTP_BLOCK_RANDOMNESS, 0, g_hw_entropy + 12,
FLASH_OTP_BLOCK_SIZE),
NULL);
mpu_restore(mpu_mode);
}
void entropy_get(uint8_t *buf) { memcpy(buf, g_hw_entropy, HW_ENTROPY_LEN); }

@ -20,6 +20,9 @@
#include STM32_HAL_H
#include "lowlevel.h"
#include <mpu.h>
#include "flash_otp.h"
#pragma GCC optimize( \
@ -80,19 +83,27 @@ secbool flash_check_option_bytes(void) {
if (FLASH->OPTCR1 != FLASH_OPTCR1_nWRP) {
return secfalse;
}
mpu_mode_t mode = mpu_reconfig(MPU_MODE_FLASHOB);
// check values stored in flash memory
if ((OPTION_BYTES_RDP_USER & ~3) !=
OPTION_BYTES_RDP_USER_VALUE) { // bits 0 and 1 are unused
mpu_reconfig(mode);
return secfalse;
}
if ((OPTION_BYTES_BANK1_WRP & 0xCFFFU) !=
OPTION_BYTES_BANK1_WRP_VALUE) { // bits 12 and 13 are unused
mpu_reconfig(mode);
return secfalse;
}
if ((OPTION_BYTES_BANK2_WRP & 0xFFFU) !=
OPTION_BYTES_BANK2_WRP_VALUE) { // bits 12, 13, 14, and 15 are unused
mpu_reconfig(mode);
return secfalse;
}
mpu_reconfig(mode);
return sectrue;
}

@ -20,6 +20,7 @@
#include "monoctr.h"
#include "flash_otp.h"
#include "model.h"
#include "mpu.h"
#include "string.h"
#if PRODUCTION
@ -70,7 +71,9 @@ secbool monoctr_write(monoctr_type_t type, uint8_t value) {
}
}
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_OTP);
ensure(flash_otp_write(block, 0, bits, FLASH_OTP_BLOCK_SIZE), NULL);
mpu_restore(mpu_mode);
#endif
return sectrue;
@ -86,7 +89,9 @@ secbool monoctr_read(monoctr_type_t type, uint8_t* value) {
return secfalse;
}
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_OTP);
ensure(flash_otp_read(block, 0, bits, FLASH_OTP_BLOCK_SIZE), NULL);
mpu_restore(mpu_mode);
int result = 0;

@ -19,20 +19,44 @@
#include STM32_HAL_H
#include TREZOR_BOARD
#include <stdbool.h>
#include <stdint.h>
#include "irq.h"
#include "model.h"
#include "mpu.h"
#include "stm32f4xx_ll_cortex.h"
// http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BABDJJGF.html
#define MPU_RASR_ATTR_FLASH (MPU_RASR_C_Msk)
#define MPU_RASR_ATTR_SRAM (MPU_RASR_C_Msk | MPU_RASR_S_Msk)
#define MPU_RASR_ATTR_PERIPH (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
#define MPU_RASR_ATTR_FLASH_CODE (MPU_RASR_C_Msk)
#define MPU_RASR_ATTR_FLASH_DATA (MPU_RASR_C_Msk | MPU_RASR_XN_Msk)
#define MPU_RASR_ATTR_SRAM (MPU_RASR_C_Msk | MPU_RASR_S_Msk | MPU_RASR_XN_Msk)
#define MPU_RASR_ATTR_PERIPH (MPU_RASR_B_Msk | MPU_RASR_S_Msk | MPU_RASR_XN_Msk)
#define SET_REGION(region, start, size, mask, attr, access) \
do { \
uint32_t _enable = MPU_RASR_ENABLE_Msk; \
uint32_t _size = LL_MPU_REGION_##size; \
uint32_t _mask = (mask) << MPU_RASR_SRD_Pos; \
uint32_t _attr = MPU_RASR_ATTR_##attr; \
uint32_t _access = LL_MPU_REGION_##access; \
MPU->RNR = region; \
MPU->RBAR = (start) & ~0x1F; \
MPU->RASR = _enable | _size | _mask | _attr | _access; \
} while (0)
#define DIS_REGION(region) \
do { \
MPU->RNR = region; \
MPU->RBAR = 0; \
MPU->RASR = 0; \
} while (0)
/*
#define MPU_SUBREGION_DISABLE(X) ((X) << MPU_RASR_SRD_Pos)
void mpu_config_off(void) {
// Disable MPU
HAL_MPU_Disable();
}
void mpu_config_boardloader(void) {
// nothing to be done
}
@ -103,7 +127,8 @@ void mpu_config_bootloader(void) {
// Enable MPU
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
*/
/*
void mpu_config_firmware_initial(void) {}
void mpu_config_firmware(void) {
@ -111,14 +136,14 @@ void mpu_config_firmware(void) {
HAL_MPU_Disable();
// Note: later entries overwrite previous ones
/*
// Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never)
MPU->RBAR = FLASH_BASE | MPU_REGION_NUMBER0;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO | MPU_RASR_XN_Msk;
*/
*/
/*
// Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never)
MPU->RBAR = FLASH_BASE | MPU_REGION_NUMBER0;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO | MPU_RASR_XN_Msk;
*/
/*
// Bootloader (0x08020000 - 0x0803FFFF, 128 KiB, read-only)
MPU->RNR = MPU_REGION_NUMBER0;
MPU->RBAR = FLASH_BASE + 0x20000;
@ -308,3 +333,264 @@ void mpu_config_prodtest(void) {
__asm__ volatile("dsb");
__asm__ volatile("isb");
}
*/
typedef struct {
// Set if the driver is initialized
bool initialized;
// Current mode
mpu_mode_t mode;
} mpu_driver_t;
mpu_driver_t g_mpu_driver = {
.initialized = false,
.mode = MPU_MODE_DISABLED,
};
static void mpu_init_fixed_regions(void) {
// Regions #0 to #4 are fixed for all targets
#ifdef BOARDLOADER
// clang-format off
// Code in the Flash Bank #1 (Unprivileged, Read-Only, Executable)
// Subregion: 48KB = 64KB except 2/8 at end
SET_REGION( 0, BOARDLOADER_START, SIZE_2MB, 0xC0, FLASH_CODE, PRIV_RO_URO );
DIS_REGION( 1 );
// All CCMRAM (Unprivileged, Read-Write, Non-Executable)
SET_REGION( 2, CCMDATARAM_BASE, SIZE_64KB, 0x00, SRAM, FULL_ACCESS );
// All SRAM (Unprivileged, Read-Write, Non-Executable)
// Subregion: 192KB = 256KB except 2/8 at end
SET_REGION( 3, SRAM_BASE, SIZE_256KB, 0xC0, SRAM, FULL_ACCESS );
// Kernel RAM (Privileged, Read-Write, Non-Executable)
// SET_REGION( 4, ..., SIZE_xxx, 0xXX, ATTR_SRAM, PRIV_RW );
DIS_REGION( 4 );
// clang-format on
#endif
#ifdef BOOTLOADER
// clang-format off
// Code in the Flash Bank #1 (Unprivileged, Read-Only, Executable)
// Subregion: 128KB = 1024KB except 2/8 at start
SET_REGION( 0, BOARDLOADER_START, SIZE_2MB, 0x00, FLASH_CODE, PRIV_RO_URO );
DIS_REGION( 1 );
// All CCMRAM (Unprivileged, Read-Write, Non-Executable)
SET_REGION( 2, CCMDATARAM_BASE, SIZE_64KB, 0x00, SRAM, FULL_ACCESS );
// All SRAM (Unprivileged, Read-Write, Non-Executable)
// Subregion: 192KB = 256KB except 2/8 at end
SET_REGION( 3, SRAM_BASE, SIZE_256KB, 0xC0, SRAM, FULL_ACCESS );
// Kernel RAM (Privileged, Read-Write, Non-Executable)
// SET_REGION( 4, ..., SIZE_xxx, 0xXX, ATTR_SRAM, PRIV_RW );
DIS_REGION( 4 );
// clang-format on
#endif
#ifdef KERNEL
// clang-format off
// Code in the Flash Bank #1 (Unprivileged, Read-Only, Executable)
// Subregion: 768KB = 1024KB except 2/8 at start
SET_REGION( 0, FLASH_BASE, SIZE_1MB, 0x03, FLASH_CODE, PRIV_RO_URO );
// Code in the Flash Bank #2 (Unprivileged, Read-Only, Executable)
// Subregion: 896KB = 1024KB except 1/8 at start
SET_REGION( 1, FLASH_BASE + 0x100000, SIZE_1MB, 0x01, FLASH_CODE, PRIV_RO_URO );
// All CCMRAM (Unprivileged, Read-Write, Non-Executable)
SET_REGION( 2, CCMDATARAM_BASE, SIZE_64KB, 0x00, SRAM, FULL_ACCESS );
// All SRAM (Unprivileged, Read-Write, Non-Executable)
// Subregion: 192KB = 256KB except 2/8 at end
SET_REGION( 3, SRAM_BASE, SIZE_256KB, 0xC0, SRAM, FULL_ACCESS );
// Kernel RAM (Privileged, Read-Write, Non-Executable)
// SET_REGION( 4, ..., SIZE_xxx, 0xXX, ATTR_SRAM, PRIV_RW );
DIS_REGION( 4 );
// clang-format on
#endif
#ifdef FIRMWARE
// TODO
#endif
#ifdef PRODTEST
// TODO
#endif
// Regions #5 to #7 are banked
DIS_REGION(5);
DIS_REGION(6);
DIS_REGION(7);
}
void mpu_init(void) {
mpu_driver_t* drv = &g_mpu_driver;
if (drv->initialized) {
return;
}
irq_key_t irq_key = irq_lock();
HAL_MPU_Disable();
mpu_init_fixed_regions();
drv->mode = MPU_MODE_DISABLED;
drv->initialized = true;
irq_unlock(irq_key);
}
mpu_mode_t mpu_get_mode(void) {
mpu_driver_t* drv = &g_mpu_driver;
if (!drv->initialized) {
return MPU_MODE_DISABLED;
}
return drv->mode;
}
// STM32F4xx memory map
//
// 0x08000000 2MB FLASH
// 0x10000000 64KB CCMRAM
// 0x1FFF7800 528B OTP
// 0x20000000 192KB SRAM
// 0x40000000 512MB PERIPH
// STM32F4xx flash layout
//
// 0x08000000 4x 16KB (BANK #1)
// 0x08010000 1x 64KB (BANK #1)
// 0x08020000 7x 128KB (BANK #1)
// 0x08100000 4x 16KB (BANK #2)
// 0x08110000 1x 64KB (BANK #3)
// 0x08120000 7x 128KB (BANK #4)
mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
mpu_driver_t* drv = &g_mpu_driver;
if (!drv->initialized) {
// Solves the issue when some IRQ handler tries to reconfigure
// MPU before it is initialized
return MPU_MODE_DISABLED;
}
irq_key_t irq_key = irq_lock();
HAL_MPU_Disable();
// Region #5 and #6 are banked
// clang-format off
switch (mode) {
case MPU_MODE_BOARDCAPS:
DIS_REGION( 5 );
// Boardloader (Privileged, Read-Only, Non-Executable)
// Subregion: 48KB = 64KB except 2/8 at end
SET_REGION( 6, FLASH_BASE, SIZE_64KB, 0xC0, FLASH_DATA, PRIV_RO );
break;
case MPU_MODE_BOOTUPDATE:
DIS_REGION( 5 );
// Bootloader (Privileged, Read-Write, Non-Executable)
SET_REGION( 6, FLASH_BASE + 0x20000, SIZE_128KB, 0x00, FLASH_DATA, PRIV_RW );
break;
case MPU_MODE_OTP:
DIS_REGION( 5 );
// OTP (Privileged, Read-Write, Non-Executable)
SET_REGION( 6, FLASH_OTP_BASE, SIZE_1KB, 0x00, FLASH_DATA, FULL_ACCESS );
break;
case MPU_MODE_FSMC_REGS:
DIS_REGION( 5 );
// FSMC Control Registers (Privileged, Read-Write, Non-Executable)
// 0xA0000000 = FMSC_R_BASE (not defined in used headers)
SET_REGION( 6, 0xA0000000, SIZE_4KB, 0x00, FLASH_DATA, FULL_ACCESS );
break;
case MPU_MODE_FLASHOB:
SET_REGION( 5, 0x1FFFC000, SIZE_1KB, 0x00, FLASH_DATA, PRIV_RO );
SET_REGION( 6, 0x1FFEC000, SIZE_1KB, 0x00, FLASH_DATA, PRIV_RO );
break;
#ifdef USE_OPTIGA
// with optiga, we use the secret sector, and assets area is smaller
case MPU_MODE_SECRET:
DIS_REGION( 5 );
// Secret sector in Bank #2 (Privileged, Read-Write, Non-Executable)
SET_REGION( 6, FLASH_BASE + 0x100000, SIZE_16KB, 0x00, FLASH_DATA, PRIV_RW );
break;
case MPU_MODE_ASSETS:
DIS_REGION( 5 );
// Assets (Privileged, Read-Write, Non-Executable)
SET_REGION( 6, FLASH_BASE + 0x108000, SIZE_32KB, 0x00, FLASH_DATA, PRIV_RW );
break;
case MPU_MODE_APP:
// Unused (maybe privileged kernel code in the future)
DIS_REGION( 5 );
// Assets (Unprivileged, Read-Only, Non-Executable)
SET_REGION( 6, FLASH_BASE + 0x108000, SIZE_32KB, 0x00, FLASH_DATA, PRIV_RO_URO );
break;
#else
// without optiga, we use additional sector for assets area
case MPU_MODE_ASSETS:
DIS_REGION( 5 );
// Assets (Privileged, Read-Write, Non-Executable)
// Subregion: 48KB = 64KB except 2/8 at end
SET_REGION( 6, FLASH_BASE + 0x100000, SIZE_64KB, 0xC0, FLASH_DATA, PRIV_RW );
break;
case MPU_MODE_APP:
// Unused (maybe privileged kernel code in the future)
DIS_REGION( 5 );
// Assets (Unprivileged, Read-Only, Non-Executable)
// Subregion: 48KB = 64KB except 2/8 at end
SET_REGION( 6, FLASH_BASE + 0x100000, SIZE_64KB, 0xC0, FLASH_DATA, PRIV_RO_URO );
break;
#endif
case MPU_MODE_STORAGE:
// Storage in the Flash Bank #1 (Privileged, Read-Write, Non-Executable)
SET_REGION( 5, FLASH_BASE + 0x10000, SIZE_64KB, 0x00, FLASH_DATA, PRIV_RW );
// Storage in the Flash Bank #2 (Privileged, Read-Write, Non-Executable)
SET_REGION( 6, FLASH_BASE + 0x110000, SIZE_64KB, 0x00, FLASH_DATA, PRIV_RW );
break;
case MPU_MODE_DEFAULT:
default:
DIS_REGION( 5 );
DIS_REGION( 6 );
break;
}
// clang-format on
// Region #7 is banked
// clang-format off
switch (mode) {
case MPU_MODE_APP:
// Dma2D (Unprivileged, Read-Write, Non-Executable)
// 3KB = 4KB except 1/4 at end
SET_REGION( 7, 0x4002B000, SIZE_4KB, 0xC0, PERIPH, FULL_ACCESS );
break;
default:
// All Peripherals (Privileged, Read-Write, Non-Executable)
SET_REGION( 7, PERIPH_BASE, SIZE_1GB, 0x00, PERIPH, PRIV_RW );
break;
}
// clang-format on
if (mode != MPU_MODE_DISABLED) {
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
mpu_mode_t prev_mode = drv->mode;
drv->mode = mode;
irq_unlock(irq_key);
return prev_mode;
}
void mpu_restore(mpu_mode_t mode) { mpu_reconfig(mode); }

@ -4,6 +4,7 @@
#include "display_draw.h"
#include "flash.h"
#include "model.h"
#include "mpu.h"
#ifdef FANCY_FATAL_ERROR
#include "rust_ui.h"
@ -20,10 +21,15 @@ secbool secret_verify_header(void) {
return secfalse;
}
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
bootloader_locked =
memcmp(addr, SECRET_HEADER_MAGIC, sizeof(SECRET_HEADER_MAGIC)) == 0
? sectrue
: secfalse;
mpu_restore(mpu_mode);
bootloader_locked_set = sectrue;
return bootloader_locked;
}
@ -44,12 +50,14 @@ void secret_write_header(void) {
}
void secret_write(const uint8_t* data, uint32_t offset, uint32_t len) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
ensure(flash_unlock_write(), "secret write");
for (int i = 0; i < len; i++) {
ensure(flash_area_write_byte(&SECRET_AREA, offset + i, data[i]),
"secret write");
}
ensure(flash_lock_write(), "secret write");
mpu_restore(mpu_mode);
}
secbool secret_read(uint8_t* data, uint32_t offset, uint32_t len) {
@ -63,28 +71,40 @@ secbool secret_read(uint8_t* data, uint32_t offset, uint32_t len) {
return secfalse;
}
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
memcpy(data, addr, len);
mpu_restore(mpu_mode);
return sectrue;
}
secbool secret_wiped(void) {
uint32_t size = flash_area_get_size(&SECRET_AREA);
secbool wiped = sectrue;
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
for (int i = 0; i < size; i += 4) {
uint32_t* addr = (uint32_t*)flash_area_get_address(&SECRET_AREA, i, 4);
if (addr == NULL) {
return secfalse;
wiped = secfalse;
break;
}
if (*addr != 0xFFFFFFFF) {
return secfalse;
wiped = secfalse;
break;
}
}
return sectrue;
mpu_restore(mpu_mode);
return wiped;
}
void secret_erase(void) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
ensure(flash_area_erase(&SECRET_AREA, NULL), "secret erase");
mpu_restore(mpu_mode);
}
secbool secret_optiga_set(const uint8_t secret[SECRET_OPTIGA_KEY_LEN]) {

@ -22,6 +22,7 @@
#include "display_io.h"
#include "irq.h"
#include "mpu.h"
__IO DISP_MEM_TYPE *const DISPLAY_CMD_ADDRESS =
(__IO DISP_MEM_TYPE *const)((uint32_t)DISPLAY_MEMORY_BASE);
@ -127,7 +128,9 @@ void display_io_init_fmc(void) {
normal_mode_timing.DataLatency = 2; // don't care
normal_mode_timing.AccessMode = FMC_ACCESS_MODE_A;
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_FSMC_REGS);
HAL_SRAM_Init(&external_display_data_sram, &normal_mode_timing, NULL);
mpu_restore(mpu_mode);
}
#ifdef DISPLAY_TE_INTERRUPT_HANDLER

@ -22,6 +22,7 @@
#include "entropy.h"
#include "flash_otp.h"
#include "model.h"
#include "mpu.h"
#include "rand.h"
#include "stm32u5xx_ll_utils.h"
@ -29,6 +30,8 @@
static uint8_t g_hw_entropy[HW_ENTROPY_LEN];
void entropy_init(void) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_OTP);
// collect entropy from UUID
uint32_t w = LL_GetUID_Word0();
memcpy(g_hw_entropy, &w, 4);
@ -50,6 +53,8 @@ void entropy_init(void) {
ensure(flash_otp_read(FLASH_OTP_BLOCK_RANDOMNESS, 0, g_hw_entropy + 12,
FLASH_OTP_BLOCK_SIZE),
NULL);
mpu_restore(mpu_mode);
}
void entropy_get(uint8_t *buf) { memcpy(buf, g_hw_entropy, HW_ENTROPY_LEN); }

@ -20,6 +20,7 @@
#include "monoctr.h"
#include "flash_area.h"
#include "model.h"
#include "mpu.h"
#include "secret.h"
static int32_t get_offset(monoctr_type_t type) {
@ -80,6 +81,8 @@ secbool monoctr_read(monoctr_type_t type, uint8_t *value) {
return secfalse;
}
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
int counter = 0;
int i = 0;
@ -111,10 +114,13 @@ secbool monoctr_read(monoctr_type_t type, uint8_t *value) {
if (not_cleared != sectrue) {
// monotonic counter is not valid
mpu_restore(mpu_mode);
return secfalse;
}
}
mpu_restore(mpu_mode);
if (value != NULL) {
*value = counter;
} else {

@ -19,8 +19,11 @@
#include STM32_HAL_H
#include <stdbool.h>
#include "common.h"
#include "model.h"
#include "mpu.h"
#include "stm32u5xx_ll_cortex.h"
// region type
@ -152,106 +155,192 @@ static void mpu_set_attributes(void) {
#define OTP_AND_ID_SIZE 0x800
void mpu_config_boardloader(void) {
HAL_MPU_Disable();
mpu_set_attributes();
// clang-format on
#define KERNEL_RAM_START (SRAM2_BASE - SIZE_16K)
#define KERNEL_RAM_SIZE (SIZE_24K)
#define COREAPP_RAM1_START SRAM1_BASE
#define COREAPP_RAM1_SIZE (SIZE_192K - SIZE_16K)
#define COREAPP_RAM2_START (SRAM2_BASE + SIZE_8K)
#define COREAPP_RAM2_SIZE (SRAM_SIZE - (SIZE_192K + SIZE_8K))
typedef struct {
// Set if the driver is initialized
bool initialized;
// Current mode
mpu_mode_t mode;
} mpu_driver_t;
mpu_driver_t g_mpu_driver = {
.initialized = false,
.mode = MPU_MODE_DISABLED,
};
static void mpu_init_fixed_regions(void) {
// Regions #0 to #5 are fixed for all targets
// clang-format off
#if defined(BOARDLOADER)
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, BOARDLOADER_START, BOARDLOADER_SIZE, FLASH_CODE, NO, NO );
SET_REGION( 1, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO );
DIS_REGION( 2 );
DIS_REGION( 3 );
DIS_REGION( 4 );
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
#endif
#if defined(BOOTLOADER)
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, BOOTLOADER_START, BOOTLOADER_SIZE, FLASH_CODE, NO, NO );
SET_REGION( 1, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO );
DIS_REGION( 2 );
DIS_REGION( 3 );
DIS_REGION( 4 );
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
#endif
#if defined(KERNEL)
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, SECRET_START, SECRET_SIZE, FLASH_DATA, YES, NO ); // Secret
SET_REGION( 1, BOARDLOADER_START, BOARDLOADER_SIZE, FLASH_CODE, NO, NO ); // Boardloader code
SET_REGION( 2, BOOTLOADER_START, L1_REST_SIZE, FLASH_DATA, YES, NO ); // Bootloader + Storage + Firmware
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO ); // SRAM1/2/3/5
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO ); // Frame buffer or display interface
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, NO ); // Peripherals
SET_REGION( 0, KERNEL_START, KERNEL_SIZE, FLASH_CODE, NO, NO );
SET_REGION( 1, KERNEL_RAM_START, KERNEL_RAM_SIZE, SRAM, YES, NO );
SET_REGION( 2, COREAPP_START, COREAPP_SIZE, FLASH_CODE, NO, YES );
SET_REGION( 3, COREAPP_RAM1_START, COREAPP_RAM1_SIZE, SRAM, YES, YES );
SET_REGION( 4, COREAPP_RAM2_START, COREAPP_RAM2_SIZE, SRAM, YES, YES );
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES );
#endif
#if defined(FIRMWARE)
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, NO );
SET_REGION( 1, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO );
DIS_REGION( 2 );
DIS_REGION( 3 );
DIS_REGION( 4 );
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
#endif
#if defined(PRODTEST)
SET_REGION( 0, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, NO );
SET_REGION( 1, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO );
DIS_REGION( 2 );
DIS_REGION( 3 );
DIS_REGION( 4 );
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
#endif
// Regions #6 and #7 are banked
DIS_REGION( 6 );
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, NO ); // SRAM4
DIS_REGION( 7 );
// clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
void mpu_config_bootloader(void) {
HAL_MPU_Disable();
mpu_set_attributes();
// clang-format off
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, SECRET_START, L2_PREV_SIZE, FLASH_DATA, YES, NO ); // Secret + Boardloader
SET_REGION( 1, BOOTLOADER_START, BOOTLOADER_SIZE, FLASH_CODE, NO, NO ); // Bootloader code
SET_REGION( 2, STORAGE_START, L2_REST_SIZE, FLASH_DATA, YES, NO ); // Storage + Firmware
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO ); // SRAM1/2/3/5
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO ); // Frame buffer or display interface
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, NO ); // Peripherals
SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, NO ); // OTP
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, NO ); // SRAM4
// clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
void mpu_init(void) {
mpu_driver_t* drv = &g_mpu_driver;
if (drv->initialized) {
return;
}
irq_key_t irq_key = irq_lock();
void mpu_config_firmware_initial(void) {
HAL_MPU_Disable();
mpu_set_attributes();
// clang-format off
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, BOOTLOADER_START, L3_PREV_SIZE_BLD, FLASH_DATA, YES, YES ); // Bootloader + Storage
SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, YES ); // Firmware
SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals
SET_REGION( 6, FLASH_OTP_BASE, SIZE_2K, FLASH_DATA, YES, YES ); // OTP
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4
// clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
mpu_init_fixed_regions();
drv->mode = MPU_MODE_DISABLED;
drv->initialized = true;
irq_unlock(irq_key);
}
void mpu_config_firmware(void) {
HAL_MPU_Disable();
mpu_set_attributes();
// clang-format off
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, STORAGE_START, STORAGE_SIZE, FLASH_DATA, YES, YES ); // Storage
SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, YES ); // Firmware
SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals
SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, YES ); // OTP
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4
// clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
mpu_mode_t mpu_get_mode(void) {
mpu_driver_t* drv = &g_mpu_driver;
if (!drv->initialized) {
return MPU_MODE_DISABLED;
}
return drv->mode;
}
void mpu_config_prodtest_initial(void) {
mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
mpu_driver_t* drv = &g_mpu_driver;
if (!drv->initialized) {
// Solves the issue when some IRQ handler tries to reconfigure
// MPU before it is initialized
return MPU_MODE_DISABLED;
}
irq_key_t irq_key = irq_lock();
HAL_MPU_Disable();
mpu_set_attributes();
// Region #6 is banked
// clang-format off
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, FLASH_BASE, L3_PREV_SIZE, FLASH_DATA, YES, YES ); // Secret, Bld, Storage
SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, YES ); // Firmware
SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals
SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, YES ); // OTP
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4
switch (mode) {
case MPU_MODE_DISABLED:
break;
case MPU_MODE_BOARDCAPS:
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 6, BOARDLOADER_START, BOARDLOADER_SIZE, FLASH_DATA, NO, NO );
break;
case MPU_MODE_BOOTUPDATE:
SET_REGION( 6, BOOTLOADER_START, BOOTLOADER_SIZE, FLASH_DATA, YES, NO );
break;
case MPU_MODE_OTP:
SET_REGION( 6, FLASH_OTP_BASE, OTP_AND_ID_SIZE, FLASH_DATA, NO, NO );
break;
case MPU_MODE_SECRET:
SET_REGION( 6, SECRET_START, SECRET_SIZE, FLASH_DATA, YES, NO );
break;
case MPU_MODE_STORAGE:
SET_REGION( 6, STORAGE_START, STORAGE_SIZE, FLASH_DATA, YES, NO );
break;
case MPU_MODE_ASSETS:
SET_REGION( 6, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, NO );
break;
case MPU_MODE_APP:
SET_REGION( 6, ASSETS_START, ASSETS_SIZE, FLASH_DATA, NO, YES );
break;
case MPU_MODE_DEFAULT:
case MPU_MODE_FSMC_REGS:
default:
DIS_REGION( 6 );
break;
}
// clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
void mpu_config_prodtest(void) {
HAL_MPU_Disable();
mpu_set_attributes();
// Region #7 is banked
// clang-format off
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, STORAGE_START, STORAGE_SIZE, FLASH_DATA, YES, YES ); // Storage
SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, YES, YES ); // Firmware
SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals
SET_REGION( 6, FLASH_OTP_BASE, OTP_AND_ID_SIZE, FLASH_DATA, YES, YES ); // OTP + device ID
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4
switch (mode) {
case MPU_MODE_APP:
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
// DMA2D peripherals (Uprivileged, Read-Write, Non-Executable)
SET_REGION( 7, 0x5002B000, SIZE_3K, PERIPHERAL, YES, YES );
break;
default:
// All peripherals (Pivileged, Read-Write, Non-Executable)
SET_REGION( 7, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, NO );
break;
}
// clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
if (mode != MPU_MODE_DISABLED) {
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
mpu_mode_t prev_mode = drv->mode;
drv->mode = mode;
irq_unlock(irq_key);
return prev_mode;
}
void mpu_config_off(void) { HAL_MPU_Disable(); }
void mpu_restore(mpu_mode_t mode) { mpu_reconfig(mode); }

@ -6,6 +6,7 @@
#include "flash.h"
#include "memzero.h"
#include "model.h"
#include "mpu.h"
#include "rng.h"
#include "secure_aes.h"
@ -19,17 +20,25 @@ secbool secret_verify_header(void) {
return secfalse;
}
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
bootloader_locked =
memcmp(addr, SECRET_HEADER_MAGIC, sizeof(SECRET_HEADER_MAGIC)) == 0
? sectrue
: secfalse;
mpu_restore(mpu_mode);
return bootloader_locked;
}
secbool secret_ensure_initialized(void) {
if (sectrue != secret_verify_header()) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_STORAGE);
ensure(flash_area_erase_bulk(STORAGE_AREAS, STORAGE_AREAS_COUNT, NULL),
"erase storage failed");
mpu_restore(mpu_mode);
secret_erase();
secret_write_header();
return secfalse;
@ -58,6 +67,7 @@ void secret_write_header(void) {
}
void secret_write(const uint8_t *data, uint32_t offset, uint32_t len) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
ensure(flash_unlock_write(), "secret write");
for (int i = 0; i < len / 16; i++) {
ensure(flash_area_write_quadword(&SECRET_AREA, offset + (i * 16),
@ -65,6 +75,7 @@ void secret_write(const uint8_t *data, uint32_t offset, uint32_t len) {
"secret write");
}
ensure(flash_lock_write(), "secret write");
mpu_restore(mpu_mode);
}
secbool secret_read(uint8_t *data, uint32_t offset, uint32_t len) {
@ -76,7 +87,10 @@ secbool secret_read(uint8_t *data, uint32_t offset, uint32_t len) {
if (addr == NULL) {
return secfalse;
}
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
memcpy(data, addr, len);
mpu_restore(mpu_mode);
return sectrue;
}
@ -106,6 +120,8 @@ static secbool secret_present(uint32_t offset, uint32_t len) {
return secfalse;
}
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
int secret_empty_bytes = 0;
for (int i = 0; i < len; i++) {
@ -115,6 +131,9 @@ static secbool secret_present(uint32_t offset, uint32_t len) {
secret_empty_bytes++;
}
}
mpu_restore(mpu_mode);
return sectrue * (secret_empty_bytes != len);
}
@ -152,6 +171,8 @@ static void secret_bhk_load(void) {
}
void secret_bhk_regenerate(void) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
ensure(flash_area_erase(&BHK_AREA, NULL), "Failed regenerating BHK");
ensure(flash_unlock_write(), "Failed regenerating BHK");
for (int i = 0; i < 2; i++) {
@ -164,6 +185,9 @@ void secret_bhk_regenerate(void) {
memzero(val, sizeof(val));
ensure(res, "Failed regenerating BHK");
}
mpu_restore(mpu_mode);
ensure(flash_lock_write(), "Failed regenerating BHK");
}
@ -187,6 +211,8 @@ secbool secret_optiga_writable(void) {
return secfalse;
}
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
int secret_empty_bytes = 0;
for (int i = 0; i < len; i++) {
@ -196,6 +222,9 @@ secbool secret_optiga_writable(void) {
secret_empty_bytes++;
}
}
mpu_restore(mpu_mode);
return sectrue * (secret_empty_bytes == len);
}
@ -272,7 +301,9 @@ void secret_optiga_erase(void) {
}
void secret_erase(void) {
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SECRET);
ensure(flash_area_erase(&SECRET_AREA, NULL), "secret erase");
mpu_restore(mpu_mode);
}
void secret_prepare_fw(secbool allow_run_with_secret, secbool trust_all) {

@ -0,0 +1,30 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mpu.h"
void mpu_init(void) {
// MPU functions are not fully implemented in Emulator
}
mpu_mode_t mpu_get_mode(void) { return MPU_MODE_DISABLED; }
mpu_mode_t mpu_reconfig(mpu_mode_t mode) { return MPU_MODE_DISABLED; }
void mpu_restore(mpu_mode_t mode) {}
Loading…
Cancel
Save