mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-28 22:15:42 +00:00
feat(core): properly utilize trustzone in kernel and core app
[no changelog]
This commit is contained in:
parent
c0829ec364
commit
b174237684
@ -255,7 +255,7 @@ int main(void) {
|
|||||||
#ifdef STM32U5
|
#ifdef STM32U5
|
||||||
tamper_init();
|
tamper_init();
|
||||||
|
|
||||||
trustzone_init_boardloader();
|
tz_init_boardloader();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
secret_init();
|
secret_init();
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "systick.h"
|
#include "systick.h"
|
||||||
#include "tamper.h"
|
#include "tamper.h"
|
||||||
#include "touch.h"
|
#include "touch.h"
|
||||||
|
#include "trustzone.h"
|
||||||
#include "unit_properties.h"
|
#include "unit_properties.h"
|
||||||
|
|
||||||
#ifdef USE_OPTIGA
|
#ifdef USE_OPTIGA
|
||||||
@ -182,24 +183,26 @@ extern uint32_t _coreapp_clear_ram_1_size;
|
|||||||
|
|
||||||
// Initializes coreapp applet
|
// Initializes coreapp applet
|
||||||
static void coreapp_init(applet_t *applet) {
|
static void coreapp_init(applet_t *applet) {
|
||||||
applet_header_t *coreapp_header =
|
const uint32_t CODE1_START = COREAPP_CODE_ALIGN(KERNEL_START + KERNEL_SIZE);
|
||||||
(applet_header_t *)COREAPP_CODE_ALIGN(KERNEL_START + KERNEL_SIZE);
|
|
||||||
|
#ifdef FIRMWARE_P1_START
|
||||||
|
const uint32_t CODE1_END = FIRMWARE_P1_START + FIRMWARE_P1_MAXSIZE;
|
||||||
|
#else
|
||||||
|
const uint32_t CODE1_END = FIRMWARE_START + FIRMWARE_MAXSIZE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
applet_header_t *coreapp_header = (applet_header_t *)CODE1_START;
|
||||||
|
|
||||||
applet_layout_t coreapp_layout = {
|
applet_layout_t coreapp_layout = {
|
||||||
.data1.start = (uint32_t)&_coreapp_clear_ram_0_start,
|
.data1.start = (uint32_t)&_coreapp_clear_ram_0_start,
|
||||||
.data1.size = (uint32_t)&_coreapp_clear_ram_0_size,
|
.data1.size = (uint32_t)&_coreapp_clear_ram_0_size,
|
||||||
.data2.start = (uint32_t)&_coreapp_clear_ram_1_start,
|
.data2.start = (uint32_t)&_coreapp_clear_ram_1_start,
|
||||||
.data2.size = (uint32_t)&_coreapp_clear_ram_1_size,
|
.data2.size = (uint32_t)&_coreapp_clear_ram_1_size,
|
||||||
#ifdef FIRMWARE_P1_START
|
.code1.start = CODE1_START,
|
||||||
.code1.start = FIRMWARE_P1_START + KERNEL_SIZE,
|
.code1.size = CODE1_END - CODE1_START,
|
||||||
.code1.size = FIRMWARE_P1_MAXSIZE - KERNEL_SIZE,
|
#ifdef FIRMWARE_P2_START
|
||||||
.code2.start = FIRMWARE_P2_START,
|
.code2.start = FIRMWARE_P2_START,
|
||||||
.code2.size = FIRMWARE_P2_MAXSIZE,
|
.code2.size = FIRMWARE_P2_MAXSIZE,
|
||||||
#else
|
|
||||||
.code1.start = FIRMWARE_START + KERNEL_SIZE,
|
|
||||||
.code1.size = FIRMWARE_MAXSIZE - KERNEL_SIZE,
|
|
||||||
.code2.start = 0,
|
|
||||||
.code2.size = 0,
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -214,7 +217,8 @@ static void show_rsod(const systask_postmortem_t *pminfo) {
|
|||||||
|
|
||||||
// Reset and run the coreapp in RSOD mode
|
// Reset and run the coreapp in RSOD mode
|
||||||
if (applet_reset(&coreapp, 1, pminfo, sizeof(systask_postmortem_t))) {
|
if (applet_reset(&coreapp, 1, pminfo, sizeof(systask_postmortem_t))) {
|
||||||
systask_yield_to(&coreapp.task);
|
// Run the applet & wait for it to finish
|
||||||
|
applet_run(&coreapp);
|
||||||
|
|
||||||
if (coreapp.task.pminfo.reason == TASK_TERM_REASON_EXIT) {
|
if (coreapp.task.pminfo.reason == TASK_TERM_REASON_EXIT) {
|
||||||
// If the RSOD was shown successfully, proceed to shutdown
|
// If the RSOD was shown successfully, proceed to shutdown
|
||||||
@ -257,6 +261,11 @@ int main(void) {
|
|||||||
// Initialize system's core services
|
// Initialize system's core services
|
||||||
system_init(&kernel_panic);
|
system_init(&kernel_panic);
|
||||||
|
|
||||||
|
#ifdef STM32U5
|
||||||
|
// Configure unprivileged access for the coreapp
|
||||||
|
tz_init_kernel();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Initialize hardware drivers
|
// Initialize hardware drivers
|
||||||
drivers_init();
|
drivers_init();
|
||||||
|
|
||||||
@ -269,7 +278,8 @@ int main(void) {
|
|||||||
error_shutdown("Cannot start coreapp");
|
error_shutdown("Cannot start coreapp");
|
||||||
}
|
}
|
||||||
|
|
||||||
systask_yield_to(&coreapp.task);
|
// Run the applet & wait for it to finish
|
||||||
|
applet_run(&coreapp);
|
||||||
|
|
||||||
// Coreapp crashed, show RSOD
|
// Coreapp crashed, show RSOD
|
||||||
show_rsod(&coreapp.task.pminfo);
|
show_rsod(&coreapp.task.pminfo);
|
||||||
|
@ -75,13 +75,16 @@ void applet_init(applet_t* applet, applet_header_t* header,
|
|||||||
|
|
||||||
// Resets the applet and prepares it for execution from its entry point.
|
// Resets the applet and prepares it for execution from its entry point.
|
||||||
//
|
//
|
||||||
// Applet does not start immediately, it needs to be scheduled by
|
// Applet does not start immediately, it needs to be run by
|
||||||
// `systask_yield_to(&applet->task)` after calling this function.
|
// `applet_run()` after calling this function.
|
||||||
//
|
//
|
||||||
// Returns `true` if the applet was successfully reset.
|
// Returns `true` if the applet was successfully reset.
|
||||||
bool applet_reset(applet_t* applet, uint32_t cmd, const void* arg,
|
bool applet_reset(applet_t* applet, uint32_t cmd, const void* arg,
|
||||||
size_t arg_size);
|
size_t arg_size);
|
||||||
|
|
||||||
|
// Runs the applet and waits until it finishes.
|
||||||
|
void applet_run(applet_t* applet);
|
||||||
|
|
||||||
// Returns the currently active applet.
|
// Returns the currently active applet.
|
||||||
//
|
//
|
||||||
// Returns `NULL` if no applet is currently active.
|
// Returns `NULL` if no applet is currently active.
|
||||||
|
@ -17,12 +17,16 @@
|
|||||||
* 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 STM32_HAL_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "applet.h"
|
#include "applet.h"
|
||||||
|
#include "display.h"
|
||||||
#include "mpu.h"
|
#include "mpu.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
#include "systask.h"
|
#include "systask.h"
|
||||||
|
#include "trustzone.h"
|
||||||
|
|
||||||
#ifdef SYSCALL_DISPATCH
|
#ifdef SYSCALL_DISPATCH
|
||||||
|
|
||||||
@ -70,6 +74,33 @@ bool applet_reset(applet_t* applet, uint32_t cmd, const void* arg,
|
|||||||
arg3);
|
arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef STM32U5
|
||||||
|
// Sets unprivileged access to the applet memory regions
|
||||||
|
// and allows applet to use some specific peripherals.
|
||||||
|
static void applet_set_unpriv(applet_t* applet, bool unpriv) {
|
||||||
|
applet_layout_t* layout = &applet->layout;
|
||||||
|
|
||||||
|
tz_set_sram_unpriv(layout->data1.start, layout->data1.size, unpriv);
|
||||||
|
tz_set_sram_unpriv(layout->data2.start, layout->data2.size, unpriv);
|
||||||
|
tz_set_flash_unpriv(layout->code1.start, layout->code1.size, unpriv);
|
||||||
|
tz_set_flash_unpriv(layout->code2.start, layout->code2.size, unpriv);
|
||||||
|
|
||||||
|
display_set_unpriv_access(unpriv);
|
||||||
|
}
|
||||||
|
#endif // STM32U5
|
||||||
|
|
||||||
|
void applet_run(applet_t* applet) {
|
||||||
|
#ifdef STM32U5
|
||||||
|
applet_set_unpriv(applet, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
systask_yield_to(&applet->task);
|
||||||
|
|
||||||
|
#ifdef STM32U5
|
||||||
|
applet_set_unpriv(applet, false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
applet_t* applet_active(void) {
|
applet_t* applet_active(void) {
|
||||||
systask_t* task = systask_active();
|
systask_t* task = systask_active();
|
||||||
|
|
||||||
|
@ -33,7 +33,9 @@
|
|||||||
#include "gfx_bitblt.h"
|
#include "gfx_bitblt.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "mpu.h"
|
#include "mpu.h"
|
||||||
|
#include "sizedefs.h"
|
||||||
#include "systemview.h"
|
#include "systemview.h"
|
||||||
|
#include "trustzone.h"
|
||||||
|
|
||||||
#ifndef BOARDLOADER
|
#ifndef BOARDLOADER
|
||||||
#include "bg_copy.h"
|
#include "bg_copy.h"
|
||||||
@ -48,20 +50,47 @@
|
|||||||
// The following code supports only 1 or 2 frame buffers
|
// The following code supports only 1 or 2 frame buffers
|
||||||
_Static_assert(FRAME_BUFFER_COUNT == 1 || FRAME_BUFFER_COUNT == 2);
|
_Static_assert(FRAME_BUFFER_COUNT == 1 || FRAME_BUFFER_COUNT == 2);
|
||||||
|
|
||||||
|
// Hardware requires physical frame buffer alignment
|
||||||
|
#ifdef USE_TRUSTZONE
|
||||||
|
#define PHYSICAL_FRAME_BUFFER_ALIGNMENT TZ_SRAM_ALIGNMENT
|
||||||
|
#else
|
||||||
|
#define PHYSICAL_FRAME_BUFFER_ALIGNMENT 32
|
||||||
|
#endif
|
||||||
|
|
||||||
// Size of the physical frame buffer in bytes
|
// Size of the physical frame buffer in bytes
|
||||||
#define PHYSICAL_FRAME_BUFFER_SIZE (DISPLAY_RESX * DISPLAY_RESY * 2)
|
#define PHYSICAL_FRAME_BUFFER_SIZE \
|
||||||
|
ALIGN_UP_CONST(DISPLAY_RESX *DISPLAY_RESY * 2, \
|
||||||
|
PHYSICAL_FRAME_BUFFER_ALIGNMENT)
|
||||||
|
|
||||||
// Physical frame buffers in internal SRAM memory.
|
// Physical frame buffers in internal SRAM memory.
|
||||||
// Both frame buffers layes in the fixed addresses that
|
// Both frame buffers layes in the fixed addresses that
|
||||||
// are shared between bootloaders and the firmware.
|
// are shared between bootloaders and the firmware.
|
||||||
static __attribute__((section(".fb1")))
|
static
|
||||||
ALIGN_32BYTES(uint8_t physical_frame_buffer_0[PHYSICAL_FRAME_BUFFER_SIZE]);
|
__attribute__((section(".fb1"), aligned(PHYSICAL_FRAME_BUFFER_ALIGNMENT)))
|
||||||
|
uint8_t physical_frame_buffer_0[PHYSICAL_FRAME_BUFFER_SIZE];
|
||||||
|
|
||||||
#if (FRAME_BUFFER_COUNT > 1)
|
#if (FRAME_BUFFER_COUNT > 1)
|
||||||
static __attribute__((section(".fb2")))
|
static
|
||||||
ALIGN_32BYTES(uint8_t physical_frame_buffer_1[PHYSICAL_FRAME_BUFFER_SIZE]);
|
__attribute__((section(".fb2"), aligned(PHYSICAL_FRAME_BUFFER_ALIGNMENT)))
|
||||||
|
uint8_t physical_frame_buffer_1[PHYSICAL_FRAME_BUFFER_SIZE];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef STM32U5
|
||||||
|
void display_set_unpriv_access(bool unpriv) {
|
||||||
|
tz_set_sram_unpriv((uint32_t)physical_frame_buffer_0,
|
||||||
|
PHYSICAL_FRAME_BUFFER_SIZE, unpriv);
|
||||||
|
|
||||||
|
#if (FRAME_BUFFER_COUNT > 1)
|
||||||
|
tz_set_sram_unpriv((uint32_t)physical_frame_buffer_1,
|
||||||
|
PHYSICAL_FRAME_BUFFER_SIZE, unpriv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_DMA2D
|
||||||
|
tz_set_dma2d_unpriv(unpriv);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif // STM32U5
|
||||||
|
|
||||||
// Returns the pointer to the physical frame buffer (0.. FRAME_BUFFER_COUNT-1)
|
// Returns the pointer to the physical frame buffer (0.. FRAME_BUFFER_COUNT-1)
|
||||||
// Returns NULL if the framebuffer index is out of range.
|
// Returns NULL if the framebuffer index is out of range.
|
||||||
static uint8_t *get_fb_ptr(uint32_t index) {
|
static uint8_t *get_fb_ptr(uint32_t index) {
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include STM32_HAL_H
|
#include STM32_HAL_H
|
||||||
|
|
||||||
#include "mpu.h"
|
#include "mpu.h"
|
||||||
|
#include "sizedefs.h"
|
||||||
|
#include "trustzone.h"
|
||||||
#include "xdisplay.h"
|
#include "xdisplay.h"
|
||||||
|
|
||||||
#ifdef USE_CONSUMPTION_MASK
|
#ifdef USE_CONSUMPTION_MASK
|
||||||
@ -37,14 +39,23 @@
|
|||||||
#error "Incompatible display resolution"
|
#error "Incompatible display resolution"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Hardware requires physical frame buffer alignment
|
||||||
|
#ifdef USE_TRUSTZONE
|
||||||
|
#define PHYSICAL_FRAME_BUFFER_ALIGNMENT TZ_SRAM_ALIGNMENT
|
||||||
|
#else
|
||||||
|
#define PHYSICAL_FRAME_BUFFER_ALIGNMENT 4
|
||||||
|
#endif
|
||||||
|
|
||||||
// This file implements display driver for monochromatic display V-2864KSWEG01
|
// This file implements display driver for monochromatic display V-2864KSWEG01
|
||||||
// with 128x64 resolution connected to CPU via SPI interface.
|
// with 128x64 resolution connected to CPU via SPI interface.
|
||||||
//
|
//
|
||||||
// This type of display is used with T3B1 model (Trezor TS3)
|
// This type of display is used with T3B1 model (Trezor TS3)
|
||||||
|
#define FRAME_BUFFER_SIZE \
|
||||||
|
ALIGN_UP_CONST(DISPLAY_RESX *DISPLAY_RESY, PHYSICAL_FRAME_BUFFER_ALIGNMENT)
|
||||||
|
|
||||||
#define FRAME_BUFFER_SIZE (DISPLAY_RESX * DISPLAY_RESY)
|
static
|
||||||
|
__attribute__((section(".fb1"), aligned(PHYSICAL_FRAME_BUFFER_ALIGNMENT)))
|
||||||
__attribute__((section(".fb1"))) uint8_t g_framebuf[FRAME_BUFFER_SIZE];
|
uint8_t g_framebuf[FRAME_BUFFER_SIZE];
|
||||||
|
|
||||||
// Display driver context.
|
// Display driver context.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -316,6 +327,12 @@ void display_deinit(display_content_mode_t mode) {
|
|||||||
drv->initialized = false;
|
drv->initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef STM32U5
|
||||||
|
void display_set_unpriv_access(bool unpriv) {
|
||||||
|
tz_set_sram_unpriv((uint32_t)g_framebuf, FRAME_BUFFER_SIZE, unpriv);
|
||||||
|
}
|
||||||
|
#endif // STM32U5
|
||||||
|
|
||||||
int display_set_backlight(int level) {
|
int display_set_backlight(int level) {
|
||||||
display_driver_t *drv = &g_display_driver;
|
display_driver_t *drv = &g_display_driver;
|
||||||
|
|
||||||
|
@ -104,9 +104,9 @@ void bg_copy_start_const_out_8(const uint8_t *src, uint8_t *dst, size_t size,
|
|||||||
DMA_Handle.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
DMA_Handle.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||||
DMA_Handle.Init.Mode = DMA_NORMAL;
|
DMA_Handle.Init.Mode = DMA_NORMAL;
|
||||||
HAL_DMA_Init(&DMA_Handle);
|
HAL_DMA_Init(&DMA_Handle);
|
||||||
HAL_DMA_ConfigChannelAttributes(&DMA_Handle, DMA_CHANNEL_SEC |
|
HAL_DMA_ConfigChannelAttributes(
|
||||||
DMA_CHANNEL_SRC_SEC |
|
&DMA_Handle, DMA_CHANNEL_PRIV | DMA_CHANNEL_SEC | DMA_CHANNEL_SRC_SEC |
|
||||||
DMA_CHANNEL_DEST_SEC);
|
DMA_CHANNEL_DEST_SEC);
|
||||||
|
|
||||||
NVIC_SetPriority(GPDMA1_Channel0_IRQn, IRQ_PRI_NORMAL);
|
NVIC_SetPriority(GPDMA1_Channel0_IRQn, IRQ_PRI_NORMAL);
|
||||||
NVIC_EnableIRQ(GPDMA1_Channel0_IRQn);
|
NVIC_EnableIRQ(GPDMA1_Channel0_IRQn);
|
||||||
|
@ -81,9 +81,9 @@ void consumption_mask_init(void) {
|
|||||||
dma_handle.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
|
dma_handle.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
|
||||||
HAL_DMAEx_List_Init(&dma_handle);
|
HAL_DMAEx_List_Init(&dma_handle);
|
||||||
|
|
||||||
HAL_DMA_ConfigChannelAttributes(&dma_handle, DMA_CHANNEL_SEC |
|
HAL_DMA_ConfigChannelAttributes(
|
||||||
DMA_CHANNEL_SRC_SEC |
|
&dma_handle, DMA_CHANNEL_PRIV | DMA_CHANNEL_SEC | DMA_CHANNEL_SRC_SEC |
|
||||||
DMA_CHANNEL_DEST_SEC);
|
DMA_CHANNEL_DEST_SEC);
|
||||||
|
|
||||||
/* DMA node configuration declaration */
|
/* DMA node configuration declaration */
|
||||||
DMA_NodeConfTypeDef pNodeConfig = {0};
|
DMA_NodeConfTypeDef pNodeConfig = {0};
|
||||||
|
@ -37,9 +37,9 @@ void hash_processor_init(void) {
|
|||||||
DMA_Handle.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
DMA_Handle.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||||
DMA_Handle.Init.Mode = DMA_NORMAL;
|
DMA_Handle.Init.Mode = DMA_NORMAL;
|
||||||
HAL_DMA_Init(&DMA_Handle);
|
HAL_DMA_Init(&DMA_Handle);
|
||||||
HAL_DMA_ConfigChannelAttributes(&DMA_Handle, DMA_CHANNEL_SEC |
|
HAL_DMA_ConfigChannelAttributes(
|
||||||
DMA_CHANNEL_SRC_SEC |
|
&DMA_Handle, DMA_CHANNEL_PRIV | DMA_CHANNEL_SEC | DMA_CHANNEL_SRC_SEC |
|
||||||
DMA_CHANNEL_DEST_SEC);
|
DMA_CHANNEL_DEST_SEC);
|
||||||
|
|
||||||
DMA_Handle.Parent = &hhash;
|
DMA_Handle.Parent = &hhash;
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "mpu.h"
|
#include "mpu.h"
|
||||||
|
#include "sizedefs.h"
|
||||||
|
|
||||||
#include "stm32u5xx_ll_cortex.h"
|
#include "stm32u5xx_ll_cortex.h"
|
||||||
|
|
||||||
@ -80,6 +81,15 @@ static inline uint32_t mpu_permission_lookup(bool write, bool unpriv) {
|
|||||||
#define MPUX_FLAG_YES 1
|
#define MPUX_FLAG_YES 1
|
||||||
|
|
||||||
#define SET_REGION(region, start, size, type, write, unpriv) \
|
#define SET_REGION(region, start, size, type, write, unpriv) \
|
||||||
|
do { \
|
||||||
|
ENSURE_ALIGNMENT(start, 32); \
|
||||||
|
ENSURE_ALIGNMENT(size, 32); \
|
||||||
|
SET_REGRUN(region, start, size, type, write, unpriv); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
// `SET_REGION` variant without static assert that can be used when
|
||||||
|
// start or size are not compile-time constants
|
||||||
|
#define SET_REGRUN(region, start, size, type, write, unpriv) \
|
||||||
do { \
|
do { \
|
||||||
uint32_t _type = MPUX_TYPE_##type; \
|
uint32_t _type = MPUX_TYPE_##type; \
|
||||||
uint32_t _write = MPUX_FLAG_##write; \
|
uint32_t _write = MPUX_FLAG_##write; \
|
||||||
@ -229,9 +239,9 @@ static void mpu_init_fixed_regions(void) {
|
|||||||
#endif
|
#endif
|
||||||
#if defined(KERNEL)
|
#if defined(KERNEL)
|
||||||
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
||||||
SET_REGION( 0, KERNEL_FLASH_START, KERNEL_FLASH_SIZE, FLASH_CODE, NO, NO ); // Kernel Code
|
SET_REGRUN( 0, KERNEL_FLASH_START, KERNEL_FLASH_SIZE, FLASH_CODE, NO, NO ); // Kernel Code
|
||||||
SET_REGION( 1, KERNEL_RAM_START, KERNEL_RAM_SIZE, SRAM, YES, NO ); // Kernel RAM
|
SET_REGION( 1, KERNEL_RAM_START, KERNEL_RAM_SIZE, SRAM, YES, NO ); // Kernel RAM
|
||||||
SET_REGION( 2, COREAPP_FLASH_START, COREAPP_FLASH_SIZE, FLASH_CODE, NO, YES ); // CoreApp Code
|
SET_REGRUN( 2, COREAPP_FLASH_START, COREAPP_FLASH_SIZE, FLASH_CODE, NO, YES ); // CoreApp Code
|
||||||
SET_REGION( 3, COREAPP_RAM1_START, COREAPP_RAM1_SIZE, SRAM, YES, YES ); // CoraApp RAM
|
SET_REGION( 3, COREAPP_RAM1_START, COREAPP_RAM1_SIZE, SRAM, YES, YES ); // CoraApp RAM
|
||||||
#ifdef STM32U585xx
|
#ifdef STM32U585xx
|
||||||
SET_REGION( 4, COREAPP_RAM2_START, COREAPP_RAM2_SIZE, SRAM, YES, YES ); // CoraAPP RAM2
|
SET_REGION( 4, COREAPP_RAM2_START, COREAPP_RAM2_SIZE, SRAM, YES, YES ); // CoraAPP RAM2
|
||||||
@ -327,7 +337,7 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
|
|||||||
break;
|
break;
|
||||||
case MPU_MODE_APP:
|
case MPU_MODE_APP:
|
||||||
if (drv->unpriv_fb_addr != 0) {
|
if (drv->unpriv_fb_addr != 0) {
|
||||||
SET_REGION( 5, drv->unpriv_fb_addr, drv->unpriv_fb_size, SRAM, YES, YES ); // Frame buffer
|
SET_REGRUN( 5, drv->unpriv_fb_addr, drv->unpriv_fb_size, SRAM, YES, YES ); // Frame buffer
|
||||||
} else {
|
} else {
|
||||||
DIS_REGION( 5 );
|
DIS_REGION( 5 );
|
||||||
}
|
}
|
||||||
@ -368,7 +378,7 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
|
|||||||
SET_REGION( 6, ASSETS_START, ASSETS_MAXSIZE, FLASH_DATA, YES, NO );
|
SET_REGION( 6, ASSETS_START, ASSETS_MAXSIZE, FLASH_DATA, YES, NO );
|
||||||
break;
|
break;
|
||||||
case MPU_MODE_SAES:
|
case MPU_MODE_SAES:
|
||||||
SET_REGION( 6, KERNEL_FLASH_U_START, KERNEL_FLASH_U_SIZE,FLASH_CODE, NO, YES ); // Unprivileged kernel flash
|
SET_REGRUN( 6, KERNEL_FLASH_U_START, KERNEL_FLASH_U_SIZE,FLASH_CODE, NO, YES ); // Unprivileged kernel flash
|
||||||
break;
|
break;
|
||||||
case MPU_MODE_APP:
|
case MPU_MODE_APP:
|
||||||
SET_REGION( 6, ASSETS_START, ASSETS_MAXSIZE, FLASH_DATA, NO, YES );
|
SET_REGION( 6, ASSETS_START, ASSETS_MAXSIZE, FLASH_DATA, NO, YES );
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
#include "trustzone.h"
|
||||||
|
|
||||||
#include "memzero.h"
|
#include "memzero.h"
|
||||||
|
|
||||||
@ -143,6 +144,8 @@ saes_invoke(void) {
|
|||||||
|
|
||||||
extern uint8_t sram_u_start;
|
extern uint8_t sram_u_start;
|
||||||
extern uint8_t sram_u_end;
|
extern uint8_t sram_u_end;
|
||||||
|
extern uint8_t _uflash_start;
|
||||||
|
extern uint8_t _uflash_end;
|
||||||
|
|
||||||
secbool unpriv_encrypt(const uint8_t* input, size_t size, uint8_t* output,
|
secbool unpriv_encrypt(const uint8_t* input, size_t size, uint8_t* output,
|
||||||
secure_aes_keysel_t key) {
|
secure_aes_keysel_t key) {
|
||||||
@ -159,6 +162,24 @@ secbool unpriv_encrypt(const uint8_t* input, size_t size, uint8_t* output,
|
|||||||
uint32_t basepri = __get_BASEPRI();
|
uint32_t basepri = __get_BASEPRI();
|
||||||
__set_BASEPRI(IRQ_PRI_HIGHEST + 1);
|
__set_BASEPRI(IRQ_PRI_HIGHEST + 1);
|
||||||
|
|
||||||
|
uint32_t unpriv_ram_start = (uint32_t)&sram_u_start;
|
||||||
|
uint32_t unpriv_ram_size = &sram_u_end - &sram_u_start;
|
||||||
|
|
||||||
|
// `saes_invoke()` function is too small to justigy placing it in a region
|
||||||
|
// that is aligned to TZ_FLASH_ALIGNMENT (8KB), as doing so would result
|
||||||
|
// in significant wasted space. Therefore, we need to align the flash
|
||||||
|
// addresses to the nearest lower and the nearest higher multiple of
|
||||||
|
// TZ_FLASH_ALIGNMENT.
|
||||||
|
uint32_t unpriv_flash_start =
|
||||||
|
ALIGN_DOWN((uint32_t)&_uflash_start, TZ_FLASH_ALIGNMENT);
|
||||||
|
uint32_t unpriv_flash_size =
|
||||||
|
ALIGN_UP((uint32_t)&_uflash_end, TZ_FLASH_ALIGNMENT) - unpriv_flash_start;
|
||||||
|
|
||||||
|
tz_set_sram_unpriv(unpriv_ram_start, unpriv_ram_size, true);
|
||||||
|
tz_set_flash_unpriv(unpriv_flash_start, unpriv_flash_size, true);
|
||||||
|
tz_set_saes_unpriv(true);
|
||||||
|
tz_set_tamper_unpriv(true);
|
||||||
|
|
||||||
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SAES);
|
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SAES);
|
||||||
|
|
||||||
memset(&sram_u_start, 0, &sram_u_end - &sram_u_start);
|
memset(&sram_u_start, 0, &sram_u_end - &sram_u_start);
|
||||||
@ -183,6 +204,11 @@ secbool unpriv_encrypt(const uint8_t* input, size_t size, uint8_t* output,
|
|||||||
|
|
||||||
mpu_reconfig(mpu_mode);
|
mpu_reconfig(mpu_mode);
|
||||||
|
|
||||||
|
tz_set_sram_unpriv(unpriv_ram_start, unpriv_ram_size, false);
|
||||||
|
tz_set_flash_unpriv(unpriv_flash_start, unpriv_flash_size, false);
|
||||||
|
tz_set_saes_unpriv(false);
|
||||||
|
tz_set_tamper_unpriv(false);
|
||||||
|
|
||||||
__set_BASEPRI(basepri);
|
__set_BASEPRI(basepri);
|
||||||
NVIC_SetPriority(SVCall_IRQn, prev_svc_prio);
|
NVIC_SetPriority(SVCall_IRQn, prev_svc_prio);
|
||||||
|
|
||||||
|
@ -17,12 +17,16 @@
|
|||||||
* 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 <trustzone.h>
|
|
||||||
|
|
||||||
#include STM32_HAL_H
|
#include STM32_HAL_H
|
||||||
#include "irq.h"
|
|
||||||
|
|
||||||
#ifdef BOARDLOADER
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "irq.h"
|
||||||
|
#include "model.h"
|
||||||
|
#include "sizedefs.h"
|
||||||
|
#include "trustzone.h"
|
||||||
|
|
||||||
#define SAU_INIT_CTRL_ENABLE 1
|
#define SAU_INIT_CTRL_ENABLE 1
|
||||||
#define SAU_INIT_CTRL_ALLNS 0
|
#define SAU_INIT_CTRL_ALLNS 0
|
||||||
@ -32,7 +36,7 @@
|
|||||||
SAU->RLAR = ((end) & SAU_RLAR_LADDR_Msk) | \
|
SAU->RLAR = ((end) & SAU_RLAR_LADDR_Msk) | \
|
||||||
(((sec) << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U
|
(((sec) << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U
|
||||||
|
|
||||||
static void trustzone_configure_sau(void) {
|
static void tz_configure_sau(void) {
|
||||||
SAU_INIT_REGION(0, 0x0BF90000, 0x0BFA8FFF, 0); // OTP etc
|
SAU_INIT_REGION(0, 0x0BF90000, 0x0BFA8FFF, 0); // OTP etc
|
||||||
|
|
||||||
SAU->CTRL =
|
SAU->CTRL =
|
||||||
@ -41,7 +45,7 @@ static void trustzone_configure_sau(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Configure ARMCortex-M33 SCB and FPU security
|
// Configure ARMCortex-M33 SCB and FPU security
|
||||||
static void trustzone_configure_arm(void) {
|
static void tz_configure_arm(void) {
|
||||||
// Enable FPU in both secure and non-secure modes
|
// Enable FPU in both secure and non-secure modes
|
||||||
SCB->NSACR |= SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk;
|
SCB->NSACR |= SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk;
|
||||||
|
|
||||||
@ -54,7 +58,7 @@ static void trustzone_configure_arm(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Configure SRAM security
|
// Configure SRAM security
|
||||||
static void trustzone_configure_sram(void) {
|
static void tz_configure_sram(void) {
|
||||||
MPCBB_ConfigTypeDef mpcbb = {0};
|
MPCBB_ConfigTypeDef mpcbb = {0};
|
||||||
|
|
||||||
// No exceptions on illegal access
|
// No exceptions on illegal access
|
||||||
@ -64,17 +68,17 @@ static void trustzone_configure_sram(void) {
|
|||||||
// Set configuration as unlocked
|
// Set configuration as unlocked
|
||||||
mpcbb.AttributeConfig.MPCBB_LockConfig_array[0] = 0x00000000U;
|
mpcbb.AttributeConfig.MPCBB_LockConfig_array[0] = 0x00000000U;
|
||||||
|
|
||||||
// Set all blocks secured & unprivileged
|
// Set all blocks secured & privileged
|
||||||
for (int index = 0; index < GTZC_MPCBB_NB_VCTR_REG_MAX; index++) {
|
for (int index = 0; index < GTZC_MPCBB_NB_VCTR_REG_MAX; index++) {
|
||||||
mpcbb.AttributeConfig.MPCBB_SecConfig_array[index] = 0xFFFFFFFFU;
|
mpcbb.AttributeConfig.MPCBB_SecConfig_array[index] = 0xFFFFFFFFU;
|
||||||
mpcbb.AttributeConfig.MPCBB_PrivConfig_array[index] = 0x00000000U;
|
mpcbb.AttributeConfig.MPCBB_PrivConfig_array[index] = 0xFFFFFFFFU;
|
||||||
}
|
}
|
||||||
|
|
||||||
HAL_GTZC_MPCBB_ConfigMem(SRAM1_BASE, &mpcbb);
|
HAL_GTZC_MPCBB_ConfigMem(SRAM1_BASE, &mpcbb);
|
||||||
HAL_GTZC_MPCBB_ConfigMem(SRAM2_BASE, &mpcbb);
|
HAL_GTZC_MPCBB_ConfigMem(SRAM2_BASE, &mpcbb);
|
||||||
HAL_GTZC_MPCBB_ConfigMem(SRAM3_BASE, &mpcbb);
|
HAL_GTZC_MPCBB_ConfigMem(SRAM3_BASE, &mpcbb);
|
||||||
HAL_GTZC_MPCBB_ConfigMem(SRAM4_BASE, &mpcbb);
|
HAL_GTZC_MPCBB_ConfigMem(SRAM4_BASE, &mpcbb);
|
||||||
#if defined STM32U5A9xx | defined STM32U5G9xx
|
#if defined STM32U5A9xx || defined STM32U5G9xx
|
||||||
HAL_GTZC_MPCBB_ConfigMem(SRAM5_BASE, &mpcbb);
|
HAL_GTZC_MPCBB_ConfigMem(SRAM5_BASE, &mpcbb);
|
||||||
#endif
|
#endif
|
||||||
#if defined STM32U5G9xx
|
#if defined STM32U5G9xx
|
||||||
@ -82,13 +86,13 @@ static void trustzone_configure_sram(void) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void trustzone_configure_fsmc(void) {
|
static void tz_configure_fsmc(void) {
|
||||||
__HAL_RCC_FMC_CLK_ENABLE();
|
__HAL_RCC_FMC_CLK_ENABLE();
|
||||||
MPCWM_ConfigTypeDef mpcwm = {0};
|
MPCWM_ConfigTypeDef mpcwm = {0};
|
||||||
|
|
||||||
mpcwm.AreaId = GTZC_TZSC_MPCWM_ID1;
|
mpcwm.AreaId = GTZC_TZSC_MPCWM_ID1;
|
||||||
mpcwm.AreaStatus = ENABLE;
|
mpcwm.AreaStatus = ENABLE;
|
||||||
mpcwm.Attribute = GTZC_TZSC_MPCWM_REGION_SEC;
|
mpcwm.Attribute = GTZC_TZSC_MPCWM_REGION_SEC | GTZC_TZSC_MPCWM_REGION_PRIV;
|
||||||
mpcwm.Length = 128 * 1024;
|
mpcwm.Length = 128 * 1024;
|
||||||
mpcwm.Offset = 0;
|
mpcwm.Offset = 0;
|
||||||
mpcwm.Lock = GTZC_TZSC_MPCWM_LOCK_OFF;
|
mpcwm.Lock = GTZC_TZSC_MPCWM_LOCK_OFF;
|
||||||
@ -96,10 +100,10 @@ static void trustzone_configure_fsmc(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Configure FLASH security
|
// Configure FLASH security
|
||||||
static void trustzone_configure_flash(void) {
|
static void tz_configure_flash(void) {
|
||||||
FLASH_BBAttributesTypeDef flash_bb = {0};
|
FLASH_BBAttributesTypeDef flash_bb = {0};
|
||||||
|
|
||||||
// Set all blocks as secured
|
// Set all blocks as secured & privileged
|
||||||
for (int index = 0; index < FLASH_BLOCKBASED_NB_REG; index++) {
|
for (int index = 0; index < FLASH_BLOCKBASED_NB_REG; index++) {
|
||||||
flash_bb.BBAttributes_array[index] = 0xFFFFFFFF;
|
flash_bb.BBAttributes_array[index] = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
@ -107,34 +111,39 @@ static void trustzone_configure_flash(void) {
|
|||||||
flash_bb.Bank = FLASH_BANK_1;
|
flash_bb.Bank = FLASH_BANK_1;
|
||||||
flash_bb.BBAttributesType = FLASH_BB_SEC;
|
flash_bb.BBAttributesType = FLASH_BB_SEC;
|
||||||
HAL_FLASHEx_ConfigBBAttributes(&flash_bb);
|
HAL_FLASHEx_ConfigBBAttributes(&flash_bb);
|
||||||
|
flash_bb.BBAttributesType = FLASH_BB_PRIV;
|
||||||
|
HAL_FLASHEx_ConfigBBAttributes(&flash_bb);
|
||||||
|
|
||||||
flash_bb.Bank = FLASH_BANK_2;
|
flash_bb.Bank = FLASH_BANK_2;
|
||||||
flash_bb.BBAttributesType = FLASH_BB_SEC;
|
flash_bb.BBAttributesType = FLASH_BB_SEC;
|
||||||
HAL_FLASHEx_ConfigBBAttributes(&flash_bb);
|
HAL_FLASHEx_ConfigBBAttributes(&flash_bb);
|
||||||
|
flash_bb.BBAttributesType = FLASH_BB_PRIV;
|
||||||
|
HAL_FLASHEx_ConfigBBAttributes(&flash_bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trustzone_init_boardloader(void) {
|
void tz_init_boardloader(void) {
|
||||||
// Configure ARM SCB/FBU security
|
// Configure ARM SCB/FBU security
|
||||||
trustzone_configure_arm();
|
tz_configure_arm();
|
||||||
|
|
||||||
// Configure SAU security attributes
|
// Configure SAU security attributes
|
||||||
trustzone_configure_sau();
|
tz_configure_sau();
|
||||||
|
|
||||||
// Enable GTZC (Global Trust-Zone Controller) peripheral clock
|
// Enable GTZC (Global Trust-Zone Controller) peripheral clock
|
||||||
__HAL_RCC_GTZC1_CLK_ENABLE();
|
__HAL_RCC_GTZC1_CLK_ENABLE();
|
||||||
__HAL_RCC_GTZC2_CLK_ENABLE();
|
__HAL_RCC_GTZC2_CLK_ENABLE();
|
||||||
|
|
||||||
// Configure SRAM security attributes
|
// Configure SRAM security attributes
|
||||||
trustzone_configure_sram();
|
tz_configure_sram();
|
||||||
|
|
||||||
// Configure FLASH security attributes
|
// Configure FLASH security attributes
|
||||||
trustzone_configure_flash();
|
tz_configure_flash();
|
||||||
|
|
||||||
// Configure FSMC security attributes
|
// Configure FSMC security attributes
|
||||||
trustzone_configure_fsmc();
|
tz_configure_fsmc();
|
||||||
|
|
||||||
// Make all peripherals secure
|
// Make all peripherals secure & privileged
|
||||||
HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_ALL, GTZC_TZSC_PERIPH_SEC);
|
HAL_GTZC_TZSC_ConfigPeriphAttributes(
|
||||||
|
GTZC_PERIPH_ALL, GTZC_TZSC_PERIPH_SEC | GTZC_TZSC_PERIPH_PRIV);
|
||||||
|
|
||||||
// Clear all illegal access flags in GTZC TZIC
|
// Clear all illegal access flags in GTZC TZIC
|
||||||
HAL_GTZC_TZIC_ClearFlag(GTZC_PERIPH_ALL);
|
HAL_GTZC_TZIC_ClearFlag(GTZC_PERIPH_ALL);
|
||||||
@ -147,4 +156,211 @@ void trustzone_init_boardloader(void) {
|
|||||||
NVIC_EnableIRQ(GTZC_IRQn);
|
NVIC_EnableIRQ(GTZC_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BOARDLOADER
|
void tz_init_kernel(void) {
|
||||||
|
// Configure SRAM security attributes
|
||||||
|
tz_configure_sram();
|
||||||
|
|
||||||
|
// Configure FLASH security attributes
|
||||||
|
tz_configure_flash();
|
||||||
|
|
||||||
|
// Configure FSMC security attributes
|
||||||
|
tz_configure_fsmc();
|
||||||
|
|
||||||
|
// Make all peripherals secure & privileged
|
||||||
|
HAL_GTZC_TZSC_ConfigPeriphAttributes(
|
||||||
|
GTZC_PERIPH_ALL, GTZC_TZSC_PERIPH_SEC | GTZC_TZSC_PERIPH_PRIV);
|
||||||
|
|
||||||
|
// Clear all illegal access flags in GTZC TZIC
|
||||||
|
HAL_GTZC_TZIC_ClearFlag(GTZC_PERIPH_ALL);
|
||||||
|
|
||||||
|
// Enable all illegal access interrupts in GTZC TZIC
|
||||||
|
HAL_GTZC_TZIC_EnableIT(GTZC_PERIPH_ALL);
|
||||||
|
|
||||||
|
// Enable GTZC secure interrupt
|
||||||
|
NVIC_SetPriority(GTZC_IRQn, IRQ_PRI_HIGHEST);
|
||||||
|
NVIC_EnableIRQ(GTZC_IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_bit_array(volatile uint32_t* regs, uint32_t bit_offset,
|
||||||
|
uint32_t bit_count, bool value) {
|
||||||
|
regs += bit_offset / 32;
|
||||||
|
bit_offset %= 32;
|
||||||
|
|
||||||
|
if (bit_offset != 0) {
|
||||||
|
uint32_t bc = MIN(32 - bit_offset, bit_count);
|
||||||
|
uint32_t mask = (1 << bc) - 1;
|
||||||
|
|
||||||
|
mask <<= bit_offset;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
*regs |= mask;
|
||||||
|
} else {
|
||||||
|
*regs &= ~mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
regs++;
|
||||||
|
bit_count -= bc;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bit_count >= 32) {
|
||||||
|
*regs = value ? 0xFFFFFFFF : 0;
|
||||||
|
regs++;
|
||||||
|
bit_count -= 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bit_count > 0) {
|
||||||
|
uint32_t mask = (1 << bit_count) - 1;
|
||||||
|
if (value) {
|
||||||
|
*regs |= mask;
|
||||||
|
} else {
|
||||||
|
*regs &= ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// Start address of the region
|
||||||
|
uint32_t start;
|
||||||
|
// End address of the region + 1
|
||||||
|
size_t end;
|
||||||
|
// MPCBB register base
|
||||||
|
volatile GTZC_MPCBB_TypeDef* regs;
|
||||||
|
} sram_region_t;
|
||||||
|
|
||||||
|
// SRAM regions must be in order of ascending start address
|
||||||
|
// and must not overlap
|
||||||
|
sram_region_t g_sram_regions[] = {
|
||||||
|
{SRAM1_BASE, SRAM1_BASE + SRAM1_SIZE, GTZC_MPCBB1},
|
||||||
|
{SRAM2_BASE, SRAM2_BASE + SRAM2_SIZE, GTZC_MPCBB2},
|
||||||
|
{SRAM3_BASE, SRAM3_BASE + SRAM3_SIZE, GTZC_MPCBB3},
|
||||||
|
#if defined STM32U5A9xx | defined STM32U5G9xx
|
||||||
|
{SRAM5_BASE, SRAM5_BASE + SRAM5_SIZE, GTZC_MPCBB5},
|
||||||
|
#endif
|
||||||
|
#if defined STM32U5G9xx
|
||||||
|
{SRAM6_BASE, SRAM6_BASE + SRAM6_SIZE, GTZC_MPCBB6},
|
||||||
|
#endif
|
||||||
|
{SRAM4_BASE, SRAM4_BASE + SRAM4_SIZE, GTZC_MPCBB4},
|
||||||
|
};
|
||||||
|
|
||||||
|
void tz_set_sram_unpriv(uint32_t start, uint32_t size, bool unpriv) {
|
||||||
|
const size_t block_size = TZ_SRAM_ALIGNMENT;
|
||||||
|
|
||||||
|
ensure(sectrue * IS_ALIGNED(start, block_size), "TZ alignment");
|
||||||
|
ensure(sectrue * IS_ALIGNED(size, block_size), "TZ alignment");
|
||||||
|
|
||||||
|
uint32_t end = start + size;
|
||||||
|
|
||||||
|
for (int idx = 0; idx < ARRAY_LENGTH(g_sram_regions); idx++) {
|
||||||
|
const sram_region_t* r = &g_sram_regions[idx];
|
||||||
|
|
||||||
|
if (start >= r->end) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end <= r->start) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clip to region bounds
|
||||||
|
uint32_t clipped_start = MAX(start, r->start);
|
||||||
|
uint32_t clipped_end = MIN(end, r->end);
|
||||||
|
|
||||||
|
// Calculate bit offsets
|
||||||
|
uint32_t bit_offset = (clipped_start - r->start) / block_size;
|
||||||
|
uint32_t bit_count = (clipped_end - clipped_start) / block_size;
|
||||||
|
|
||||||
|
// Set/reset bits corresponding to 512B blocks
|
||||||
|
set_bit_array(r->regs->PRIVCFGR, bit_offset, bit_count, !unpriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
__ISB();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// Start address of the region
|
||||||
|
uint32_t start;
|
||||||
|
// End address of the region + 1
|
||||||
|
size_t end;
|
||||||
|
// PRIVBB register base
|
||||||
|
volatile uint32_t* privbb;
|
||||||
|
} flash_region_t;
|
||||||
|
|
||||||
|
#if defined STM32U5A9xx
|
||||||
|
#define XFLASH_BANK_SIZE 0x200000
|
||||||
|
#elif defined STM32U5G9xx
|
||||||
|
#define XFLASH_BANK_SIZE 0x200000
|
||||||
|
#elif defined STM32U585xx
|
||||||
|
#define XFLASH_BANK_SIZE 0x100000
|
||||||
|
#else
|
||||||
|
#error "Unknown MCU"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FLASH_BANK1_BASE FLASH_BASE
|
||||||
|
#define FLASH_BANK2_BASE (FLASH_BASE + XFLASH_BANK_SIZE)
|
||||||
|
|
||||||
|
// FLASH regions must be in order of ascending start address
|
||||||
|
// and must not overlap
|
||||||
|
flash_region_t g_flash_regions[] = {
|
||||||
|
{FLASH_BANK1_BASE, FLASH_BANK1_BASE + XFLASH_BANK_SIZE, &FLASH->PRIVBB1R1},
|
||||||
|
{FLASH_BANK2_BASE, FLASH_BANK2_BASE + XFLASH_BANK_SIZE, &FLASH->PRIVBB2R1},
|
||||||
|
};
|
||||||
|
|
||||||
|
void tz_set_flash_unpriv(uint32_t start, uint32_t size, bool unpriv) {
|
||||||
|
const size_t block_size = TZ_FLASH_ALIGNMENT;
|
||||||
|
|
||||||
|
ensure(sectrue * IS_ALIGNED(start, block_size), "TZ alignment");
|
||||||
|
ensure(sectrue * IS_ALIGNED(size, block_size), "TZ alignment");
|
||||||
|
|
||||||
|
uint32_t end = start + size;
|
||||||
|
|
||||||
|
for (int idx = 0; idx < ARRAY_LENGTH(g_flash_regions); idx++) {
|
||||||
|
const flash_region_t* r = &g_flash_regions[idx];
|
||||||
|
|
||||||
|
if (start >= r->end) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end <= r->start) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clip to region bounds
|
||||||
|
uint32_t clipped_start = MAX(start, r->start);
|
||||||
|
uint32_t clipped_end = MIN(end, r->end);
|
||||||
|
|
||||||
|
// Calculate bit offsets
|
||||||
|
uint32_t bit_offset = (clipped_start - r->start) / block_size;
|
||||||
|
uint32_t bit_count = (clipped_end - clipped_start) / block_size;
|
||||||
|
|
||||||
|
// Set/reset bits corresponding to flash pages (8KB)
|
||||||
|
set_bit_array(r->privbb, bit_offset, bit_count, !unpriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
__ISB();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tz_set_saes_unpriv(bool unpriv) {
|
||||||
|
HAL_GTZC_TZSC_ConfigPeriphAttributes(
|
||||||
|
GTZC_PERIPH_SAES,
|
||||||
|
unpriv ? GTZC_TZSC_PERIPH_NPRIV : GTZC_TZSC_PERIPH_PRIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tz_set_tamper_unpriv(bool unpriv) {
|
||||||
|
HAL_GTZC_TZSC_ConfigPeriphAttributes(
|
||||||
|
GTZC_PERIPH_TAMP,
|
||||||
|
unpriv ? GTZC_TZSC_PERIPH_NPRIV : GTZC_TZSC_PERIPH_PRIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tz_set_dma2d_unpriv(bool unpriv) {
|
||||||
|
HAL_GTZC_TZSC_ConfigPeriphAttributes(
|
||||||
|
GTZC_PERIPH_DMA2D,
|
||||||
|
unpriv ? GTZC_TZSC_PERIPH_NPRIV : GTZC_TZSC_PERIPH_PRIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined STM32U5A9xx || defined STM32U5G9xx
|
||||||
|
void tz_set_gfxmmu_unpriv(bool unpriv) {
|
||||||
|
HAL_GTZC_TZSC_ConfigPeriphAttributes(
|
||||||
|
GTZC_PERIPH_GFXMMU,
|
||||||
|
unpriv ? GTZC_TZSC_PERIPH_NPRIV : GTZC_TZSC_PERIPH_PRIV);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -26,21 +26,50 @@
|
|||||||
#include <xdisplay.h>
|
#include <xdisplay.h>
|
||||||
#include "display_internal.h"
|
#include "display_internal.h"
|
||||||
#include "mpu.h"
|
#include "mpu.h"
|
||||||
|
#include "trustzone.h"
|
||||||
|
|
||||||
#ifdef KERNEL_MODE
|
#ifdef KERNEL_MODE
|
||||||
|
|
||||||
// Physical frame buffers in internal SRAM memory
|
// Physical frame buffers in internal SRAM memory
|
||||||
__attribute__((section(".fb1")))
|
__attribute__((section(".fb1"), aligned(PHYSICAL_FRAME_BUFFER_ALIGNMENT)))
|
||||||
ALIGN_32BYTES(uint8_t physical_frame_buffer_0[PHYSICAL_FRAME_BUFFER_SIZE]);
|
uint8_t physical_frame_buffer_0[PHYSICAL_FRAME_BUFFER_SIZE];
|
||||||
|
|
||||||
__attribute__((section(".fb2")))
|
__attribute__((section(".fb2"), aligned(PHYSICAL_FRAME_BUFFER_ALIGNMENT)))
|
||||||
ALIGN_32BYTES(uint8_t physical_frame_buffer_1[PHYSICAL_FRAME_BUFFER_SIZE]);
|
uint8_t physical_frame_buffer_1[PHYSICAL_FRAME_BUFFER_SIZE];
|
||||||
|
|
||||||
// The current frame buffer selector at fixed memory address
|
// The current frame buffer selector at fixed memory address
|
||||||
// It's shared between bootloaders and the firmware
|
// It's shared between bootloaders and the firmware
|
||||||
__attribute__((section(".framebuffer_select"))) uint32_t current_frame_buffer =
|
__attribute__((section(".framebuffer_select"))) uint32_t current_frame_buffer =
|
||||||
0;
|
0;
|
||||||
|
|
||||||
|
void display_set_unpriv_access(bool unpriv) {
|
||||||
|
// To allow unprivileged access both GFXMMU virtual buffers area and
|
||||||
|
// underlying SRAM region must be configured as unprivileged.
|
||||||
|
|
||||||
|
// Order of GFXMMU and SRAM unprivileged access configuration is important
|
||||||
|
// to avoid the situation the virtual frame buffer has lower privileges
|
||||||
|
// than underlying frame buffer in physical memory so LTDC could not
|
||||||
|
// refresh the display properly.
|
||||||
|
|
||||||
|
if (!unpriv) {
|
||||||
|
tz_set_gfxmmu_unpriv(unpriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
tz_set_sram_unpriv((uint32_t)physical_frame_buffer_0,
|
||||||
|
PHYSICAL_FRAME_BUFFER_SIZE, unpriv);
|
||||||
|
|
||||||
|
tz_set_sram_unpriv((uint32_t)physical_frame_buffer_1,
|
||||||
|
PHYSICAL_FRAME_BUFFER_SIZE, unpriv);
|
||||||
|
|
||||||
|
if (unpriv) {
|
||||||
|
tz_set_gfxmmu_unpriv(unpriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_DMA2D
|
||||||
|
tz_set_dma2d_unpriv(unpriv);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool display_get_frame_buffer(display_fb_info_t *fb) {
|
bool display_get_frame_buffer(display_fb_info_t *fb) {
|
||||||
display_driver_t *drv = &g_display_driver;
|
display_driver_t *drv = &g_display_driver;
|
||||||
|
|
||||||
@ -87,13 +116,9 @@ void display_refresh(void) {
|
|||||||
if (current_frame_buffer == 0) {
|
if (current_frame_buffer == 0) {
|
||||||
current_frame_buffer = 1;
|
current_frame_buffer = 1;
|
||||||
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER1_BASE_S);
|
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER1_BASE_S);
|
||||||
memcpy(physical_frame_buffer_0, physical_frame_buffer_1,
|
|
||||||
sizeof(physical_frame_buffer_0));
|
|
||||||
} else {
|
} else {
|
||||||
current_frame_buffer = 0;
|
current_frame_buffer = 0;
|
||||||
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER0_BASE_S);
|
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER0_BASE_S);
|
||||||
memcpy(physical_frame_buffer_1, physical_frame_buffer_0,
|
|
||||||
sizeof(physical_frame_buffer_1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "sizedefs.h"
|
||||||
|
#include "trustzone.h"
|
||||||
|
|
||||||
// Display driver context.
|
// Display driver context.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Set if the driver is initialized
|
// Set if the driver is initialized
|
||||||
@ -36,11 +39,19 @@ typedef struct {
|
|||||||
// Display driver instance
|
// Display driver instance
|
||||||
extern display_driver_t g_display_driver;
|
extern display_driver_t g_display_driver;
|
||||||
|
|
||||||
|
// Hardware requires physical frame buffer alignment
|
||||||
|
#ifdef USE_TRUSTZONE
|
||||||
|
#define PHYSICAL_FRAME_BUFFER_ALIGNMENT TZ_SRAM_ALIGNMENT
|
||||||
|
#else
|
||||||
|
#define PHYSICAL_FRAME_BUFFER_ALIGNMENT 32
|
||||||
|
#endif
|
||||||
|
|
||||||
// Size of the physical frame buffer in bytes
|
// Size of the physical frame buffer in bytes
|
||||||
//
|
//
|
||||||
// It's smaller than size of the virtual frame buffer
|
// It's smaller than size of the virtual frame buffer
|
||||||
// due to used GFXMMU settings
|
// due to used GFXMMU settings
|
||||||
#define PHYSICAL_FRAME_BUFFER_SIZE (184320 * 4)
|
#define PHYSICAL_FRAME_BUFFER_SIZE \
|
||||||
|
ALIGN_UP_CONST(184320 * 4, PHYSICAL_FRAME_BUFFER_ALIGNMENT)
|
||||||
|
|
||||||
// Pitch (in pixels) of the virtual frame buffer
|
// Pitch (in pixels) of the virtual frame buffer
|
||||||
#define FRAME_BUFFER_PIXELS_PER_LINE 768
|
#define FRAME_BUFFER_PIXELS_PER_LINE 768
|
||||||
|
@ -17,15 +17,49 @@
|
|||||||
* 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 __TREZORHAL_TRUSTZONE__
|
#ifndef TREZORHAL_TRUSTZONE
|
||||||
#define __TREZORHAL_TRUSTZONE__
|
#define TREZORHAL_TRUSTZONE
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef BOARDLOADER
|
#ifdef BOARDLOADER
|
||||||
|
|
||||||
// Provides initial security configuration of CPU and GTZC
|
// Provides initial security configuration of CPU and GTZC
|
||||||
// in the board-loader
|
// in the board-loader
|
||||||
void trustzone_init_boardloader(void);
|
void tz_init_boardloader(void);
|
||||||
|
|
||||||
#endif // BOARDLOADER
|
#endif // BOARDLOADER
|
||||||
|
|
||||||
#endif
|
// Alters configuration of GTZC in the kernel
|
||||||
|
void tz_init_kernel(void);
|
||||||
|
|
||||||
|
// Alignment required by MCPBB/GTZC for SRAM regions
|
||||||
|
#define TZ_SRAM_ALIGNMENT 512
|
||||||
|
|
||||||
|
// Set unprivileged access to an SRAM address range at the
|
||||||
|
// MCPBB/GTZC level. The region's start and end are automatically aligned to
|
||||||
|
// 512B to cover the entire specified range.
|
||||||
|
void tz_set_sram_unpriv(uint32_t start, uint32_t size, bool unpriv);
|
||||||
|
|
||||||
|
// Alignment required by GTZC for FLASH regions
|
||||||
|
#define TZ_FLASH_ALIGNMENT 8192
|
||||||
|
|
||||||
|
// Sets unprivileged access to a FLASH address range at the
|
||||||
|
// MCPBB/GTZC level. The region's start and end are automatically aligned to
|
||||||
|
// 8KB to cover the entire specified range.
|
||||||
|
void tz_set_flash_unpriv(uint32_t start, uint32_t size, bool unpriv);
|
||||||
|
|
||||||
|
// Sets unprivileged access to the SAES peripheral.
|
||||||
|
void tz_set_saes_unpriv(bool unpriv);
|
||||||
|
|
||||||
|
// Sets unprivileged access to the TAMP peripheral.
|
||||||
|
void tz_set_tamper_unpriv(bool unpriv);
|
||||||
|
|
||||||
|
// Sets unprivileged access to the DMA2D peripheral.
|
||||||
|
void tz_set_dma2d_unpriv(bool unpriv);
|
||||||
|
|
||||||
|
// Sets unprivileged access to the GFXMMU peripheral.
|
||||||
|
void tz_set_gfxmmu_unpriv(bool unpriv);
|
||||||
|
|
||||||
|
#endif // TREZORHAL_TRUSTZONE
|
||||||
|
@ -71,6 +71,10 @@ void display_init(display_content_mode_t mode);
|
|||||||
// `display_init(DISPLAY_RETAIN_CONTENT)`.
|
// `display_init(DISPLAY_RETAIN_CONTENT)`.
|
||||||
void display_deinit(display_content_mode_t mode);
|
void display_deinit(display_content_mode_t mode);
|
||||||
|
|
||||||
|
// Allows unprivileged access to the display framebuffer from
|
||||||
|
// perspective of the GTZC (Global TrustZone Controller).
|
||||||
|
void display_set_unpriv_access(bool unpriv);
|
||||||
|
|
||||||
#endif // KERNEL_MODE
|
#endif // KERNEL_MODE
|
||||||
|
|
||||||
// Sets display backlight level ranging from 0 (off)..255 (maximum).
|
// Sets display backlight level ranging from 0 (off)..255 (maximum).
|
||||||
|
Loading…
Reference in New Issue
Block a user