u5 - basic support

tychovrahe/u5/master
tychovrahe 11 months ago
parent 067b37ad32
commit aa7422df0e

@ -34,21 +34,29 @@ PYTEST_TIMEOUT ?= 400
OPENOCD_INTERFACE ?= stlink
# OpenOCD transport default. Alternative: jtag
OPENOCD_TRANSPORT ?= hla_swd
OPENOCD = openocd -f interface/$(OPENOCD_INTERFACE).cfg -c "transport select $(OPENOCD_TRANSPORT)" -f target/stm32f4x.cfg
OPENOCD_T1 = openocd -f interface/$(OPENOCD_INTERFACE).cfg -c "transport select $(OPENOCD_TRANSPORT)" -f target/stm32f2x.cfg
ifeq ($(TREZOR_MODEL),$(filter $(TREZOR_MODEL),T R DISC1))
OPENOCD_TARGET = target/stm32f4x.cfg
BOARDLOADER_START = 0x08000000
BOARDLOADER_END = 0x0800C000
BOOTLOADER_START = 0x08020000
FIRMWARE_P1_START = 0x08040000
FIRMWARE_START = 0x08040000
FIRMWARE_P2_START = 0x08120000
PRODTEST_START = 0x08040000
FIRMWARE_T1_START = 0x08010000
BOARDLOADER_MAXSIZE = 49152
BOOTLOADER_MAXSIZE = 131072
FIRMWARE_P1_MAXSIZE = 786432
FIRMWARE_P2_MAXSIZE = 917504
FIRMWARE_MAXSIZE = 1703936
else ifeq ($(TREZOR_MODEL), 1)
OPENOCD_TARGET = target/stm32uf2.cfg
FIRMWARE_START = 0x08010000
else
$(error Unknown TREZOR_MODEL: $(TREZOR_MODEL))
endif
OPENOCD = openocd -f interface/$(OPENOCD_INTERFACE).cfg -c "transport select $(OPENOCD_TRANSPORT)" -f $(OPENOCD_TARGET)
CFLAGS += -DSCM_REVISION='\"$(shell git rev-parse HEAD | sed 's:\(..\):\\x\1:g')\"'
@ -271,10 +279,12 @@ flash_prodtest: $(PRODTEST_BUILD_DIR)/prodtest.bin ## flash prodtest using OpenO
$(OPENOCD) -c "init; reset halt; flash write_image erase $< $(PRODTEST_START); exit"
flash_firmware: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash firmware using OpenOCD
$(OPENOCD) -c "init; reset halt; flash write_image erase $<.p1 $(FIRMWARE_P1_START); flash write_image erase $<.p2 $(FIRMWARE_P2_START); exit"
ifdef FIRMWARE_P2_START
$(OPENOCD) -c "init; reset halt; flash write_image erase $<.p1 $(FIRMWARE_START); flash write_image erase $<.p2 $(FIRMWARE_P2_START); exit"
flash_firmware_t1: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash T1 core port on T1 using OpenOCD
$(OPENOCD_T1) -c "init; reset halt; flash write_image erase $< $(FIRMWARE_T1_START); exit"
else
$(OPENOCD) -c "init; reset halt; flash write_image erase $< $(FIRMWARE_START); exit"
endif
flash_combine: $(PRODTEST_BUILD_DIR)/combined.bin ## flash combined using OpenOCD
$(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit"
@ -346,7 +356,11 @@ combine: ## combine boardloader + bootloader + prodtest into one combined image
$(BOARDLOADER_BUILD_DIR)/boardloader.bin \
$(BOOTLOADER_BUILD_DIR)/bootloader.bin \
$(PRODTEST_BUILD_DIR)/prodtest.bin \
$(PRODTEST_BUILD_DIR)/combined.bin
$(PRODTEST_BUILD_DIR)/combined.bin \
$(BOARDLOADER_START) \
$(BOARDLOADER_END) \
$(BOOTLOADER_START) \
$(PRODTEST_START)
upload: ## upload firmware using trezorctl
trezorctl firmware_update -s -f $(FIRMWARE_BUILD_DIR)/firmware.bin

@ -63,17 +63,19 @@ SOURCE_MOD += [
'embed/lib/fonts/font_bitmap.c',
'embed/lib/image.c',
'embed/lib/mini_printf.c',
'vendor/trezor-storage/flash_common.c',
]
env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0')), CONSTRAINTS=["limited_util_s"])
FEATURES_AVAILABLE = tools.configure_board(TREZOR_MODEL, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL)
FILE_SUFFIX= env.get('ENV')['SUFFIX']
SOURCE_BOARDLOADER = [
'embed/boardloader/startup.s',
f"embed/boardloader/startup_{FILE_SUFFIX}.s",
'embed/boardloader/main.c',
]
env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0')), CONSTRAINTS=["limited_util_s"])
FEATURES_AVAILABLE = tools.configure_board(TREZOR_MODEL, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL)
env.Replace(
CP='cp',
@ -101,7 +103,7 @@ env.Replace(
'-fstack-protector-all '
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB',
LINKFLAGS='-T embed/boardloader/memory.ld -Wl,--gc-sections -Wl,-Map=build/boardloader/boardloader.map -Wl,--warn-common -Wl,--print-memory-usage',
LINKFLAGS=f"-T embed/boardloader/memory_{FILE_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/boardloader/boardloader.map -Wl,--warn-common -Wl,--print-memory-usage",
CPPPATH=[
'embed/boardloader',
'embed/lib',
@ -158,7 +160,7 @@ program_bin = env.Command(
target='boardloader.bin',
source=program_elf,
action=[
'$OBJCOPY -O binary $SOURCE $TARGET',
'$OBJCOPY -O binary -j .vector_table -j .text -j .data -j .rodata -j .capabilities -j .sensitive $SOURCE $TARGET',
'$CP $TARGET ' + BINARY_NAME,
],
)

@ -91,7 +91,6 @@ SOURCE_MOD += [
'vendor/micropython/lib/uzlib/adler32.c',
'vendor/micropython/lib/uzlib/crc32.c',
'vendor/micropython/lib/uzlib/tinflate.c',
'vendor/trezor-storage/flash_common.c',
]
SOURCE_NANOPB = [
@ -100,15 +99,6 @@ SOURCE_NANOPB = [
'vendor/nanopb/pb_encode.c',
]
SOURCE_BOOTLOADER = [
'embed/bootloader/startup.s',
'embed/bootloader/header.S',
'embed/bootloader/bootui.c',
'embed/bootloader/main.c',
'embed/bootloader/messages.c',
'embed/bootloader/protob/messages.pb.c',
]
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
@ -120,6 +110,18 @@ env = Environment(ENV=os.environ, CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODU
FEATURES_AVAILABLE = tools.configure_board(TREZOR_MODEL, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL)
FILE_SUFFIX= env.get('ENV')['SUFFIX']
SOURCE_BOOTLOADER = [
f'embed/bootloader/startup_{FILE_SUFFIX}.s',
'embed/bootloader/header.S',
'embed/bootloader/bootui.c',
'embed/bootloader/main.c',
'embed/bootloader/messages.c',
'embed/bootloader/protob/messages.pb.c',
]
env.Replace(
CP='cp',
AS='arm-none-eabi-as',
@ -146,7 +148,7 @@ env.Replace(
'-fstack-protector-all '
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB',
LINKFLAGS='-T embed/bootloader/memory.ld -Wl,--gc-sections -Wl,-Map=build/bootloader/bootloader.map -Wl,--warn-common -Wl,--print-memory-usage',
LINKFLAGS=f'-T embed/bootloader/memory_{FILE_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/bootloader/bootloader.map -Wl,--warn-common -Wl,--print-memory-usage',
CPPPATH=[
'embed/rust',
'embed/bootloader',
@ -265,7 +267,7 @@ program_bin = env.Command(
target='bootloader.bin',
source=program_elf,
action=[
'$OBJCOPY -O binary -j .header -j .flash -j .data $SOURCE $TARGET',
'$OBJCOPY -O binary -j .header -j .flash -j .data -j .sensitive $SOURCE $TARGET',
'$HEADERTOOL $TARGET ' + ('-D' if not PRODUCTION else ''),
'$CP $TARGET ' + BINARY_NAME,
], )

@ -66,7 +66,6 @@ SOURCE_MOD += [
'vendor/trezor-crypto/memzero.c',
'vendor/trezor-crypto/rand.c',
'vendor/trezor-crypto/sha2.c',
'vendor/trezor-storage/flash_common.c',
]
# modtrezorui
@ -92,16 +91,6 @@ SOURCE_NANOPB = [
'vendor/nanopb/pb_encode.c',
]
SOURCE_BOOTLOADER = [
'embed/bootloader_ci/startup.s',
'embed/bootloader_ci/header.S',
'embed/bootloader_ci/bootui.c',
'embed/bootloader_ci/main.c',
'embed/bootloader_ci/messages.c',
'embed/bootloader_ci/protob/messages.pb.c',
]
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
@ -113,6 +102,17 @@ env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('
FEATURES_AVAILABLE = tools.configure_board(TREZOR_MODEL, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL)
FILE_SUFFIX= env.get('ENV')['SUFFIX']
SOURCE_BOOTLOADER = [
'embed/bootloader_ci/startup_{FILE_SUFFIX}.s',
'embed/bootloader_ci/header.S',
'embed/bootloader_ci/bootui.c',
'embed/bootloader_ci/main.c',
'embed/bootloader_ci/messages.c',
'embed/bootloader_ci/protob/messages.pb.c',
]
env.Replace(
CP='cp',
AS='arm-none-eabi-as',
@ -139,7 +139,7 @@ env.Replace(
'-fstack-protector-all '
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB',
LINKFLAGS='-T embed/bootloader_ci/memory.ld -Wl,--gc-sections -Wl,-Map=build/bootloader_ci/bootloader.map -Wl,--warn-common',
LINKFLAGS='-T embed/bootloader_ci/memory_{FILE_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/bootloader_ci/bootloader.map -Wl,--warn-common',
CPPPATH=[
'embed/bootloader_ci',
'embed/bootloader_ci/nanopb',
@ -206,7 +206,7 @@ program_bin = env.Command(
target='bootloader.bin',
source=program_elf,
action=[
'$OBJCOPY -O binary -j .header -j .flash -j .data $SOURCE $TARGET',
'$OBJCOPY -O binary -j .header -j .flash -j .data -j .sensitive $SOURCE $TARGET',
'$HEADERTOOL $TARGET ' + ('-D' if ARGUMENTS.get('PRODUCTION', '0') == '0' else ''),
'$CP $TARGET ' + BINARY_NAME,
], )

@ -89,7 +89,6 @@ SOURCE_MOD += [
'vendor/micropython/lib/uzlib/adler32.c',
'vendor/micropython/lib/uzlib/crc32.c',
'vendor/micropython/lib/uzlib/tinflate.c',
'vendor/trezor-storage/flash_common.c',
]
if TREZOR_MODEL in ('1', ):

@ -54,7 +54,6 @@ SOURCE_MOD += [
'embed/extmod/modtrezorconfig/modtrezorconfig.c',
'vendor/trezor-storage/norcow.c',
'vendor/trezor-storage/storage.c',
'vendor/trezor-storage/flash_common.c',
]
# modtrezorcrypto
@ -336,16 +335,6 @@ SOURCE_MICROPYTHON_SPEED = [
'vendor/micropython/py/vm.c',
]
SOURCE_FIRMWARE = [
'embed/firmware/bl_check.c',
'embed/firmware/delay.c',
'embed/firmware/header.S',
'embed/firmware/main.c',
'embed/firmware/mphalport.c',
'embed/firmware/nlrthumb.c',
'embed/firmware/startup.S',
]
CPPDEFINES_MOD += ['USE_SVC_SHUTDOWN']
if FEATURE_FLAGS["RDI"]:
@ -380,6 +369,18 @@ env = Environment(ENV=os.environ, CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODU
FEATURES_AVAILABLE = tools.configure_board(TREZOR_MODEL, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL)
FILE_SUFFIX= env.get('ENV')['SUFFIX']
SOURCE_FIRMWARE = [
'embed/firmware/bl_check.c',
'embed/firmware/delay.c',
'embed/firmware/header.S',
'embed/firmware/main.c',
'embed/firmware/mphalport.c',
'embed/firmware/nlrthumb.c',
f'embed/firmware/startup_{FILE_SUFFIX}.S',
]
if TREZOR_MODEL in ('T', 'DISC1'):
UI_LAYOUT = 'UI_LAYOUT_TT'
@ -813,23 +814,31 @@ BINARY_NAME += "-dirty" if tools.get_git_modified() else ""
BINARY_NAME += ".bin"
if TREZOR_MODEL in ('T', 'R', 'DISC1'):
action_bin=[
'$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data --pad-to 0x08100000 $SOURCE ${TARGET}.p1',
'$OBJCOPY -O binary -j .flash2 $SOURCE ${TARGET}.p2',
'$CAT ${TARGET}.p1 ${TARGET}.p2 > $TARGET',
'$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''),
'$DD if=$TARGET of=${TARGET}.p1 skip=0 bs=128k count=6',
'$CP $TARGET ' + BINARY_NAME,
]
elif TREZOR_MODEL in ('1',):
if TREZOR_MODEL in ('1',):
action_bin=[
'$OBJCOPY -O binary -j .header -j .flash -j .data $SOURCE $TARGET',
'$OBJCOPY -O binary -j .header -j .flash -j .data -j .sensitive $SOURCE $TARGET',
'../legacy/bootloader/firmware_sign.py -f $TARGET',
'$CP $TARGET ' + BINARY_NAME,
]
else:
raise ValueError('Unknown Trezor model')
if 'STM32F427xx' in CPPDEFINES_HAL or 'STM32F429xx' in CPPDEFINES_HAL:
action_bin=[
'$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .sensitive --pad-to 0x08100000 $SOURCE ${TARGET}.p1',
'$OBJCOPY -O binary -j .flash2 $SOURCE ${TARGET}.p2',
'$CAT ${TARGET}.p1 ${TARGET}.p2 > $TARGET',
'$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''),
'$DD if=$TARGET of=${TARGET}.p1 skip=0 bs=128k count=6',
'$CP $TARGET ' + BINARY_NAME,
]
elif 'STM32U5A9xx' in CPPDEFINES_HAL:
action_bin=[
'$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .sensitive $SOURCE ${TARGET}',
'$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''),
'$CP $TARGET ' + BINARY_NAME,
]
else:
raise Exception("Unknown MCU")
program_bin = env.Command(
target='firmware.bin',

@ -87,21 +87,8 @@ SOURCE_MOD += [
'vendor/micropython/lib/uzlib/adler32.c',
'vendor/micropython/lib/uzlib/crc32.c',
'vendor/micropython/lib/uzlib/tinflate.c',
'vendor/trezor-storage/flash_common.c',
]
SOURCE_PRODTEST = [
'embed/prodtest/startup.s',
'embed/prodtest/header.S',
'embed/prodtest/main.c',
'embed/prodtest/prodtest_common.c',
]
if TREZOR_MODEL in ('R',):
SOURCE_PRODTEST += [
'embed/prodtest/optiga_prodtest.c',
]
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
@ -113,6 +100,21 @@ env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('
FEATURES_AVAILABLE = tools.configure_board(TREZOR_MODEL, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL)
FILE_SUFFIX= env.get('ENV')['SUFFIX']
SOURCE_PRODTEST = [
f'embed/prodtest/startup_{FILE_SUFFIX}.s',
'embed/prodtest/header.S',
'embed/prodtest/main.c',
'embed/prodtest/prodtest_common.c',
]
if 'optiga' in FEATURES_AVAILABLE:
SOURCE_PRODTEST += [
'embed/prodtest/optiga_prodtest.c',
]
env.Replace(
CP='cp',
AS='arm-none-eabi-as',
@ -139,7 +141,7 @@ env.Replace(
'-fstack-protector-all '
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB',
LINKFLAGS='-T embed/prodtest/memory.ld -Wl,--gc-sections -Wl,-Map=build/prodtest/prodtest.map -Wl,--warn-common',
LINKFLAGS=f'-T embed/prodtest/memory_{FILE_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/prodtest/prodtest.map -Wl,--warn-common',
CPPPATH=[
'embed/prodtest',
'embed/lib',
@ -220,7 +222,7 @@ program_bin = env.Command(
target='prodtest.bin',
source=program_elf,
action=[
'$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data $SOURCE $TARGET',
'$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .sensitive $SOURCE $TARGET',
'$HEADERTOOL $TARGET ' + ('-D' if ARGUMENTS.get('PRODUCTION', '0') == '0' else ''),
'$CP $TARGET ' + BINARY_NAME,
], )

@ -63,13 +63,6 @@ SOURCE_MOD += [
'vendor/micropython/lib/uzlib/adler32.c',
'vendor/micropython/lib/uzlib/crc32.c',
'vendor/micropython/lib/uzlib/tinflate.c',
'vendor/trezor-storage/flash_common.c',
]
SOURCE_REFLASH = [
'embed/reflash/startup.s',
'embed/reflash/header.S',
'embed/reflash/main.c',
]
# fonts
@ -83,6 +76,14 @@ env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('
FEATURES_AVAILABLE = tools.configure_board(TREZOR_MODEL, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL)
FILE_SUFFIX= env.get('ENV')['SUFFIX']
SOURCE_REFLASH = [
f'embed/reflash/startup_{FILE_SUFFIX}.s',
'embed/reflash/header.S',
'embed/reflash/main.c',
]
env.Replace(
CP='cp',
AS='arm-none-eabi-as',
@ -109,7 +110,7 @@ env.Replace(
'-fstack-protector-all '
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB',
LINKFLAGS='-T embed/reflash/memory.ld -Wl,--gc-sections -Wl,-Map=build/reflash/reflash.map -Wl,--warn-common',
LINKFLAGS=f'-T embed/reflash/memory_{FILE_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/reflash/reflash.map -Wl,--warn-common',
CPPPATH=[
'embed/reflash',
'embed/lib',
@ -180,7 +181,7 @@ program_bin = env.Command(
target='reflash.bin',
source=program_elf,
action=[
'$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data $SOURCE $TARGET',
'$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .sensitive $SOURCE $TARGET',
'$HEADERTOOL $TARGET ' + ('-D' if ARGUMENTS.get('PRODUCTION', '0') == '0' else ''),
'$CP $TARGET ' + BINARY_NAME,
], )

@ -58,7 +58,6 @@ SOURCE_MOD += [
'embed/extmod/modtrezorconfig/modtrezorconfig.c',
'vendor/trezor-storage/norcow.c',
'vendor/trezor-storage/storage.c',
'vendor/trezor-storage/flash_common.c',
]
# modtrezorcrypto

@ -27,7 +27,9 @@
#include "flash.h"
#include "image.h"
#include "model.h"
#include "mpu.h"
#include "rng.h"
#ifdef USE_SD_CARD
#include "sdcard.h"
#endif
@ -41,6 +43,12 @@
#include "memzero.h"
#ifdef STM32U5
#include "secret.h"
#include "tamper.h"
#include "trustzone.h"
#endif
const uint8_t BOARDLOADER_KEY_M = 2;
const uint8_t BOARDLOADER_KEY_N = 3;
static const uint8_t * const BOARDLOADER_KEYS[] = {
@ -53,6 +61,44 @@ static const uint8_t * const BOARDLOADER_KEYS[] = {
#endif
};
#ifdef STM32U5
void check_bootloader_version(uint8_t bld_version) {
const uint8_t *counter_addr =
flash_area_get_address(&SECRET_AREA, SECRET_MONOTONIC_COUNTER_OFFSET,
SECRET_MONOTONIC_COUNTER_LEN);
ensure((counter_addr != NULL) * sectrue, "counter_addr is NULL");
int counter = 0;
for (int i = 0; i < SECRET_MONOTONIC_COUNTER_LEN / 16; i++) {
secbool not_cleared = sectrue;
for (int j = 0; j < 16; j++) {
if (counter_addr[i * 16 + j] != 0xFF) {
not_cleared = secfalse;
break;
}
}
if (not_cleared != sectrue) {
counter++;
} else {
break;
}
}
ensure((bld_version >= counter) * sectrue, "BOOTLOADER DOWNGRADED");
if (bld_version > counter) {
for (int i = 0; i < bld_version; i++) {
uint32_t data[4] = {0};
secret_write((uint8_t *)data, SECRET_MONOTONIC_COUNTER_OFFSET + i * 16,
16);
}
}
}
#endif
struct BoardCapabilities capablities
__attribute__((section(".capabilities_section"))) = {
.header = CAPABILITIES_HEADER,
@ -193,7 +239,29 @@ int main(void) {
return 2;
}
#ifdef STM32U5
tamper_init();
if (sectrue == secret_bhk_locked()) {
delete_secrets();
NVIC_SystemReset();
}
#endif
#ifdef STM32F4
clear_otg_hs_memory();
#endif
mpu_config_boardloader();
#ifdef USE_SDRAM
sdram_init();
#endif
#ifdef STM32U5
trustzone_init();
trustzone_run();
#endif
#ifdef USE_SDRAM
sdram_init();
@ -224,8 +292,22 @@ int main(void) {
ensure(check_image_contents(hdr, IMAGE_HEADER_SIZE, &BOOTLOADER_AREA),
"invalid bootloader hash");
#ifdef STM32U5
check_bootloader_version(hdr->monotonic);
#endif
ensure_compatible_settings();
mpu_config_off();
#ifdef STM32U5
if (_stay_in_bootloader_flag_addr == STAY_IN_BOOTLOADER_FLAG) {
_stay_in_bootloader_flag_addr = 0;
jump_to_with_flag(BOOTLOADER_START + IMAGE_HEADER_SIZE,
STAY_IN_BOOTLOADER_FLAG);
}
#endif
jump_to(BOOTLOADER_START + IMAGE_HEADER_SIZE);
return 0;

@ -0,0 +1,104 @@
/* Trezor v2 boardloader linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C004000, LENGTH = 48K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 512K
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
}
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100;
_estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */
data_lma = LOADADDR(.data);
data_vma = ADDR(.data);
data_size = SIZEOF(.data);
/* used by the startup code to populate variables used by the C code */
sensitive_lma = LOADADDR(.sensitive);
sensitive_vma = ADDR(.sensitive);
sensitive_size = SIZEOF(.sensitive);
/* used by the startup code to wipe memory */
sram1_start = ORIGIN(SRAM1);
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
sram2_start = ORIGIN(SRAM2);
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
sram3_start = ORIGIN(SRAM3);
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
sram4_start = ORIGIN(SRAM4);
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
sram5_start = ORIGIN(SRAM5);
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
sram6_start = ORIGIN(SRAM6);
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
/* IMAGE_HEADER_SIZE is 0x400, this is for interaction-less firmware update start */
firmware_header_start = sram1_end - 0x400;
_stay_in_bootloader_flag_addr = ABSOLUTE(sram1_end - 0x400 - 4);
SECTIONS {
.vector_table : ALIGN(512) {
KEEP(*(.vector_table));
} >FLASH AT>FLASH
.text : ALIGN(4) {
*(.text*);
. = ALIGN(4); /* make the section size a multiple of the word size */
} >FLASH AT>FLASH
.rodata : ALIGN(4) {
*(.rodata*);
. = ALIGN(4); /* make the section size a multiple of the word size */
} >FLASH AT>FLASH
.data : ALIGN(4) {
*(.data*);
. = ALIGN(512);
} >SRAM1 AT>FLASH
/DISCARD/ : {
*(.ARM.exidx*);
}
.bss : ALIGN(4) {
*(.bss*);
. = ALIGN(4);
} >SRAM1
.buf : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
} >SRAM1
.stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
} >SRAM2
.sensitive : ALIGN(8) {
*(.sensitive*);
. = ALIGN(4);
} >SRAM2 AT>FLASH
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
} >SRAM3
.fb2 : ALIGN(4) {
*(.fb2*);
. = ALIGN(4);
} >SRAM5
/* Hard-coded address for capabilities structure */
.capabilities 0x0C00FF00 : {KEEP(*(.capabilities_section))}
}

@ -0,0 +1,110 @@
.syntax unified
.text
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
bl SystemInit
// read the first rng data and save it
ldr r0, =0 // r0 - previous value
ldr r1, =0 // r1 - whether to compare the previous value
bl rng_read
// read the next rng data and make sure it is different than previous
// r0 - value returned from previous call
ldr r1, =1 // r1 - whether to compare the previous value
bl rng_read
mov r4, r0 // save TRNG output in r4
// wipe memory to remove any possible vestiges of sensitive data
ldr r1, =_stay_in_bootloader_flag_addr // r0 - address of storage for "stay in bootloader" flag
ldr r2, [r1]
ldr r3, =0x0FC35A96
sub r2, r2, r3
cbz r2, fill_ram
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
fill_ram:
ldr r0, =sram1_start // r0 - point to beginning of SRAM
mov r2, r4 // r2 - the word-sized value to be written
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
mov r2, r4 // r2 - the word-sized value to be written
bl memset_reg
ldr r0, =sram3_start // r0 - point to beginning of SRAM
ldr r1, =sram3_end // r1 - point to byte after the end of SRAM
mov r2, r4 // r2 - the word-sized value to be written
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
mov r2, r4 // r2 - the word-sized value to be written
bl memset_reg
ldr r0, =sram5_start // r0 - point to beginning of SRAM
ldr r1, =sram5_end // r1 - point to byte after the end of SRAM
mov r2, r4 // r2 - the word-sized value to be written
bl memset_reg
// setup environment for subsequent stage of code
ldr r1, =_stay_in_bootloader_flag_addr // r0 - address of storage for "stay in bootloader" flag
ldr r2, [r1]
ldr r3, =0x0FC35A96
sub r2, r2, r3
cbz r2, clear_ram
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
clear_ram:
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram3_start // r0 - point to beginning of SRAM
ldr r1, =sram3_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram5_start // r0 - point to beginning of SRAM
ldr r1, =sram5_end // r1 - point to byte after the end of SRAM
bl memset_reg
// copy data in from flash
ldr r0, =data_vma // dst addr
ldr r1, =data_lma // src addr
ldr r2, =data_size // size in bytes
bl memcpy
// copy sensitive data in from flash
ldr r0, =sensitive_vma // dst addr
ldr r1, =sensitive_lma // src addr
ldr r2, =sensitive_size // size in bytes
bl memcpy
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
bl rng_get
ldr r1, = __stack_chk_guard
str r0, [r1]
// enter the application code
bl main
b shutdown_privileged
.end

@ -24,6 +24,7 @@
#include "display.h"
#include "flash.h"
#include "image.h"
#include "lowlevel.h"
#include "messages.pb.h"
#include "random_delays.h"
#include "secbool.h"
@ -89,9 +90,10 @@ typedef enum {
RETURN_TO_MENU = 0x55667788,
} usb_result_t;
volatile secbool dont_optimize_out_true = sectrue;
void failed_jump_to_firmware(void);
volatile void (*firmware_jump_fn)(void) = failed_jump_to_firmware;
SENSITIVE volatile secbool dont_optimize_out_true = sectrue;
SENSITIVE volatile void (*firmware_jump_fn)(void) = failed_jump_to_firmware;
static void usb_init_all(secbool usb21_landing) {
usb_dev_info_t dev_info = {
@ -226,7 +228,7 @@ static usb_result_t bootloader_usb_loop(const vendor_header *const vhdr,
case MessageType_MessageType_GetFeatures:
process_msg_GetFeatures(USB_IFACE_NUM, msg_size, buf, vhdr, hdr);
break;
#ifdef USE_OPTIGA
#if defined USE_OPTIGA && !defined STM32U5
case MessageType_MessageType_UnlockBootloader:
response = ui_screen_unlock_bootloader_confirm();
if (INPUT_CANCEL == response) {
@ -275,7 +277,7 @@ static secbool check_vendor_header_lock(const vendor_header *const vhdr) {
// protection against bootloader downgrade
#if PRODUCTION
#if PRODUCTION && !defined STM32U5
static void check_bootloader_version(void) {
uint8_t bits[FLASH_OTP_BLOCK_SIZE];
@ -334,11 +336,30 @@ void real_jump_to_firmware(void) {
&FIRMWARE_AREA),
"Firmware is corrupted");
#ifdef STM32U5
secret_bhk_provision();
secret_bhk_lock();
#ifdef USE_OPTIGA
if (sectrue == secret_optiga_present()) {
secret_optiga_backup();
secret_hide();
}
#else
secret_hide();
#endif
#endif
#ifdef USE_OPTIGA
#ifdef STM32U5
if ((vhdr.vtrust & VTRUST_SECRET) != 0) {
secret_optiga_hide();
}
#else
if (((vhdr.vtrust & VTRUST_SECRET) != 0) && (sectrue != secret_wiped())) {
ui_screen_install_restricted();
trezor_shutdown();
}
#endif
#endif
// if all VTRUST flags are unset = ultimate trust => skip the procedure
@ -374,6 +395,18 @@ void real_jump_to_firmware(void) {
jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE);
}
#ifdef STM32U5
__attribute__((noreturn)) void jump_to_fw_through_reset(void) {
display_fade(display_backlight(-1), 0, 200);
__disable_irq();
delete_secrets();
NVIC_SystemReset();
for (;;)
;
}
#endif
#ifndef TREZOR_EMULATOR
int main(void) {
// grab "stay in bootloader" flag as soon as possible
@ -384,7 +417,21 @@ int bootloader_main(void) {
#endif
random_delays_init();
// display_init_seq();
#ifdef STM32U5
if (sectrue != flash_configure_sec_area_ob()) {
#ifdef STM32U5
secret_bhk_regenerate();
#endif
const secbool r =
flash_area_erase_bulk(STORAGE_AREAS, STORAGE_AREAS_COUNT, NULL);
(void)r;
__disable_irq();
HAL_NVIC_SystemReset();
}
#endif
#ifdef USE_DMA2D
dma2d_init();
#endif
@ -478,7 +525,8 @@ int bootloader_main(void) {
unit_variant_init();
#if PRODUCTION
#if PRODUCTION && !defined STM32U5
// for STM32U5, this check is moved to boardloader
check_bootloader_version();
#endif
@ -530,6 +578,9 @@ int bootloader_main(void) {
} else {
screen = SCREEN_WELCOME;
#ifdef STM32U5
secret_bhk_regenerate();
#endif
// erase storage
ensure(flash_area_erase_bulk(STORAGE_AREAS, STORAGE_AREAS_COUNT, NULL),
NULL);
@ -586,7 +637,9 @@ int bootloader_main(void) {
screen = SCREEN_INTRO;
}
if (ui_result == 0x11223344) { // reboot
#ifndef STM32U5
ui_screen_boot_empty(true);
#endif
continue_to_firmware = firmware_present;
continue_to_firmware_backup = firmware_present_backup;
}
@ -636,6 +689,10 @@ int bootloader_main(void) {
if (continue_to_firmware != continue_to_firmware_backup) {
// erase storage if we saw flips randomly flip, most likely due to
// glitch
#ifdef STM32U5
secret_bhk_regenerate();
#endif
ensure(flash_area_erase_bulk(STORAGE_AREAS, STORAGE_AREAS_COUNT, NULL),
NULL);
}
@ -643,7 +700,11 @@ int bootloader_main(void) {
(continue_to_firmware == continue_to_firmware_backup),
NULL);
if (sectrue == continue_to_firmware) {
#ifdef STM32U5
firmware_jump_fn = jump_to_fw_through_reset;
#else
firmware_jump_fn = real_jump_to_firmware;
#endif
break;
}
}
@ -651,13 +712,19 @@ int bootloader_main(void) {
ensure(dont_optimize_out_true * (firmware_present == firmware_present_backup),
NULL);
#ifdef STM32U5
if (sectrue == firmware_present &&
firmware_jump_fn != jump_to_fw_through_reset) {
firmware_jump_fn = real_jump_to_firmware;
}
#else
if (sectrue == firmware_present) {
firmware_jump_fn = real_jump_to_firmware;
}
#endif
firmware_jump_fn();
return 0;
}
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }

@ -9,6 +9,8 @@ MEMORY {
}
main_stack_base = ORIGIN(CCMRAM) + SIZEOF(.stack) ; /* 8-byte aligned full descending stack */
_sstack = ORIGIN(CCMRAM);
_estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */
data_lma = LOADADDR(.data);

@ -0,0 +1,100 @@
/* Trezor v2 bootloader linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C010000, LENGTH = 128K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 512K
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
}
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100;
_estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */
data_lma = LOADADDR(.data);
data_vma = ADDR(.data);
data_size = SIZEOF(.data);
/* used by the startup code to populate variables used by the C code */
sensitive_lma = LOADADDR(.sensitive);
sensitive_vma = ADDR(.sensitive);
sensitive_size = SIZEOF(.sensitive);
/* used by the startup code to wipe memory */
sram1_start = ORIGIN(SRAM1);
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
sram2_start = ORIGIN(SRAM2);
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
sram3_start = ORIGIN(SRAM3);
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
sram4_start = ORIGIN(SRAM4);
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
sram5_start = ORIGIN(SRAM5);
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
sram6_start = ORIGIN(SRAM6);
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
/* IMAGE_HEADER_SIZE is 0x400, this is for interaction-less firmware update start */
firmware_header_start = sram1_end - 0x400;
_stay_in_bootloader_flag_addr = ABSOLUTE(sram1_end - 0x400 - 4);
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
SECTIONS {
.header : ALIGN(4) {
KEEP(*(.header));
} >FLASH AT>FLASH
.flash : ALIGN(512) {
KEEP(*(.vector_table));
. = ALIGN(4);
*(.text*);
. = ALIGN(4);
*(.rodata*);
. = ALIGN(512);
} >FLASH AT>FLASH
.data : ALIGN(4) {
*(.data*);
. = ALIGN(512);
} >SRAM1 AT>FLASH
/DISCARD/ : {
*(.ARM.exidx*);
}
.bss : ALIGN(4) {
*(.bss*);
. = ALIGN(4);
} >SRAM1
.buf : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
} >SRAM1
.stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
} >SRAM2
.sensitive : ALIGN(512) {
*(.sensitive*);
. = ALIGN(512);
} >SRAM2 AT>FLASH
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
} >SRAM3
.fb2 : ALIGN(4) {
*(.fb2*);
. = ALIGN(4);
} >SRAM5
}

@ -582,7 +582,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
&should_keep_seed, &is_newvendor);
}
#ifdef USE_OPTIGA
#if defined USE_OPTIGA && !defined STM32U5
if (sectrue != secret_wiped() && ((vhdr.vtrust & VTRUST_SECRET) != 0)) {
MSG_SEND_INIT(Failure);
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
@ -611,6 +611,9 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
// if firmware is not upgrade, erase storage
if (sectrue != should_keep_seed) {
#ifdef STM32U5
secret_bhk_regenerate();
#endif
ensure(flash_area_erase_bulk(STORAGE_AREAS, STORAGE_AREAS_COUNT, NULL),
NULL);
}
@ -671,11 +674,11 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
const uint32_t *const src = (const uint32_t *const)CHUNK_BUFFER_PTR;
for (int i = 0; i < chunk_size / (sizeof(uint32_t) * 4); i++) {
ensure(flash_area_write_quadword(
for (int i = 0; i < chunk_size / (sizeof(uint32_t) * 8 * 4); i++) {
ensure(flash_area_write_burst(
&FIRMWARE_AREA,
firmware_block * IMAGE_CHUNK_SIZE + i * 4 * sizeof(uint32_t),
&src[4 * i]),
firmware_block * IMAGE_CHUNK_SIZE + i * 8 * 4 * sizeof(uint32_t),
&src[8 * 4 * i]),
NULL);
}
@ -743,7 +746,7 @@ void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf) {
MSG_SEND(Failure);
}
#ifdef USE_OPTIGA
#if defined USE_OPTIGA && !defined STM32U5
void process_msg_UnlockBootloader(uint8_t iface_num, uint32_t msg_size,
uint8_t *buf) {
secret_erase();

@ -0,0 +1,59 @@
.syntax unified
.text
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram3_start // r0 - point to beginning of SRAM
ldr r1, =sram3_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram5_start // r0 - point to beginning of SRAM
ldr r1, =sram5_end // r1 - point to byte after the end of SRAM
bl memset_reg
// copy data in from flash
ldr r0, =data_vma // dst addr
ldr r1, =data_lma // src addr
ldr r2, =data_size // size in bytes
bl memcpy
// copy sensitive data in from flash
ldr r0, =sensitive_vma // dst addr
ldr r1, =sensitive_lma // src addr
ldr r2, =sensitive_size // size in bytes
bl memcpy
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
bl rng_get
ldr r1, = __stack_chk_guard
str r0, [r1]
// re-enable exceptions
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
// subsequent operations, it is not necessary to insert a memory barrier instruction."
cpsie f
// enter the application code
bl main
b shutdown_privileged
.end

@ -0,0 +1,100 @@
/* Trezor v2 bootloader linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C010000, LENGTH = 128K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 512K
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
}
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100;
_estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */
data_lma = LOADADDR(.data);
data_vma = ADDR(.data);
data_size = SIZEOF(.data);
/* used by the startup code to populate variables used by the C code */
sensitive_lma = LOADADDR(.sensitive);
sensitive_vma = ADDR(.sensitive);
sensitive_size = SIZEOF(.sensitive);
/* used by the startup code to wipe memory */
sram1_start = ORIGIN(SRAM1);
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
sram2_start = ORIGIN(SRAM2);
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
sram3_start = ORIGIN(SRAM3);
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
sram4_start = ORIGIN(SRAM4);
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
sram5_start = ORIGIN(SRAM5);
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
sram6_start = ORIGIN(SRAM6);
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
/* IMAGE_HEADER_SIZE is 0x400, this is for interaction-less firmware update start */
firmware_header_start = sram1_end - 0x400;
_stay_in_bootloader_flag_addr = ABSOLUTE(sram1_end - 0x400 - 4);
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
SECTIONS {
.header : ALIGN(4) {
KEEP(*(.header));
} >FLASH AT>FLASH
.flash : ALIGN(512) {
KEEP(*(.vector_table));
. = ALIGN(4);
*(.text*);
. = ALIGN(4);
*(.rodata*);
. = ALIGN(512);
} >FLASH AT>FLASH
.data : ALIGN(4) {
*(.data*);
. = ALIGN(512);
} >SRAM1 AT>FLASH
/DISCARD/ : {
*(.ARM.exidx*);
}
.bss : ALIGN(4) {
*(.bss*);
. = ALIGN(4);
} >SRAM1
.buf : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
} >SRAM1
.stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
} >SRAM2
.sensitive : ALIGN(512) {
*(.sensitive*);
. = ALIGN(512);
} >SRAM2 AT>FLASH
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
} >SRAM3
.fb2 : ALIGN(4) {
*(.fb2*);
. = ALIGN(4);
} >SRAM5
}

@ -0,0 +1,59 @@
.syntax unified
.text
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram3_start // r0 - point to beginning of SRAM
ldr r1, =sram3_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram5_start // r0 - point to beginning of SRAM
ldr r1, =sram5_end // r1 - point to byte after the end of SRAM
bl memset_reg
// copy data in from flash
ldr r0, =data_vma // dst addr
ldr r1, =data_lma // src addr
ldr r2, =data_size // size in bytes
bl memcpy
// copy sensitive data in from flash
ldr r0, =sensitive_vma // dst addr
ldr r1, =sensitive_lma // src addr
ldr r2, =sensitive_size // size in bytes
bl memcpy
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
bl rng_get
ldr r1, = __stack_chk_guard
str r0, [r1]
// re-enable exceptions
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
// subsequent operations, it is not necessary to insert a memory barrier instruction."
cpsie f
// enter the application code
bl main
b shutdown_privileged
.end

@ -47,6 +47,7 @@
#include "model.h"
#include "mpu.h"
#include "random_delays.h"
#include "secure_aes.h"
#include TREZOR_BOARD
@ -74,10 +75,13 @@
#ifdef USE_OPTIGA
#include "optiga_commands.h"
#include "optiga_transport.h"
#include "secret.h"
#endif
#include "unit_variant.h"
#if defined USE_OPTIGA | defined STM32U5
#include "secret.h"
#endif
#ifdef SYSTEM_VIEW
#include "systemview.h"
#endif
@ -118,8 +122,7 @@ int main(void) {
#ifdef USE_OPTIGA
uint8_t secret[SECRET_OPTIGA_KEY_LEN] = {0};
secbool secret_ok =
secret_read(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
secbool secret_ok = secret_optiga_extract(secret);
#endif
#if PRODUCTION || BOOTLOADER_QA
@ -145,6 +148,10 @@ int main(void) {
set_core_clock(CLOCK_180_MHZ);
#endif
#ifdef STM32U5
secure_aes_init();
#endif
#ifdef USE_BUTTON
button_init();
#endif
@ -225,25 +232,6 @@ void __attribute__((noreturn)) nlr_jump_fail(void *val) {
error_shutdown("INTERNAL ERROR", "(UE)");
}
// interrupt handlers
void NMI_Handler(void) {
// Clock Security System triggered NMI
if ((RCC->CIR & RCC_CIR_CSSF) != 0) {
error_shutdown("INTERNAL ERROR", "(CS)");
}
}
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }
void MemManage_Handler_MM(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
void MemManage_Handler_SO(void) { error_shutdown("INTERNAL ERROR", "(SO)"); }
void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }
void UsageFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(UF)"); }
__attribute__((noreturn)) void reboot_to_bootloader() {
mpu_config_bootloader();
jump_to_with_flag(BOOTLOADER_START + IMAGE_HEADER_SIZE,
@ -294,11 +282,19 @@ void SVC_C_Handler(uint32_t *stack) {
__asm__ volatile("msr control, %0" ::"r"(0x0));
__asm__ volatile("isb");
#ifdef STM32U5
_stay_in_bootloader_flag_addr = STAY_IN_BOOTLOADER_FLAG;
__disable_irq();
delete_secrets();
NVIC_SystemReset();
#else
// See stack layout in
// https://developer.arm.com/documentation/ka004005/latest We are changing
// return address in PC to land into reboot to avoid any bug with ROP and
// raising privileges.
stack[6] = (uintptr_t)reboot_to_bootloader;
#endif
return;
case SVC_GET_SYSTICK_VAL: {
systick_val_copy = SysTick->VAL;

@ -61,16 +61,4 @@ reset_handler:
b shutdown_privileged
.global MemManage_Handler
.type MemManage_Handler, STT_FUNC
MemManage_Handler:
ldr r2, =_sstack
mrs r1, msp
ldr r0, =_estack
msr msp, r0
cmp r1, r2
IT lt
bllt MemManage_Handler_SO
bl MemManage_Handler_MM
.end

@ -0,0 +1,52 @@
.syntax unified
.text
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
// copy data in from flash
ldr r0, =data_vma // dst addr
ldr r1, =data_lma // src addr
ldr r2, =data_size // size in bytes
bl memcpy
// copy sensitive data in from flash
ldr r0, =sensitive_vma // dst addr
ldr r1, =sensitive_lma // src addr
ldr r2, =sensitive_size // size in bytes
bl memcpy
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
bl rng_get
ldr r1, = __stack_chk_guard
str r0, [r1]
// re-enable exceptions
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
// subsequent operations, it is not necessary to insert a memory barrier instruction."
cpsie f
// enter the application code
bl main
b shutdown_privileged
.end

@ -15,6 +15,7 @@
extern const flash_area_t STORAGE_AREAS[STORAGE_AREAS_COUNT];
extern const flash_area_t BOARDLOADER_AREA;
extern const flash_area_t SECRET_AREA;
extern const flash_area_t BHK_AREA;
extern const flash_area_t BOOTLOADER_AREA;
extern const flash_area_t FIRMWARE_AREA;
extern const flash_area_t WIPE_AREA;

@ -19,6 +19,7 @@
(const uint8_t *)"\xee\x93\xa4\xf6\x6f\x8d\x16\xb8\x19\xbb\x9b\xeb\x9f\xfc\xcd\xfc\xdc\x14\x12\xe8\x7f\xee\x6a\x32\x4c\x2a\x99\xa1\xe0\xe6\x71\x48",
#define BOARDLOADER_START 0x08000000
#define BOARD_CAPABILITIES_ADDR 0x0800BF00
#define BOOTLOADER_START 0x08020000
#define FIRMWARE_START 0x08040000

@ -19,6 +19,7 @@
(const uint8_t *)"\x07\xc8\x51\x34\x94\x6b\xf8\x9f\xa1\x9b\xdc\x2c\x5e\x5f\xf9\xce\x01\x29\x65\x08\xee\x08\x63\xd0\xff\x6d\x63\x33\x1d\x1a\x25\x16",
#define BOARDLOADER_START 0x08000000
#define BOARD_CAPABILITIES_ADDR 0x0800BF00
#define BOOTLOADER_START 0x08020000
#define FIRMWARE_START 0x08040000

@ -19,6 +19,7 @@
(const uint8_t *)"\xb8\x30\x7a\x71\xf5\x52\xc6\x0a\x4c\xbb\x31\x7f\xf4\x8b\x82\xcd\xbf\x6b\x6b\xb5\xf0\x4c\x92\x0f\xec\x7b\xad\xf0\x17\x88\x37\x51",
#define BOARDLOADER_START 0x08000000
#define BOARD_CAPABILITIES_ADDR 0x0800BF00
#define BOOTLOADER_START 0x08020000
#define FIRMWARE_START 0x08040000

@ -690,5 +690,3 @@ __attribute__((naked)) void SVC_Handler(void) {
" b SVC_C_Handler \n" // Off to C land
);
}
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR!", "(HF)"); }

@ -0,0 +1,112 @@
/* TREZORv2 firmware linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 3648K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 512K
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
}
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100;
_estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */
data_lma = LOADADDR(.data);
data_vma = ADDR(.data);
data_size = SIZEOF(.data);
/* used by the startup code to populate variables used by the C code */
sensitive_lma = LOADADDR(.sensitive);
sensitive_vma = ADDR(.sensitive);
sensitive_size = SIZEOF(.sensitive);
/* used by the startup code to wipe memory */
sram1_start = ORIGIN(SRAM1);
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
sram2_start = ORIGIN(SRAM2);
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
sram3_start = ORIGIN(SRAM3);
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
sram4_start = ORIGIN(SRAM4);
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
sram5_start = ORIGIN(SRAM5);
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
sram6_start = ORIGIN(SRAM6);
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
_flash_start = ORIGIN(FLASH);
_flash_end = ORIGIN(FLASH) + LENGTH(FLASH);
_heap_start = ADDR(.heap);
_heap_end = ADDR(.heap) + SIZEOF(.heap);
SECTIONS {
.vendorheader : ALIGN(4) {
KEEP(*(.vendorheader))
} >FLASH AT>FLASH
.header : ALIGN(4) {
KEEP(*(.header));
} >FLASH AT>FLASH
.flash : ALIGN(512) {
KEEP(*(.vector_table));
. = ALIGN(4);
*(.text*);
. = ALIGN(4);
*(.rodata*);
. = ALIGN(4);
KEEP(*(.bootloader));
*(.bootloader*);
. = ALIGN(512);
} >FLASH AT>FLASH
.data : ALIGN(4) {
*(.data*);
. = ALIGN(512);
} >SRAM1 AT>FLASH
/DISCARD/ : {
*(.ARM.exidx*);
}
.bss : ALIGN(4) {
*(.bss*);
. = ALIGN(4);
} >SRAM1
.data_ccm : ALIGN(4) {
*(.no_dma_buffers*);
. = ALIGN(4);
} >SRAM1
.heap : ALIGN(4) {
. = 37K; /* this acts as a build time assertion that at least this much memory is available for heap use */
. = ABSOLUTE(sram1_end); /* this explicitly sets the end of the heap */
} >SRAM1
.stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
} >SRAM2
.sensitive : ALIGN(512) {
*(.sensitive*);
. = ALIGN(512);
} >SRAM2 AT>FLASH
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
} >SRAM3
.fb2 : ALIGN(4) {
*(.fb2*);
. = ALIGN(4);
} >SRAM5
}

@ -0,0 +1,52 @@
.syntax unified
.text
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
// copy data in from flash
ldr r0, =data_vma // dst addr
ldr r1, =data_lma // src addr
ldr r2, =data_size // size in bytes
bl memcpy
// copy sensitive data in from flash
ldr r0, =sensitive_vma // dst addr
ldr r1, =sensitive_lma // src addr
ldr r2, =sensitive_size // size in bytes
bl memcpy
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
bl rng_get
ldr r1, = __stack_chk_guard
str r0, [r1]
// re-enable exceptions
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
// subsequent operations, it is not necessary to insert a memory barrier instruction."
cpsie f
// enter the application code
bl main
b shutdown_privileged
.end

@ -0,0 +1,112 @@
/* TREZORv2 firmware linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 3648K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 512K
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
}
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100;
_estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */
data_lma = LOADADDR(.data);
data_vma = ADDR(.data);
data_size = SIZEOF(.data);
/* used by the startup code to populate variables used by the C code */
sensitive_lma = LOADADDR(.sensitive);
sensitive_vma = ADDR(.sensitive);
sensitive_size = SIZEOF(.sensitive);
/* used by the startup code to wipe memory */
sram1_start = ORIGIN(SRAM1);
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
sram2_start = ORIGIN(SRAM2);
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
sram3_start = ORIGIN(SRAM3);
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
sram4_start = ORIGIN(SRAM4);
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
sram5_start = ORIGIN(SRAM5);
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
sram6_start = ORIGIN(SRAM6);
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
_flash_start = ORIGIN(FLASH);
_flash_end = ORIGIN(FLASH) + LENGTH(FLASH);
_heap_start = ADDR(.heap);
_heap_end = ADDR(.heap) + SIZEOF(.heap);
SECTIONS {
.vendorheader : ALIGN(4) {
KEEP(*(.vendorheader))
} >FLASH AT>FLASH
.header : ALIGN(4) {
KEEP(*(.header));
} >FLASH AT>FLASH
.flash : ALIGN(512) {
KEEP(*(.vector_table));
. = ALIGN(4);
*(.text*);
. = ALIGN(4);
*(.rodata*);
. = ALIGN(4);
KEEP(*(.bootloader));
*(.bootloader*);
. = ALIGN(512);
} >FLASH AT>FLASH
.data : ALIGN(4) {
*(.data*);
. = ALIGN(512);
} >SRAM1 AT>FLASH
/DISCARD/ : {
*(.ARM.exidx*);
}
.bss : ALIGN(4) {
*(.bss*);
. = ALIGN(4);
} >SRAM1
.data_ccm : ALIGN(4) {
*(.no_dma_buffers*);
. = ALIGN(4);
} >SRAM1
.heap : ALIGN(4) {
. = 37K; /* this acts as a build time assertion that at least this much memory is available for heap use */
. = ABSOLUTE(sram1_end); /* this explicitly sets the end of the heap */
} >SRAM1
.stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
} >SRAM2
.sensitive : ALIGN(512) {
*(.sensitive*);
. = ALIGN(512);
} >SRAM2 AT>FLASH
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
} >SRAM3
.fb2 : ALIGN(4) {
*(.fb2*);
. = ALIGN(4);
} >SRAM5
}

@ -0,0 +1,52 @@
.syntax unified
.text
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
// copy data in from flash
ldr r0, =data_vma // dst addr
ldr r1, =data_lma // src addr
ldr r2, =data_size // size in bytes
bl memcpy
// copy sensitive data in from flash
ldr r0, =sensitive_vma // dst addr
ldr r1, =sensitive_lma // src addr
ldr r2, =sensitive_size // size in bytes
bl memcpy
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
bl rng_get
ldr r1, = __stack_chk_guard
str r0, [r1]
// re-enable exceptions
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
// subsequent operations, it is not necessary to insert a memory barrier instruction."
cpsie f
// enter the application code
bl main
b shutdown_privileged
.end

@ -382,7 +382,7 @@ fn generate_trezorhal_bindings() {
fn is_firmware() -> bool {
let target = env::var("TARGET").unwrap();
target.starts_with("thumbv7")
target.starts_with("thumbv7") || target.starts_with("thumbv8")
}
#[cfg(feature = "test")]

@ -10,6 +10,8 @@ use crate::{
geometry::{Alignment2D, Offset, Point, Rect},
},
};
#[cfg(feature = "framebuffer")]
use core::cmp::max;
#[cfg(feature = "dma2d")]

@ -35,7 +35,6 @@ Last tag must be terminator or all space used.
#include <stdint.h>
#define BOARD_CAPABILITIES_ADDR 0x0800BF00
#define BOARD_CAPABILITIES_SIZE 256
#define CAPABILITIES_HEADER "TRZC"

@ -57,6 +57,7 @@
extern uint8_t firmware_header_start;
extern uint8_t ccmram_start;
extern uint8_t ccmram_end;
extern uint32_t _stay_in_bootloader_flag_addr;
void __attribute__((noreturn)) trezor_shutdown(void);

@ -27,6 +27,7 @@ void flash_lock_option_bytes(void);
void flash_unlock_option_bytes(void);
uint32_t flash_set_option_bytes(void);
secbool flash_configure_option_bytes(void);
secbool flash_configure_sec_area_ob(void);
void periph_init(void);
secbool reset_flags_check(void);
void reset_flags_reset(void);

@ -21,6 +21,7 @@
#define __MPU_H__
void mpu_config_off(void);
void mpu_config_boardloader(void);
void mpu_config_bootloader(void);
void mpu_config_firmware(void);
void mpu_config_prodtest(void);

@ -7,6 +7,12 @@
#define SECRET_OPTIGA_KEY_OFFSET 16
#define SECRET_OPTIGA_KEY_LEN 32
#define SECRET_MONOTONIC_COUNTER_OFFSET 48
#define SECRET_MONOTONIC_COUNTER_LEN 1024
#define SECRET_BHK_OFFSET (1024 * 8)
#define SECRET_BHK_LEN 32
secbool secret_bootloader_locked(void);
void secret_write(uint8_t* data, uint32_t offset, uint32_t len);
@ -17,4 +23,22 @@ secbool secret_wiped(void);
void secret_erase(void);
void secret_hide(void);
void secret_write_header(void);
void secret_optiga_backup(void);
void secret_optiga_hide(void);
secbool secret_optiga_extract(uint8_t* dest);
void secret_bhk_lock(void);
secbool secret_bhk_locked(void);
void secret_bhk_regenerate(void);
void secret_bhk_provision(void);
secbool secret_optiga_present(void);

@ -0,0 +1,40 @@
/*
* 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/>.
*/
#ifndef TREZOR_HAL_SECURE_AES_H
#define TREZOR_HAL_SECURE_AES_H
#include <secbool.h>
#include <stddef.h>
#include <stdint.h>
// Initializes secure AES module
secbool secure_aes_init(void);
// Encrypts a block of data using AES-256 CBC and DHUK key
// Input and output must be aligned to 32 bits, size is in bytes
secbool secure_aes_encrypt(uint32_t* input, size_t size, uint32_t* output);
// Decrypts a block of data using AES-256 CBC and DHUK key
// Input and output must be aligned to 32 bits, size is in bytes
secbool secure_aes_decrypt(uint32_t* input, size_t size, uint32_t* output);
void secure_aes_test();
#endif // TREZOR_HAL_SECURE_AES_H

@ -20,6 +20,7 @@
#include "board_capabilities.h"
#include <string.h>
#include "common.h"
#include "model.h"
#define handle_fault(msg) \
(__fatal_error("Fault detected", msg, __FILE__, __LINE__, __func__))

@ -0,0 +1,18 @@
#include "common.h"
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }
void MemManage_Handler(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
void MemManage_Handler_SO(void) { error_shutdown("INTERNAL ERROR", "(SO)"); }
void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }
void UsageFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(UF)"); }
void NMI_Handler(void) {
// Clock Security System triggered NMI
if ((RCC->CIR & RCC_CIR_CSSF) != 0) {
error_shutdown("INTERNAL ERROR", "(CS)");
}
}

@ -160,4 +160,7 @@ static inline void restore_irq_pri(uint32_t state) {
#define IRQ_PRI_PENDSV NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 15, 0)
#define IRQ_PRI_RTC_WKUP NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 15, 0)
// !@# TAMPER interrupt priority should be probably much higher
#define IRQ_PRI_TAMP NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 15, 0)
#endif // MICROPY_INCLUDED_STM32_IRQ_H

@ -33,6 +33,10 @@ void mpu_config_off(void) {
HAL_MPU_Disable();
}
void mpu_config_boardloader(void) {
// nothing to be done
}
void mpu_config_bootloader(void) {
// Disable MPU
HAL_MPU_Disable();

@ -23,6 +23,7 @@
#include STM32_HAL_H
#include <stdint.h>
#define SENSITIVE
#define FLASH_BYTE_ACCESS 1
typedef enum {

@ -72,3 +72,7 @@ secbool secret_wiped(void) {
void secret_erase(void) {
ensure(flash_area_erase(&SECRET_AREA, NULL), "secret erase");
}
secbool secret_optiga_extract(uint8_t* dest) {
return secret_read(dest, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
}

@ -32,6 +32,8 @@
#define USB_PHY_ID USB_PHY_FS_ID
#elif defined(USE_USB_HS) && defined(USE_USB_HS_IN_FS)
#define USB_PHY_ID USB_PHY_HS_ID
#elif defined(USE_USB_HS) && !defined(USE_USB_HS_IN_FS)
#define USB_PHY_ID USB_PHY_HS_ID
#else
#error Unable to determine proper USB_PHY_ID to use
#endif

@ -83,6 +83,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
{
GPIO_InitTypeDef GPIO_InitStruct;
#ifdef USB_OTG_FS
if(hpcd->Instance == USB_OTG_FS)
{
/* Configure USB FS GPIOs */
@ -96,7 +97,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Configure VBUS Pin */
/* Configure VBUS Pin */
#if defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
// USB VBUS detect pin is always A9
GPIO_InitStruct.Pin = GPIO_PIN_9;
@ -124,9 +125,9 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
/* Enable USBFS Interrupt */
svc_enableIRQ(OTG_FS_IRQn);
}
#endif
#if defined(USE_USB_HS)
else if(hpcd->Instance == USB_OTG_HS)
{
if (hpcd->Instance == USB_OTG_HS) {
#if defined(USE_USB_HS_IN_FS)
/* Configure USB FS GPIOs */
@ -168,7 +169,53 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
/* Enable USB HS Clocks */
__USB_OTG_HS_CLK_ENABLE();
#else // !USE_USB_HS_IN_FS
#elif defined USE_USB_HS_INTERNAL_PHY && defined STM32U5
/* Configure DM and DP PINs */
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12);
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_USB_HS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
__HAL_RCC_SYSCFG_CLK_ENABLE();
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USBPHY;
PeriphClkInit.UsbPhyClockSelection = RCC_USBPHYCLKSOURCE_HSE;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
/** Set the OTG PHY reference clock selection
*/
HAL_SYSCFG_SetOTGPHYReferenceClockSelection(SYSCFG_OTG_HS_PHY_CLK_SELECT_1);
/* Peripheral clock enable */
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
__HAL_RCC_USBPHYC_CLK_ENABLE();
/* Enable VDDUSB */
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWREx_EnableVddUSB();
/*configure VOSR register of USB*/
HAL_PWREx_EnableUSBHSTranceiverSupply();
__HAL_RCC_PWR_CLK_DISABLE();
/*Configuring the SYSCFG registers OTG_HS PHY*/
/*OTG_HS PHY enable*/
HAL_SYSCFG_EnableOTGPHY(SYSCFG_OTG_HS_PHY_ENABLE);
#else // !USE_USB_HS_IN_FS && !USE_USB_HS_INTERNAL_PHY
/* Configure USB HS GPIOs */
__HAL_RCC_GPIOA_CLK_ENABLE();
@ -242,20 +289,22 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
*/
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
{
#ifdef USB_OTG_FS
if(hpcd->Instance == USB_OTG_FS)
{
/* Disable USB FS Clocks */
__HAL_RCC_USB_OTG_FS_CLK_DISABLE();
__HAL_RCC_SYSCFG_CLK_DISABLE();
}
#if defined(USE_USB_HS)
else if(hpcd->Instance == USB_OTG_HS)
#endif
#if defined(USE_USB_HS)
if(hpcd->Instance == USB_OTG_HS)
{
/* Disable USB FS Clocks */
__HAL_RCC_USB_OTG_HS_CLK_DISABLE();
__HAL_RCC_SYSCFG_CLK_DISABLE();
}
#endif
#endif
}
/*******************************************************************************
@ -440,6 +489,44 @@ USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev)
}
}
#endif
#if defined(USE_USB_HS) && !defined(USE_USB_HS_IN_FS) && defined STM32U5
// Trezor T uses the OTG_HS peripheral
if (pdev->id == USB_PHY_HS_ID) {
/* Set LL Driver parameters */
pcd_hs_handle.Instance = USB_OTG_HS;
pcd_hs_handle.Init.dev_endpoints = 6;
pcd_hs_handle.Init.use_dedicated_ep1 = 0;
pcd_hs_handle.Init.ep0_mps = 0x40;
pcd_hs_handle.Init.dma_enable = 0;
pcd_hs_handle.Init.low_power_enable = 0;
pcd_hs_handle.Init.phy_itface = USB_OTG_HS_EMBEDDED_PHY;
pcd_hs_handle.Init.Sof_enable = 1;
pcd_hs_handle.Init.speed = PCD_SPEED_HIGH;
// Trezor T hardware has PB13 connected to HS_VBUS
// but we leave vbus sensing disabled because
// we don't use it for anything. the device is a bus powered peripheral.
pcd_hs_handle.Init.vbus_sensing_enable = 0;
/* Link The driver to the stack */
pcd_hs_handle.pData = pdev;
pdev->pData = &pcd_hs_handle;
/* Initialize LL Driver */
HAL_PCD_Init(&pcd_hs_handle);
// the OTG_HS peripheral has a dedicated 4KiB data RAM from which we
// allocate an area for each transmit FIFO and the single shared receive FIFO.
// the configuration is in terms of 32-bit words, so we have 1024 32-bit words
// in this dedicated 4KiB data RAM to use. see section 35.10.1 and 34.11 in RM0090.
// the reference to section 34.11 is for the OTG_FS device, but the FIFO architecture
// diagram seems to apply similarly to the FIFO in the OTG_HS that we are using.
// USB packets that we deal with are 64 bytes in size which equates to 16 32-bit words.
// we size the transmit FIFO's equally and give the rest of the space to the receive FIFO.
const uint16_t transmit_fifo_size = 144; // 144 = 16 * 9 meaning that we give 9 packets of space for each transmit fifo
const uint16_t receive_fifo_zie = 160; // 160 = 1024 - 6 * 144 section 35.10.1 details what some of this is used for besides storing packets
HAL_PCDEx_SetRxFiFo(&pcd_hs_handle, receive_fifo_zie);
for (uint16_t i = 0; i < 6; i++) {
HAL_PCDEx_SetTxFiFo(&pcd_hs_handle, i, transmit_fifo_size);
}
}
#endif
#if defined(USE_USB_HS_IN_FS)
// Trezor T uses the OTG_HS peripheral
if (pdev->id == USB_PHY_HS_ID) {
@ -698,6 +785,7 @@ void OTG_HS_IRQHandler(void) {
}
#endif
#ifndef STM32U5
/**
* @brief This function handles USB OTG Common FS/HS Wakeup functions.
* @param *pcd_handle for FS or HS
@ -763,5 +851,6 @@ void OTG_HS_WKUP_IRQHandler(void) {
IRQ_EXIT(OTG_HS_WKUP_IRQn);
}
#endif
#endif
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

@ -167,4 +167,16 @@ shutdown_privileged:
ldr r0, =0
b . // loop forever
.global MemManage_Handler
.type MemManage_Handler, STT_FUNC
MemManage_Handler:
ldr r2, =_sstack
mrs r1, msp
ldr r0, =_estack
msr msp, r0
cmp r1, r2
IT lt
bllt MemManage_Handler_SO
bl MemManage_Handler_MM
.end

@ -0,0 +1 @@
../stm32f4/board_capabilities.c

@ -0,0 +1,204 @@
/*
* 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 STM32_HAL_H
#include <string.h>
#include "common.h"
#include "display.h"
#include "secret.h"
#ifdef FANCY_FATAL_ERROR
#include "rust_ui.h"
#endif
#include "flash.h"
#include "model.h"
#include "platform.h"
#include "rand.h"
#include "supervise.h"
#include "mini_printf.h"
#include "stm32u5xx_ll_utils.h"
#ifdef RGB16
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
#else
#define COLOR_FATAL_ERROR COLOR_BLACK
#endif
uint32_t systick_val_copy = 0;
// from util.s
extern void shutdown_privileged(void);
void __attribute__((noreturn)) trezor_shutdown(void) {
__HAL_RCC_SAES_CLK_DISABLE();
// Erase all secrets
TAMP->CR2 |= TAMP_CR2_BKERASE;
#ifdef USE_SVC_SHUTDOWN
svc_shutdown();
#else
// It won't work properly unless called from the privileged mode
shutdown_privileged();
#endif
for (;;)
;
}
void __attribute__((noreturn))
error_uni(const char *label, const char *msg, const char *footer) {
display_orientation(0);
#ifdef FANCY_FATAL_ERROR
screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
display_refresh();
#else
display_print_color(COLOR_WHITE, COLOR_FATAL_ERROR);
if (label) {
display_printf("%s\n", label);
}
if (msg) {
display_printf("%s\n", msg);
}
if (footer) {
display_printf("\n%s\n", footer);
}
#endif
display_backlight(255);
display_refresh();
trezor_shutdown();
}
void __attribute__((noreturn))
__fatal_error(const char *expr, const char *msg, const char *file, int line,
const char *func) {
display_orientation(0);
display_backlight(255);
#ifdef FANCY_FATAL_ERROR
char buf[256] = {0};
mini_snprintf(buf, sizeof(buf), "%s: %d", file, line);
screen_fatal_error_rust("INTERNAL ERROR", msg != NULL ? msg : buf,
"PLEASE VISIT\nTREZOR.IO/RSOD");
display_refresh();
#else
display_print_color(COLOR_WHITE, COLOR_FATAL_ERROR);
display_printf("\nINTERNAL ERROR:\n");
if (expr) {
display_printf("expr: %s\n", expr);
}
if (msg) {
display_printf("msg : %s\n", msg);
}
if (file) {
display_printf("file: %s:%d\n", file, line);
}
if (func) {
display_printf("func: %s\n", func);
}
#ifdef SCM_REVISION
const uint8_t *rev = (const uint8_t *)SCM_REVISION;
display_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
rev[4]);
#endif
display_printf("\nPlease contact Trezor support.\n");
#endif
trezor_shutdown();
}
void __attribute__((noreturn))
error_shutdown(const char *label, const char *msg) {
display_orientation(0);
#ifdef FANCY_FATAL_ERROR
screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
display_refresh();
#else
display_print_color(COLOR_WHITE, COLOR_FATAL_ERROR);
if (label) {
display_printf("%s\n", label);
}
if (msg) {
display_printf("%s\n", msg);
}
display_printf("\nPLEASE VISIT TREZOR.IO/RSOD\n");
#endif
display_backlight(255);
trezor_shutdown();
}
#ifndef NDEBUG
void __assert_func(const char *file, int line, const char *func,
const char *expr) {
__fatal_error(expr, "assert failed", file, line, func);
}
#endif
void hal_delay(uint32_t ms) { HAL_Delay(ms); }
uint32_t hal_ticks_ms() { return HAL_GetTick(); }
uint32_t __stack_chk_guard = 0;
void __attribute__((noreturn)) __stack_chk_fail(void) {
error_shutdown("INTERNAL ERROR", "(SS)");
}
uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
void collect_hw_entropy(void) {
// collect entropy from UUID
uint32_t w = LL_GetUID_Word0();
memcpy(HW_ENTROPY_DATA, &w, 4);
w = LL_GetUID_Word1();
memcpy(HW_ENTROPY_DATA + 4, &w, 4);
w = LL_GetUID_Word2();
memcpy(HW_ENTROPY_DATA + 8, &w, 4);
// set entropy in the OTP randomness block
if (secfalse == flash_otp_is_locked(FLASH_OTP_BLOCK_RANDOMNESS)) {
uint8_t entropy[FLASH_OTP_BLOCK_SIZE];
random_buffer(entropy, FLASH_OTP_BLOCK_SIZE);
ensure(flash_otp_write(FLASH_OTP_BLOCK_RANDOMNESS, 0, entropy,
FLASH_OTP_BLOCK_SIZE),
NULL);
// ensure(flash_otp_lock(FLASH_OTP_BLOCK_RANDOMNESS), NULL);
}
// collect entropy from OTP randomness block
ensure(flash_otp_read(FLASH_OTP_BLOCK_RANDOMNESS, 0, HW_ENTROPY_DATA + 12,
FLASH_OTP_BLOCK_SIZE),
NULL);
}
// this function resets settings changed in one layer (bootloader/firmware),
// which might be incompatible with the other layers older versions,
// where this setting might be unknown
void ensure_compatible_settings(void) {}
void show_wipe_code_screen(void) {
error_uni("WIPE CODE ENTERED", "All data has been erased from the device",
"PLEASE RECONNECT\nTHE DEVICE");
}
void show_pin_too_many_screen(void) {
error_uni("TOO MANY PIN ATTEMPTS", "All data has been erased from the device",
"PLEASE RECONNECT\nTHE DEVICE");
}

@ -0,0 +1,173 @@
/*
* 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 "dma2d.h"
#include "colors.h"
#include STM32_HAL_H
#include "display_interface.h"
typedef enum {
DMA2D_LAYER_FG = 1,
DMA2D_LAYER_BG = 0,
} dma2d_layer_t;
static DMA2D_HandleTypeDef dma2d_handle = {0};
static uint16_t current_width = 0;
static uint16_t current_height = 0;
void dma2d_init(void) {
__HAL_RCC_DMA2D_CLK_ENABLE();
dma2d_handle.Instance = (DMA2D_TypeDef*)DMA2D_BASE;
dma2d_handle.Init.ColorMode = DISPLAY_COLOR_MODE;
dma2d_handle.Init.OutputOffset = 0;
}
static void dma2d_init_clut(uint16_t fg, uint16_t bg, dma2d_layer_t layer) {
volatile uint32_t* table = NULL;
if (layer == DMA2D_LAYER_BG) {
table = dma2d_handle.Instance->BGCLUT;
} else {
table = dma2d_handle.Instance->FGCLUT;
}
uint32_t fg32 = rgb565_to_rgb888(fg);
uint32_t bg32 = rgb565_to_rgb888(bg);
for (uint8_t i = 0; i < 16; i++) {
table[i] = interpolate_rgb888_color(fg32, bg32, i);
}
DMA2D_CLUTCfgTypeDef clut;
clut.CLUTColorMode = DMA2D_CCM_ARGB8888;
clut.Size = 0xf;
clut.pCLUT = 0; // loading directly
HAL_DMA2D_ConfigCLUT(&dma2d_handle, clut, layer);
}
void dma2d_setup_const(void) {
dma2d_handle.Init.Mode = DMA2D_R2M;
dma2d_handle.Init.OutputOffset = display_get_window_offset();
HAL_DMA2D_Init(&dma2d_handle);
}
void dma2d_setup_4bpp(uint16_t fg_color, uint16_t bg_color) {
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
dma2d_handle.Init.OutputOffset = display_get_window_offset();
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_L4;
dma2d_handle.LayerCfg[1].InputOffset = 0;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = 0;
dma2d_init_clut(fg_color, bg_color, DMA2D_LAYER_FG);
HAL_DMA2D_Init(&dma2d_handle);
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
}
void dma2d_setup_16bpp(void) {
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
dma2d_handle.Init.OutputOffset = display_get_window_offset();
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
dma2d_handle.LayerCfg[1].InputOffset = 0;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = 0;
HAL_DMA2D_Init(&dma2d_handle);
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
}
void dma2d_setup_4bpp_over_16bpp(uint16_t overlay_color) {
dma2d_handle.Init.Mode = DMA2D_M2M_BLEND;
dma2d_handle.Init.OutputOffset = display_get_window_offset();
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_A4;
dma2d_handle.LayerCfg[1].InputOffset = 0;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha =
0xFF000000 | rgb565_to_rgb888(overlay_color);
dma2d_handle.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
dma2d_handle.LayerCfg[0].InputOffset = 0;
dma2d_handle.LayerCfg[0].AlphaMode = 0;
dma2d_handle.LayerCfg[0].InputAlpha = 0;
HAL_DMA2D_Init(&dma2d_handle);
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
HAL_DMA2D_ConfigLayer(&dma2d_handle, 0);
}
void dma2d_setup_4bpp_over_4bpp(uint16_t fg_color, uint16_t bg_color,
uint16_t overlay_color) {
dma2d_handle.Init.Mode = DMA2D_M2M_BLEND;
dma2d_handle.Init.OutputOffset = display_get_window_offset();
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_A4;
dma2d_handle.LayerCfg[1].InputOffset = 0;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = rgb565_to_rgb888(overlay_color);
dma2d_handle.LayerCfg[0].InputColorMode = DMA2D_INPUT_L4;
dma2d_handle.LayerCfg[0].InputOffset = 0;
dma2d_handle.LayerCfg[0].AlphaMode = DMA2D_REPLACE_ALPHA;
dma2d_handle.LayerCfg[0].InputAlpha = 0xFF;
dma2d_init_clut(fg_color, bg_color, DMA2D_LAYER_BG);
HAL_DMA2D_Init(&dma2d_handle);
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
HAL_DMA2D_ConfigLayer(&dma2d_handle, 0);
}
void dma2d_start(uint8_t* in_addr, uint8_t* out_addr, int32_t pixels) {
current_width = pixels;
current_height = 1;
HAL_DMA2D_Start(&dma2d_handle, (uint32_t)in_addr, (uint32_t)out_addr, pixels,
1);
}
void dma2d_start_const(uint16_t color, uint8_t* out_addr, int32_t pixels) {
current_width = pixels;
current_height = 1;
HAL_DMA2D_Start(&dma2d_handle, rgb565_to_rgb888(color), (uint32_t)out_addr,
pixels, 1);
}
void dma2d_start_const_multiline(uint16_t color, uint8_t* out_addr,
int32_t width, int32_t height) {
current_width = width;
current_height = height;
HAL_DMA2D_Start(&dma2d_handle, rgb565_to_rgb888(color), (uint32_t)out_addr,
width, height);
}
void dma2d_start_blend(uint8_t* overlay_addr, uint8_t* bg_addr,
uint8_t* out_addr, int32_t pixels) {
current_width = pixels;
current_height = 1;
HAL_DMA2D_BlendingStart(&dma2d_handle, (uint32_t)overlay_addr,
(uint32_t)bg_addr, (uint32_t)out_addr, pixels, 1);
}
void dma2d_wait_for_transfer(void) {
while (HAL_DMA2D_PollForTransfer(&dma2d_handle, 10) != HAL_OK)
;
display_shift_window(current_width * current_height);
current_width = 0;
current_height = 0;
}

@ -0,0 +1,20 @@
#include "common.h"
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }
void MemManage_Handler_MM(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
void MemManage_Handler_SO(void) { error_shutdown("INTERNAL ERROR", "(SO)"); }
void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }
void UsageFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(UF)"); }
void SecureFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(SF)"); }
void NMI_Handler(void) {
// Clock Security System triggered NMI
if ((RCC->CIFR & RCC_CIFR_CSSF) != 0) {
error_shutdown("INTERNAL ERROR", "(CS)");
}
}

@ -0,0 +1,477 @@
/*
* 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 STM32_HAL_H
#include <string.h>
#include "common.h"
#include "flash.h"
#include "model.h"
#define FLASH_SEC_START_ADDRESS 0x0C000000
#define FLASH_START_ADDRESS 0x08000000
#define FLASH_SECTOR_COUNT (256 * 2)
#define FLASH_STATUS_ALL_FLAGS \
(FLASH_NSSR_PGSERR | FLASH_NSSR_PGAERR | FLASH_NSSR_WRPERR | FLASH_NSSR_EOP)
uint32_t flash_wait_and_clear_status_flags(void) {
while (FLASH->NSSR & FLASH_NSSR_BSY)
; // wait for all previous flash operations to complete
uint32_t result =
FLASH->NSSR & FLASH_STATUS_ALL_FLAGS; // get the current status flags
FLASH->NSSR |= FLASH_STATUS_ALL_FLAGS; // clear all status flags
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
while (FLASH->SECSR & FLASH_SECSR_BSY)
; // wait for all previous flash operations to complete
result |=
FLASH->SECSR & FLASH_STATUS_ALL_FLAGS; // get the current status flags
FLASH->SECSR |= FLASH_STATUS_ALL_FLAGS; // clear all status flags
#endif
return result;
}
secbool flash_unlock_write(void) {
HAL_FLASH_Unlock();
FLASH->NSSR |= FLASH_STATUS_ALL_FLAGS; // clear all status flags
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
FLASH->SECSR |= FLASH_STATUS_ALL_FLAGS; // clear all status flags
#endif
return sectrue;
}
secbool flash_lock_write(void) {
HAL_FLASH_Lock();
return sectrue;
}
const void *flash_get_address(uint16_t sector, uint32_t offset, uint32_t size,
bool secure_area) {
if (sector >= FLASH_SECTOR_COUNT) {
return NULL;
}
uint32_t base_addr = FLASH_START_ADDRESS;
if (secure_area) {
base_addr = FLASH_SEC_START_ADDRESS;
}
const uint32_t addr = base_addr + (FLASH_PAGE_SIZE * sector) + offset;
const uint32_t next = base_addr + (FLASH_PAGE_SIZE * (sector + 1));
if (addr + size > next) {
return NULL;
}
return (const void *)addr;
}
uint32_t flash_sector_size(uint16_t sector) {
if (sector >= FLASH_SECTOR_COUNT) {
return 0;
}
return FLASH_PAGE_SIZE;
}
uint32_t flash_subarea_get_size(const flash_subarea_t *sub) {
return FLASH_PAGE_SIZE * sub->num_sectors;
}
uint32_t flash_area_get_size(const flash_area_t *area) {
uint32_t size = 0;
for (int i = 0; i < area->num_subareas; i++) {
size += flash_subarea_get_size(&area->subarea[i]);
}
return size;
}
uint16_t flash_total_sectors(const flash_area_t *area) {
uint16_t total = 0;
for (int i = 0; i < area->num_subareas; i++) {
total += area->subarea[i].num_sectors;
}
return total;
}
const void *flash_area_get_address(const flash_area_t *area, uint32_t offset,
uint32_t size) {
uint32_t tmp_offset = offset;
for (int i = 0; i < area->num_subareas; i++) {
uint16_t sector = area->subarea[i].first_sector;
if (tmp_offset >= flash_subarea_get_size(area->subarea)) {
tmp_offset -= flash_subarea_get_size(area->subarea);
continue;
}
uint32_t base_addr = FLASH_START_ADDRESS;
if (area->secure_area) {
base_addr = FLASH_SEC_START_ADDRESS;
}
const uint32_t addr = base_addr + (FLASH_PAGE_SIZE * sector) + tmp_offset;
const uint32_t area_end =
base_addr + (FLASH_PAGE_SIZE * (area->subarea[i].first_sector +
area->subarea[i].num_sectors));
if (addr + size > area_end) {
return NULL;
}
return (const void *)addr;
}
return NULL;
}
int32_t flash_get_sector_num(const flash_area_t *area,
uint32_t sector_inner_num) {
uint16_t sector = 0;
uint16_t remaining = sector_inner_num;
for (int i = 0; i < area->num_subareas; i++) {
if (remaining < area->subarea[i].num_sectors) {
sector = area->subarea[i].first_sector + remaining;
return sector;
} else {
remaining -= area->subarea[i].num_sectors;
}
}
return -1;
}
secbool flash_area_erase(const flash_area_t *area,
void (*progress)(int pos, int len)) {
ensure(flash_unlock_write(), NULL);
FLASH_EraseInitTypeDef EraseInitStruct;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.NbPages = 1;
int total_pages = 0;
int done_pages = 0;
for (int i = 0; i < area->num_subareas; i++) {
total_pages += area->subarea[i].num_sectors;
}
if (progress) {
progress(0, total_pages);
}
for (int s = 0; s < area->num_subareas; s++) {
for (int i = 0; i < area->subarea[s].num_sectors; i++) {
int page = area->subarea[s].first_sector + i;
if (page >= 256) {
EraseInitStruct.Banks = FLASH_BANK_2;
} else {
EraseInitStruct.Banks = FLASH_BANK_1;
}
EraseInitStruct.Page = page;
uint32_t SectorError;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
ensure(flash_lock_write(), NULL);
return secfalse;
}
// check whether the sector was really deleted (contains only 0xFF)
const uint32_t addr_start =
(uint32_t)flash_get_address(page, 0, 0, area->secure_area);
const uint32_t addr_end =
(uint32_t)flash_get_address(page + 1, 0, 0, area->secure_area);
for (uint32_t addr = addr_start; addr < addr_end; addr += 4) {
if (*((const uint32_t *)addr) != 0xFFFFFFFF) {
ensure(flash_lock_write(), NULL);
return secfalse;
}
}
done_pages++;
if (progress && done_pages % 16 == 0) {
progress(done_pages, total_pages);
}
}
}
ensure(flash_lock_write(), NULL);
return sectrue;
}
secbool flash_area_erase_bulk(const flash_area_t *areas, int count,
void (*progress)(int pos, int len)) {
ensure(flash_unlock_write(), NULL);
FLASH_EraseInitTypeDef EraseInitStruct;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.NbPages = 1;
int total_pages = 0;
int done_pages = 0;
for (int c = 0; c < count; c++) {
for (int i = 0; i < areas[c].num_subareas; i++) {
total_pages += areas[c].subarea[i].num_sectors;
}
}
if (progress) {
progress(0, total_pages);
}
for (int c = 0; c < count; c++) {
for (int s = 0; s < areas[c].num_subareas; s++) {
for (int i = 0; i < areas[c].subarea[s].num_sectors; i++) {
int page = areas[c].subarea[s].first_sector + i;
if (page >= 256) {
EraseInitStruct.Banks = FLASH_BANK_2;
} else {
EraseInitStruct.Banks = FLASH_BANK_1;
}
EraseInitStruct.Page = page;
uint32_t SectorError;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
ensure(flash_lock_write(), NULL);
return secfalse;
}
// check whether the sector was really deleted (contains only 0xFF)
const uint32_t addr_start =
(uint32_t)flash_get_address(page, 0, 0, areas[c].secure_area);
const uint32_t addr_end =
(uint32_t)flash_get_address(page + 1, 0, 0, areas[c].secure_area);
for (uint32_t addr = addr_start; addr < addr_end; addr += 4) {
if (*((const uint32_t *)addr) != 0xFFFFFFFF) {
ensure(flash_lock_write(), NULL);
return secfalse;
}
}
done_pages++;
if (progress) {
progress(done_pages, total_pages);
}
}
}
}
ensure(flash_lock_write(), NULL);
return sectrue;
}
secbool flash_write_quadword(uint16_t sector, uint32_t offset,
const uint32_t *data, bool secure_area) {
uint32_t address = (uint32_t)flash_get_address(
sector, offset, 4 * sizeof(uint32_t), secure_area);
if (address == 0) {
return secfalse;
}
if (offset % (4 * sizeof(uint32_t))) { // we write only at 16-byte boundary
return secfalse;
}
for (int i = 0; i < 4; i++) {
if (data[i] != (data[i] & *((const uint32_t *)address + i))) {
return secfalse;
}
}
secbool all_match = sectrue;
for (int i = 0; i < 4; i++) {
if (data[i] != *((const uint32_t *)address + i)) {
all_match = secfalse;
break;
}
}
if (all_match == sectrue) {
return sectrue;
}
if (HAL_OK !=
HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, address, (uint32_t)data)) {
return secfalse;
}
for (int i = 0; i < 4; i++) {
if (data[i] != *((const uint32_t *)address + i)) {
return secfalse;
}
}
return sectrue;
}
secbool flash_write_burst(uint16_t sector, uint32_t offset,
const uint32_t *data, bool secure_area) {
uint32_t address = (uint32_t)flash_get_address(
sector, offset, 8 * 4 * sizeof(uint32_t), secure_area);
if (address == 0) {
return secfalse;
}
if (offset %
(8 * 4 * sizeof(uint32_t))) { // we write only at 16-byte boundary
return secfalse;
}
for (int i = 0; i < 8 * 4; i++) {
if (data[i] != (data[i] & *((const uint32_t *)address + i))) {
return secfalse;
}
}
secbool all_match = sectrue;
for (int i = 0; i < 8 * 4; i++) {
if (data[i] != *((const uint32_t *)address + i)) {
all_match = secfalse;
break;
}
}
if (all_match == sectrue) {
return sectrue;
}
if (HAL_OK !=
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BURST, address, (uint32_t)data)) {
return secfalse;
}
for (int i = 0; i < 8 * 4; i++) {
if (data[i] != *((const uint32_t *)address + i)) {
return secfalse;
}
}
return sectrue;
}
secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset,
const uint32_t *data) {
uint32_t tmp_offset = offset;
for (int i = 0; i < area->num_subareas; i++) {
uint16_t sector = area->subarea[i].first_sector;
uint32_t sub_size = flash_subarea_get_size(&area->subarea[i]);
if (tmp_offset >= sub_size) {
tmp_offset -= sub_size;
continue;
}
// in correct subarea
for (int s = 0; s < area->subarea[i].num_sectors; s++) {
const uint32_t sector_size = flash_sector_size(sector);
if (tmp_offset >= sector_size) {
tmp_offset -= sector_size;
sector++;
if (s == area->subarea[i].num_sectors - 1) {
return secfalse;
}
continue;
}
// in correct sector
return flash_write_quadword(sector, tmp_offset, data, area->secure_area);
}
}
return secfalse;
}
secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset,
const uint32_t *data) {
uint32_t tmp_offset = offset;
for (int i = 0; i < area->num_subareas; i++) {
uint16_t sector = area->subarea[i].first_sector;
uint32_t sub_size = flash_subarea_get_size(&area->subarea[i]);
if (tmp_offset >= sub_size) {
tmp_offset -= sub_size;
continue;
}
// in correct subarea
for (int s = 0; s < area->subarea[i].num_sectors; s++) {
const uint32_t sector_size = flash_sector_size(sector);
if (tmp_offset >= sector_size) {
tmp_offset -= sector_size;
sector++;
if (s == area->subarea[i].num_sectors - 1) {
return secfalse;
}
continue;
}
// in correct sector
return flash_write_burst(sector, tmp_offset, data, area->secure_area);
}
}
return secfalse;
}
secbool flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data,
uint8_t datalen) {
if (block >= FLASH_OTP_NUM_BLOCKS ||
offset + datalen > FLASH_OTP_BLOCK_SIZE) {
return secfalse;
}
for (uint8_t i = 0; i < datalen; i++) {
data[i] = *(__IO uint8_t *)(FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE +
offset + i);
}
return sectrue;
}
secbool flash_otp_write(uint8_t block, uint8_t offset, const uint8_t *data,
uint8_t datalen) {
if (datalen % 16 != 0) {
return secfalse;
}
if (block >= FLASH_OTP_NUM_BLOCKS ||
offset + datalen > FLASH_OTP_BLOCK_SIZE) {
return secfalse;
}
ensure(flash_unlock_write(), NULL);
for (uint8_t i = 0; i < datalen; i++) {
uint32_t address =
FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE + offset + i;
ensure(sectrue * (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD,
address, (uint32_t)data)),
NULL);
}
ensure(flash_lock_write(), NULL);
return sectrue;
}
secbool flash_otp_lock(uint8_t block) {
// check that all quadwords in the block have been written to
volatile uint8_t *addr =
(__IO uint8_t *)(FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE);
secbool qw_locked = secfalse;
for (uint8_t i = 0; i < FLASH_OTP_BLOCK_SIZE; i++) {
if (addr[i] != 0xFF) {
qw_locked = sectrue;
}
if (i % 16 == 15 && qw_locked == secfalse) {
return secfalse;
}
}
return sectrue;
}
secbool flash_otp_is_locked(uint8_t block) {
// considering block locked if any quadword in the block is non-0xFF
volatile uint8_t *addr =
(__IO uint8_t *)(FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE);
for (uint8_t i = 0; i < FLASH_OTP_BLOCK_SIZE; i++) {
if (addr[i] != 0xFF) {
return sectrue;
}
}
return secfalse;
}

@ -0,0 +1,174 @@
.syntax unified
.text
.global memset_reg
.type memset_reg, STT_FUNC
memset_reg:
// call with the following (note that the arguments are not validated prior to use):
// r0 - address of first word to write (inclusive)
// r1 - address of first word following the address in r0 to NOT write (exclusive)
// r2 - word value to be written
// both addresses in r0 and r1 needs to be divisible by 4!
.L_loop_begin:
str r2, [r0], 4 // store the word in r2 to the address in r0, post-indexed
cmp r0, r1
bne .L_loop_begin
bx lr
// Jump to address given in first argument R0 that points to next's stage's VTOR
// Clear memory and all registers before jump
.global jump_to
.type jump_to, STT_FUNC
jump_to:
mov r4, r0 // save input argument r0 (the address of the next stage's vector table) (r4 is callee save)
// this subroutine re-points the exception handlers before the C code
// that comprises them has been given a good environment to run.
// therefore, this code needs to disable interrupts before the VTOR
// update. then, the reset_handler of the next stage needs to re-enable interrupts.
// the following prevents activation of all exceptions except Non-Maskable Interrupt (NMI).
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.8:
// "there is no requirement to insert memory barrier instructions after CPSID".
cpsid f
// wipe memory at the end of the current stage of code
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
mov lr, r4
// clear out the general purpose registers before the next stage's code can run (even the NMI exception handler)
ldr r0, =0
mov r1, r0
mov r2, r0
mov r3, r0
mov r4, r0
mov r5, r0
mov r6, r0
mov r7, r0
mov r8, r0
mov r9, r0
mov r10, r0
mov r11, r0
mov r12, r0
// give the next stage a fresh main stack pointer
ldr r0, [lr] // set r0 to the main stack pointer in the next stage's vector table
msr msp, r0 // give the next stage its main stack pointer
// point to the next stage's exception handlers
// AN321, section 4.11: "a memory barrier is not required after a VTOR update"
.set SCB_VTOR, 0xE000ED08 // reference "Cortex-M4 Devices Generic User Guide" section 4.3
ldr r0, =SCB_VTOR
str lr, [r0]
mov r0, r1 // zero out r0
// go on to the next stage
ldr lr, [lr, 4] // set lr to the next stage's reset_handler
bx lr
.global jump_to_with_flag
.type jump_to_with_flag, STT_FUNC
jump_to_with_flag:
mov r4, r0 // save input argument r0 (the address of the next stage's vector table) (r4 is callee save)
mov r11, r1 // save second argument in "flag" register because we'll be cleaning RAM
// this subroutine re-points the exception handlers before the C code
// that comprises them has been given a good environment to run.
// therefore, this code needs to disable interrupts before the VTOR
// update. then, the reset_handler of the next stage needs to re-enable interrupts.
// the following prevents activation of all exceptions except Non-Maskable Interrupt (NMI).
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.8:
// "there is no requirement to insert memory barrier instructions after CPSID".
cpsid f
// wipe memory at the end of the current stage of code
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
mov lr, r4
// clear out the general purpose registers before the next stage's except the register with flag R11
ldr r0, =0
mov r1, r0
mov r2, r0
mov r3, r0
mov r4, r0
mov r5, r0
mov r6, r0
mov r7, r0
mov r8, r0
mov r9, r0
mov r10, r0
mov r12, r0
// give the next stage a fresh main stack pointer
ldr r0, [lr] // set r0 to the main stack pointer in the next stage's vector table
msr msp, r0 // give the next stage its main stack pointer
// point to the next stage's exception handlers
// AN321, section 4.11: "a memory barrier is not required after a VTOR update"
.set SCB_VTOR, 0xE000ED08 // reference "Cortex-M4 Devices Generic User Guide" section 4.3
ldr r0, =SCB_VTOR
str lr, [r0]
mov r0, r1 // zero out r0
// go on to the next stage
ldr lr, [lr, 4] // set lr to the next stage's reset_handler
bx lr
.global shutdown_privileged
.type shutdown_privileged, STT_FUNC
// The function must be called from the privileged mode
shutdown_privileged:
cpsid f // disable all exceptions (except for NMI), the instruction is ignored in unprivileged mode
// if the exceptions weren't disabled, an exception handler (for example systick handler)
// could be called after the memory is erased, which would lead to another exception
ldr r0, =0
mov r1, r0
mov r2, r0
mov r3, r0
mov r4, r0
mov r5, r0
mov r6, r0
mov r7, r0
mov r8, r0
mov r9, r0
mov r10, r0
mov r11, r0
mov r12, r0
ldr lr, =0xffffffff
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =1
msr control, r0 // jump to unprivileged mode
ldr r0, =0
b . // loop forever
.global MemManage_Handler
.type MemManage_Handler, STT_FUNC
MemManage_Handler:
ldr r2, =_sstack
mrs r1, msp
ldr r0, =_estack
msr msp, r0
cmp r1, r2
IT lt
bllt MemManage_Handler_SO
bl MemManage_Handler_MM
.end

@ -0,0 +1,298 @@
/*
* 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 STM32_HAL_H
#include "lowlevel.h"
#include "flash.h"
#include "model.h"
#pragma GCC optimize( \
"no-stack-protector") // applies to all functions in this file
#if PRODUCTION
#define WANT_RDP_LEVEL (OB_RDP_LEVEL_2)
#define WANT_WRP_PAGE_START 1
#define WANT_WRP_PAGE_END 6
#else
#define WANT_RDP_LEVEL (OB_RDP_LEVEL_0)
#endif
// BOR LEVEL 0: Reset level threshold is around 1.7 V
#define WANT_BOR_LEVEL (OB_BOR_LEVEL_0)
#define FLASH_OPTR_VALUE \
((WANT_RDP_LEVEL << FLASH_OPTR_RDP_Pos) | FLASH_OPTR_nRST_STDBY | \
FLASH_OPTR_nRST_STOP | FLASH_OPTR_IWDG_SW | FLASH_OPTR_IWDG_STOP | \
FLASH_OPTR_IWDG_STDBY | FLASH_OPTR_WWDG_SW | FLASH_OPTR_DUALBANK | \
FLASH_OPTR_nSWBOOT0 | FLASH_OPTR_nBOOT0 | FLASH_OPTR_PA15_PUPEN | \
FLASH_OPTR_BKPRAM_ECC | FLASH_OPTR_SRAM3_ECC | FLASH_OPTR_TZEN | \
FLASH_OPTR_SRAM_RST | WANT_BOR_LEVEL)
// TODO set values according to MCU variant
#define FALSH_SECBOOTADD0R_VALUE \
((BOARDLOADER_START & 0xFFFFFF80) | FLASH_SECBOOTADD0R_BOOT_LOCK | 0x7C)
#define FLASH_SECWM1R1_VALUE \
(0 << FLASH_SECWM1R1_SECWM1_PSTRT_Pos | \
0xff << FLASH_SECWM1R1_SECWM1_PEND_Pos | 0xFF00FF00)
#define FLASH_SECWM1R2_VALUE \
(1 << FLASH_SECWM1R2_HDP1_PEND_Pos | FLASH_SECWM1R2_HDP1EN | 0x7F007F00)
#define FLASH_SECWM2R1_VALUE \
(0 << FLASH_SECWM1R1_SECWM1_PSTRT_Pos | \
0xff << FLASH_SECWM1R1_SECWM1_PEND_Pos | 0xFF00FF00)
#define FLASH_SECWM2R2_VALUE (0x7F007F00)
secbool flash_check_option_bytes(void) {
flash_wait_and_clear_status_flags();
// check values stored in flash interface registers
if (FLASH->OPTR !=
FLASH_OPTR_VALUE) { // ignore bits 0 and 1 because they are control bits
return secfalse;
}
if (FLASH->SECBOOTADD0R != FALSH_SECBOOTADD0R_VALUE) {
return secfalse;
}
#if PRODUCTION
if (FLASH->WRP1AR != (WANT_WRP_PAGE_START | (WANT_WRP_PAGE_END << 16))) {
return secfalse;
}
#else
// TODO set values according to MCU variant
if (FLASH->WRP1AR != 0xFF00FFFF) {
return secfalse;
}
#endif
// TODO set values according to MCU variant
if (FLASH->WRP1BR != 0xFF00FFFF) {
return secfalse;
}
// TODO set values according to MCU variant
if (FLASH->WRP2AR != 0xFF00FFFF) {
return secfalse;
}
// TODO set values according to MCU variant
if (FLASH->WRP2BR != 0xFF00FFFF) {
return secfalse;
}
return sectrue;
}
void flash_lock_option_bytes(void) {
FLASH->NSCR |= FLASH_NSCR_OPTLOCK; // lock the option bytes
}
void flash_unlock_option_bytes(void) {
if ((FLASH->NSCR & FLASH_NSCR_OPTLOCK) == 0) {
return; // already unlocked
}
// reference RM0090 section 3.7.2
// write the special sequence to unlock
FLASH->OPTKEYR = FLASH_OPTKEY1;
FLASH->OPTKEYR = FLASH_OPTKEY2;
while (FLASH->NSCR & FLASH_NSCR_OPTLOCK)
; // wait until the flash option control register is unlocked
}
uint32_t flash_set_option_bytes(void) {
if (flash_unlock_write() != sectrue) {
return 0;
}
flash_wait_and_clear_status_flags();
flash_unlock_option_bytes();
flash_wait_and_clear_status_flags();
FLASH->OPTR =
FLASH_OPTR_VALUE; // WARNING: dev board safe unless you compile for
// PRODUCTION or change this value!!!
FLASH->SECBOOTADD0R = FALSH_SECBOOTADD0R_VALUE;
#if PRODUCTION
FLASH->WRP1AR = WANT_WRP_PAGE_START | (WANT_WRP_PAGE_END << 16);
// TODO set values according to MCU variant
FLASH->WRP1BR = 0xFF00FFFF;
FLASH->WRP2AR = 0xFF00FFFF FLASH->WRP2BR = 0xFF00FFFF
#endif
FLASH_WaitForLastOperation(HAL_MAX_DELAY);
FLASH->NSCR |= FLASH_NSCR_OPTSTRT;
uint32_t result =
flash_wait_and_clear_status_flags(); // wait until changes are committed
FLASH_WaitForLastOperation(HAL_MAX_DELAY);
FLASH->NSCR |= FLASH_NSCR_OBL_LAUNCH; // begin committing changes to flash
result =
flash_wait_and_clear_status_flags(); // wait until changes are committed
flash_lock_option_bytes();
if (flash_lock_write() != sectrue) {
return 0;
}
return result;
}
secbool flash_configure_option_bytes(void) {
if (sectrue == flash_check_option_bytes()) {
return sectrue; // we DID NOT have to change the option bytes
}
do {
flash_set_option_bytes();
} while (sectrue != flash_check_option_bytes());
return secfalse; // notify that we DID have to change the option bytes
}
secbool flash_check_sec_area_ob(void) {
flash_wait_and_clear_status_flags();
// check values stored in flash interface registers
if (FLASH->SECWM1R1 != FLASH_SECWM1R1_VALUE) {
return secfalse;
}
if (FLASH->SECWM1R2 != FLASH_SECWM1R2_VALUE) {
return secfalse;
}
if (FLASH->SECWM2R1 != FLASH_SECWM2R1_VALUE) {
return secfalse;
}
if (FLASH->SECWM2R2 != FLASH_SECWM2R2_VALUE) {
return secfalse;
}
return sectrue;
}
uint32_t flash_set_sec_area_ob(void) {
if (flash_unlock_write() != sectrue) {
return 0;
}
flash_wait_and_clear_status_flags();
flash_unlock_option_bytes();
flash_wait_and_clear_status_flags();
FLASH->SECWM1R1 = FLASH_SECWM1R1_VALUE;
FLASH->SECWM1R2 = FLASH_SECWM1R2_VALUE;
FLASH->SECWM2R1 = FLASH_SECWM2R1_VALUE;
FLASH->SECWM2R2 = FLASH_SECWM2R2_VALUE;
FLASH_WaitForLastOperation(HAL_MAX_DELAY);
FLASH->NSCR |= FLASH_NSCR_OPTSTRT;
uint32_t result =
flash_wait_and_clear_status_flags(); // wait until changes are committed
FLASH_WaitForLastOperation(HAL_MAX_DELAY);
FLASH->NSCR |= FLASH_NSCR_OBL_LAUNCH; // begin committing changes to flash
result =
flash_wait_and_clear_status_flags(); // wait until changes are committed
flash_lock_option_bytes();
if (flash_lock_write() != sectrue) {
return 0;
}
return result;
}
secbool flash_configure_sec_area_ob(void) {
if (sectrue == flash_check_sec_area_ob()) {
return sectrue; // we DID NOT have to change the option bytes
}
do {
flash_set_sec_area_ob();
} while (sectrue != flash_check_sec_area_ob());
return secfalse; // notify that we DID have to change the option bytes
}
void periph_init(void) {
// STM32U5xx HAL library initialization:
// - configure the Flash prefetch, instruction and data caches
// - configure the Systick to generate an interrupt each 1 msec
// - set NVIC Group Priority to 4
// - global MSP (MCU Support Package) initialization
HAL_Init();
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the common periph clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_DSI;
PeriphClkInit.DsiClockSelection = RCC_DSICLKSOURCE_PLL3;
PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3;
PeriphClkInit.PLL3.PLL3Source = RCC_PLLSOURCE_HSE;
PeriphClkInit.PLL3.PLL3M = 4;
PeriphClkInit.PLL3.PLL3N = 125;
PeriphClkInit.PLL3.PLL3P = 8;
PeriphClkInit.PLL3.PLL3Q = 2;
PeriphClkInit.PLL3.PLL3R = 24;
PeriphClkInit.PLL3.PLL3RGE = RCC_PLLVCIRANGE_0;
PeriphClkInit.PLL3.PLL3FRACN = 0;
PeriphClkInit.PLL3.PLL3ClockOut = RCC_PLL3_DIVP | RCC_PLL3_DIVR;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
/** Enable instruction cache in 1-way (direct mapped cache)
*/
HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY);
// Enable GPIO clocks
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
// enable the PVD (programmable voltage detector).
// select the "2.8V" threshold (level 5).
// this detector will be active regardless of the
// flash option byte BOR setting.
// __HAL_RCC_PWR_CLK_ENABLE();
// PWR_PVDTypeDef pvd_config;
// pvd_config.PVDLevel = PWR_PVDLEVEL_5;
// pvd_config.Mode = PWR_PVD_MODE_IT_RISING_FALLING;
// HAL_PWR_ConfigPVD(&pvd_config);
// HAL_PWR_EnablePVD();
// NVIC_EnableIRQ(PVD_PVM_IRQn);
}
secbool reset_flags_check(void) {
#if PRODUCTION
// this is effective enough that it makes development painful, so only use it
// for production. check the reset flags to assure that we arrive here due to
// a regular full power-on event, and not as a result of a lesser reset.
if ((RCC->CSR & (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF | RCC_CSR_IWDGRSTF |
RCC_CSR_SFTRSTF | RCC_CSR_PINRSTF | RCC_CSR_BORRSTF |
RCC_CSR_OBLRSTF)) != (RCC_CSR_PINRSTF | RCC_CSR_BORRSTF)) {
return secfalse;
}
#endif
return sectrue;
}
void reset_flags_reset(void) {
RCC->CSR |= RCC_CSR_RMVF; // clear the reset flags
}

@ -0,0 +1,257 @@
/*
* 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 STM32_HAL_H
#include "common.h"
#include "flash.h"
#include "model.h"
#include "stm32u5xx_ll_cortex.h"
#define ATTR_IDX_FLASH (0 << 1)
#define ATTR_IDX_FLASH_NON_CACHABLE (3 << 1)
#define ATTR_IDX_SRAM (1 << 1)
#define ATTR_IDX_PERIPH (2 << 1)
#define REGION_END(x) (((x) & ~0x1F) | 0x01)
#define SHAREABILITY_FLASH (LL_MPU_ACCESS_NOT_SHAREABLE)
#define SHAREABILITY_SRAM \
(LL_MPU_ACCESS_INNER_SHAREABLE | LL_MPU_ACCESS_OUTER_SHAREABLE)
void mpu_config_off(void) {
// Disable MPU
HAL_MPU_Disable();
}
static uint32_t area_start(const flash_area_t* area) {
return (uint32_t)flash_area_get_address(area, 0, 0);
}
static uint32_t area_end(const flash_area_t* area) {
uint32_t start = area_start(area);
uint32_t size = flash_area_get_size(area);
return start + size;
}
void mpu_config_boardloader(void) {
// Disable MPU
HAL_MPU_Disable();
// flash memory
MPU->MAIR0 = 0xAA;
// internal ram
MPU->MAIR0 |= 0xAA << 8;
// peripherals
MPU->MAIR0 |= 0x00 << 16;
// non-cachable flash
MPU->MAIR0 |= 0x44 << 24;
// Secret
MPU->RNR = MPU_REGION_NUMBER0;
MPU->RBAR = FLASH_BASE_S | LL_MPU_REGION_ALL_RW | SHAREABILITY_FLASH |
LL_MPU_INSTRUCTION_ACCESS_DISABLE;
MPU->RLAR = REGION_END(BOARDLOADER_START - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
// Flash boardloader (read-write)
MPU->RNR = MPU_REGION_NUMBER1;
MPU->RBAR = BOARDLOADER_START | LL_MPU_REGION_ALL_RW | SHAREABILITY_FLASH;
MPU->RLAR = REGION_END(BOOTLOADER_START - 1) | ATTR_IDX_FLASH;
// Flash rest
MPU->RNR = MPU_REGION_NUMBER2;
MPU->RBAR = BOOTLOADER_START | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
MPU->RLAR =
REGION_END(FLASH_BASE_S + 0x400000 - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
// RAM (read-write, execute never) (SRAM1)
MPU->RNR = MPU_REGION_NUMBER3;
MPU->RBAR = SRAM1_BASE_S | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0xC0000 - 1) | ATTR_IDX_SRAM;
// RAM (read-write, execute never) (SRAM2, 3, 5, 6)
// reserve 256 bytes for stack overflow detection
MPU->RNR = MPU_REGION_NUMBER4;
MPU->RBAR = (SRAM2_BASE_S + 0x100) | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0x2F0000 - 1) | ATTR_IDX_SRAM;
// GFXMMU_VIRTUAL_BUFFERS (read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER5;
MPU->RBAR = GFXMMU_VIRTUAL_BUFFERS_BASE_S | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
MPU->RLAR =
REGION_END(GFXMMU_VIRTUAL_BUFFERS_BASE_S + 0x1000000 - 1) | ATTR_IDX_SRAM;
// Peripherals (read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER6;
MPU->RBAR =
PERIPH_BASE_S | LL_MPU_REGION_ALL_RW | LL_MPU_INSTRUCTION_ACCESS_DISABLE;
MPU->RLAR = REGION_END(PERIPH_BASE_S + 0x10000000 - 1) | ATTR_IDX_PERIPH;
// OTP (read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER7;
MPU->RBAR = FLASH_OTP_BASE | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
MPU->RLAR = REGION_END(FLASH_OTP_BASE + FLASH_OTP_SIZE - 1) |
ATTR_IDX_FLASH_NON_CACHABLE;
// RAM SRAM4
MPU->RNR = MPU_REGION_NUMBER7;
MPU->RBAR = SRAM4_BASE_S | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
MPU->RLAR = REGION_END(SRAM4_BASE_S + 0x4000 - 1) | ATTR_IDX_SRAM;
// Enable MPU
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
void mpu_config_bootloader(void) {
// Disable MPU
HAL_MPU_Disable();
// flash memory
MPU->MAIR0 = 0xAA;
// internal ram
MPU->MAIR0 |= 0xAA << 8;
// peripherals
MPU->MAIR0 |= 0x00 << 16;
// non-cachable flash
MPU->MAIR0 |= 0x44 << 24;
// Secret + boardloader
MPU->RNR = MPU_REGION_NUMBER0;
MPU->RBAR = FLASH_BASE_S | LL_MPU_REGION_ALL_RW | SHAREABILITY_FLASH;
MPU->RLAR = REGION_END(BOOTLOADER_START - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
// Bootloader (read-write)
MPU->RNR = MPU_REGION_NUMBER1;
MPU->RBAR = BOOTLOADER_START | LL_MPU_REGION_ALL_RW | SHAREABILITY_FLASH;
MPU->RLAR = REGION_END(area_start(&STORAGE_AREAS[0]) - 1) | ATTR_IDX_FLASH;
// Flash firmware + storage (read-write, execute never), till flash end
MPU->RNR = MPU_REGION_NUMBER2;
MPU->RBAR = area_start(&STORAGE_AREAS[0]) | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
MPU->RLAR =
REGION_END(FLASH_BASE_S + 0x400000 - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
// RAM (read-write, execute never) (SRAM1)
MPU->RNR = MPU_REGION_NUMBER3;
MPU->RBAR = SRAM1_BASE_S | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0xC0000 - 1) | ATTR_IDX_SRAM;
// RAM (read-write, execute never) (SRAM2, 3, 5, 6)
// reserve 256 bytes for stack overflow detection
MPU->RNR = MPU_REGION_NUMBER4;
MPU->RBAR = (SRAM2_BASE_S + 0x100) | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0x2F0000 - 1) | ATTR_IDX_SRAM;
// GFXMMU_VIRTUAL_BUFFERS (read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER5;
MPU->RBAR = GFXMMU_VIRTUAL_BUFFERS_BASE_S | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
MPU->RLAR =
REGION_END(GFXMMU_VIRTUAL_BUFFERS_BASE_S + 0x1000000 - 1) | ATTR_IDX_SRAM;
// Peripherals (read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER6;
MPU->RBAR =
PERIPH_BASE_S | LL_MPU_REGION_ALL_RW | LL_MPU_INSTRUCTION_ACCESS_DISABLE;
MPU->RLAR = REGION_END(PERIPH_BASE_S + 0x10000000 - 1) | ATTR_IDX_PERIPH;
// OTP (read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER7;
MPU->RBAR = FLASH_OTP_BASE | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
MPU->RLAR = REGION_END(FLASH_OTP_BASE + FLASH_OTP_SIZE - 1) |
ATTR_IDX_FLASH_NON_CACHABLE;
// Enable MPU
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
void mpu_config_firmware(void) {
// Disable MPU
HAL_MPU_Disable();
// flash memory
MPU->MAIR0 = 0xAA;
// internal ram
MPU->MAIR0 |= 0xAA << 8;
// peripherals
MPU->MAIR0 |= 0x00 << 16;
// non-cachable flash
MPU->MAIR0 |= 0x44 << 24;
// bootloader + boardloader: no access, execute never: need to do everything
// before turning on MPU
// Storage (read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER0;
MPU->RBAR = area_start(&STORAGE_AREAS[0]) | LL_MPU_REGION_ALL_RW |
SHAREABILITY_FLASH | LL_MPU_INSTRUCTION_ACCESS_DISABLE;
MPU->RLAR = REGION_END(FIRMWARE_START - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
// Flash firmware (read-write)
MPU->RNR = MPU_REGION_NUMBER1;
MPU->RBAR = (FIRMWARE_START) | LL_MPU_REGION_ALL_RO | SHAREABILITY_FLASH;
MPU->RLAR = REGION_END(area_end(&FIRMWARE_AREA) - 1) | ATTR_IDX_FLASH;
// RAM (read-write, execute never) (SRAM1)
MPU->RNR = MPU_REGION_NUMBER2;
MPU->RBAR = SRAM1_BASE_S | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0xC0000 - 1) | ATTR_IDX_SRAM;
// RAM (read-write, execute never) (SRAM2, 3, 5, 6)
// reserve 256 bytes for stack overflow detection
MPU->RNR = MPU_REGION_NUMBER3;
MPU->RBAR = (SRAM2_BASE_S + 0x100) | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0x2F0000 - 1) | ATTR_IDX_SRAM;
// GFXMMU_VIRTUAL_BUFFERS (read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER4;
MPU->RBAR = GFXMMU_VIRTUAL_BUFFERS_BASE_S | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
MPU->RLAR =
REGION_END(GFXMMU_VIRTUAL_BUFFERS_BASE_S + 0x1000000 - 1) | ATTR_IDX_SRAM;
// Peripherals (read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER5;
MPU->RBAR =
PERIPH_BASE_S | LL_MPU_REGION_ALL_RW | LL_MPU_INSTRUCTION_ACCESS_DISABLE;
MPU->RLAR = REGION_END(PERIPH_BASE_S + 0x10000000 - 1) | ATTR_IDX_PERIPH;
// OTP (read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER6;
MPU->RBAR = FLASH_OTP_BASE | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
MPU->RLAR = REGION_END(FLASH_OTP_BASE + FLASH_OTP_SIZE - 1) |
ATTR_IDX_FLASH_NON_CACHABLE;
// Enable MPU
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
__asm__ volatile("dsb");
__asm__ volatile("isb");
}

@ -0,0 +1,205 @@
/*
* 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 STM32_HAL_H
#include "platform.h"
#include "rng.h"
const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,
1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
const uint32_t MSIRangeTable[16] = {48000000U, 24000000U, 16000000U, 12000000U,
4000000U, 2000000U, 1330000U, 1000000U,
3072000U, 1536000U, 1024000U, 768000U,
400000U, 200000U, 133000U, 100000U};
typedef struct {
uint32_t freq;
uint32_t pllq;
uint32_t pllp;
uint32_t pllm;
uint32_t plln;
} clock_conf_t;
#if defined STM32U5
// HSE 16MHz
#define DEFAULT_FREQ 160U
#define DEFAULT_PLLM 1
#define DEFAULT_PLLN 10 // mult by 10
#define DEFAULT_PLLR 1U // division by 1
#define DEFAULT_PLLQ 1U // division by 1
#define DEFAULT_PLLP 5U // division by 5
#else
#error Unsupported MCU
#endif
uint32_t SystemCoreClock = DEFAULT_FREQ * 1000000U;
// PLLCLK = ((HSE / PLLM) * PLLN) / PLLR
// assuming HSE 16 MHz
clock_conf_t clock_conf[1] = {
{
// clk = ((16MHz / 1) * 10) / 1 = 160 MHz
.freq = 160,
.pllp = 1,
.pllq = 1,
.pllm = 1,
.plln = 10,
},
};
#pragma GCC optimize( \
"no-stack-protector") // applies to all functions in this file
void SystemInit(void) {
// set flash wait states for an increasing HCLK frequency
FLASH->ACR = FLASH_ACR_LATENCY_5WS;
// wait until the new wait state config takes effect -- per section 3.5.1
// guidance
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_5WS)
;
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set MSION bit */
RCC->CR = RCC_CR_MSISON;
/* Reset CFGR register */
RCC->CFGR1 = 0U;
RCC->CFGR2 = 0U;
RCC->CFGR3 = 0U;
/* Reset HSEON, CSSON , HSION, PLLxON bits */
RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLL1ON | RCC_CR_PLL2ON |
RCC_CR_PLL3ON | RCC_CR_HSI48ON);
/* Reset PLLCFGR register */
RCC->PLL1CFGR = 0U;
/* Reset HSEBYP bit */
RCC->CR &= ~(RCC_CR_HSEBYP);
/* Disable all interrupts */
RCC->CIER = 0U;
__HAL_RCC_PWR_CLK_ENABLE();
MODIFY_REG(PWR->VOSR, (PWR_VOSR_VOS | PWR_VOSR_BOOSTEN),
PWR_REGULATOR_VOLTAGE_SCALE1);
while (HAL_IS_BIT_CLR(PWR->VOSR, PWR_VOSR_VOSRDY))
;
while (HAL_IS_BIT_CLR(PWR->SVMSR, PWR_SVMSR_ACTVOSRDY))
;
__HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
;
__HAL_RCC_PLL_CONFIG(RCC_PLLSOURCE_HSE, RCC_PLLMBOOST_DIV1, DEFAULT_PLLM,
DEFAULT_PLLN, DEFAULT_PLLP, DEFAULT_PLLQ, DEFAULT_PLLR);
__HAL_RCC_PLL_FRACN_DISABLE();
__HAL_RCC_PLL_VCIRANGE(RCC_PLLVCIRANGE_1);
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVR);
__HAL_RCC_PLL_ENABLE();
while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
;
__HAL_RCC_HSI48_ENABLE();
while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) == 0U)
;
/** Initializes the CPU, AHB and APB buses clocks
*/
FLASH->ACR = FLASH_ACR_LATENCY_4WS;
// wait until the new wait state config takes effect -- per section 3.5.1
// guidance
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_4WS)
;
MODIFY_REG(RCC->CFGR3, RCC_CFGR3_PPRE3, RCC_HCLK_DIV1);
MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, ((RCC_HCLK_DIV1) << 4));
MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, RCC_HCLK_DIV1);
MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, RCC_SYSCLK_DIV1);
MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, RCC_SYSCLKSOURCE_PLLCLK);
/*
* Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
*/
HAL_PWREx_DisableUCPDDeadBattery();
/*
* Switch to SMPS regulator instead of LDO
*/
SET_BIT(PWR->CR3, PWR_CR3_REGSEL);
/* Wait until system switch on new regulator */
while (HAL_IS_BIT_CLR(PWR->SVMSR, PWR_SVMSR_REGS))
;
__HAL_RCC_PWR_CLK_DISABLE();
// this will be overriden by static initialization
SystemCoreClock = DEFAULT_FREQ * 1000000U;
// enable clock security system, HSE clock, and main PLL
RCC->CR |= RCC_CR_CSSON;
// turn off the HSI as it is now unused (it will be turned on again
// automatically if a clock security failure occurs)
RCC->CR &= ~RCC_CR_HSION;
// wait until ths HSI is off
while ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
;
// TODO turn off MSI?
// init the TRNG peripheral
rng_init();
// set CP10 and CP11 to enable full access to the fpu coprocessor;
SCB->CPACR |=
((3UL << 20U) | (3UL << 22U)); /* set CP10 and CP11 Full Access */
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
SCB_NS->CPACR |=
((3UL << 20U) | (3UL << 22U)); /* set CP10 and CP11 Full Access */
#endif
// enable instruction cache
ICACHE->CR = ICACHE_CR_EN;
}
void drop_privileges(void) {
// jump to unprivileged mode
// http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/CHDBIBGJ.html
__asm__ volatile("msr control, %0" ::"r"(0x1));
__asm__ volatile("isb");
}
// from util.s
extern void shutdown_privileged(void);
void PVD_PVM_IRQHandler(void) {
TIM1->CCR1 = 0; // turn off display backlight
shutdown_privileged();
}

@ -0,0 +1,54 @@
/*
* 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/>.
*/
#ifndef TREZORHAL_STM32_H
#define TREZORHAL_STM32_H
#include STM32_HAL_H
#include <stdint.h>
#define SENSITIVE __attribute__((section(".sensitive")))
typedef enum {
CLOCK_160_MHZ = 0,
} clock_settings_t;
void set_core_clock(clock_settings_t settings);
void ensure_compatible_settings(void);
void drop_privileges(void);
// the following functions are defined in util.s
void memset_reg(volatile void *start, volatile void *stop, uint32_t val);
void jump_to(uint32_t address);
void jump_to_unprivileged(uint32_t address);
void jump_to_with_flag(uint32_t address, uint32_t register_flag);
extern uint32_t __stack_chk_guard;
// this deletes all secrets and SRAM2 where stack is located
// to prevent stack smashing error, do not return from function calling this
static inline void __attribute__((always_inline)) delete_secrets(void) {
// Disable SAES peripheral clock, so that we don't get tamper events
__HAL_RCC_SAES_CLK_DISABLE();
// Erase all
TAMP->CR2 |= TAMP_CR2_BKERASE;
}
#endif // TREZORHAL_STM32_H

@ -0,0 +1 @@
../stm32f4/random_delays.c

@ -0,0 +1,162 @@
#include "secret.h"
#include <string.h>
#include "common.h"
#include "flash.h"
#include "model.h"
#include "rng.h"
static secbool bootloader_locked_set = secfalse;
static secbool bootloader_locked = secfalse;
static secbool verify_header(void) {
uint8_t header[SECRET_HEADER_LEN] = {0};
memcpy(header, flash_area_get_address(&SECRET_AREA, 0, SECRET_HEADER_LEN),
SECRET_HEADER_LEN);
bootloader_locked =
memcmp(header, SECRET_HEADER_MAGIC, 4) == 0 ? sectrue : secfalse;
bootloader_locked_set = sectrue;
return bootloader_locked;
}
secbool secret_bootloader_locked(void) {
if (bootloader_locked_set != sectrue) {
// Set bootloader_locked.
verify_header();
}
return bootloader_locked;
}
void secret_write_header(void) {
uint8_t header[SECRET_HEADER_LEN] = {0};
memcpy(header, SECRET_HEADER_MAGIC, 4);
secret_write(header, 0, SECRET_HEADER_LEN);
}
void secret_write(uint8_t *data, uint32_t offset, uint32_t len) {
ensure(flash_unlock_write(), "secret write");
for (int i = 0; i < len / 16; i++) {
ensure(flash_area_write_quadword(&SECRET_AREA, offset + (i * 16),
(uint32_t *)&data[(i * 16)]),
"secret write");
}
ensure(flash_lock_write(), "secret write");
}
secbool secret_read(uint8_t *data, uint32_t offset, uint32_t len) {
if (sectrue != verify_header()) {
return secfalse;
}
memcpy(data, flash_area_get_address(&SECRET_AREA, offset, len), len);
return sectrue;
}
void secret_hide(void) {
FLASH->SECHDPCR |= FLASH_SECHDPCR_HDP1_ACCDIS_Msk;
FLASH->SECHDPCR |= FLASH_SECHDPCR_HDP2_ACCDIS_Msk;
}
void secret_bhk_lock(void) {
TAMP_S->SECCFGR = 8 << TAMP_SECCFGR_BKPRWSEC_Pos | TAMP_SECCFGR_BHKLOCK;
}
secbool secret_bhk_locked(void) {
return ((TAMP_S->SECCFGR & TAMP_SECCFGR_BHKLOCK) == TAMP_SECCFGR_BHKLOCK) *
sectrue;
}
void secret_bhk_provision(void) {
uint32_t secret[SECRET_BHK_LEN / sizeof(uint32_t)] = {0};
secbool ok =
secret_read((uint8_t *)secret, SECRET_BHK_OFFSET, SECRET_BHK_LEN);
volatile uint32_t *reg1 = &TAMP->BKP0R;
if (sectrue == ok) {
for (int i = 0; i < 8; i++) {
*reg1 = ((uint32_t *)secret)[i];
reg1++;
}
} else {
for (int i = 0; i < 8; i++) {
*reg1 = 0;
reg1++;
}
}
}
void secret_bhk_regenerate(void) {
ensure(flash_area_erase(&BHK_AREA, NULL), "Failed regenerating BHK");
ensure(flash_unlock_write(), "Failed regenerating BHK");
for (int i = 0; i < 2; i++) {
uint32_t val[4] = {0};
for (int j = 0; j < 4; j++) {
val[j] = rng_get();
}
ensure(flash_area_write_quadword(&BHK_AREA, i * 4 * sizeof(uint32_t), val),
"Failed regenerating BHK");
}
ensure(flash_lock_write(), "Failed regenerating BHK");
}
secbool secret_optiga_present(void) {
uint8_t *optiga_secret = (uint8_t *)flash_area_get_address(
&SECRET_AREA, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
int optiga_secret_empty_bytes = 0;
for (int i = 0; i < SECRET_OPTIGA_KEY_LEN; i++) {
if (optiga_secret[i] == 0xFF) {
optiga_secret_empty_bytes++;
}
}
return sectrue * (optiga_secret_empty_bytes != SECRET_OPTIGA_KEY_LEN);
}
void secret_optiga_backup(void) {
uint32_t secret[SECRET_OPTIGA_KEY_LEN / sizeof(uint32_t)] = {0};
secbool ok = secret_read((uint8_t *)secret, SECRET_OPTIGA_KEY_OFFSET,
SECRET_OPTIGA_KEY_LEN);
volatile uint32_t *reg1 = &TAMP->BKP8R;
if (sectrue == ok) {
for (int i = 0; i < 8; i++) {
*reg1 = ((uint32_t *)secret)[i];
reg1++;
}
} else {
for (int i = 0; i < 8; i++) {
*reg1 = 0;
reg1++;
}
}
}
secbool secret_optiga_extract(uint8_t *dest) {
bool all_zero = true;
volatile uint32_t *reg1 = &TAMP->BKP8R;
for (int i = 0; i < 8; i++) {
uint32_t val = *reg1++;
if (val != 0) {
all_zero = false;
}
for (int j = 0; j < 4; j++) {
dest[i * 4 + j] = (val >> (j * 8)) & 0xFF;
}
}
return all_zero ? secfalse : sectrue;
}
void secret_optiga_hide(void) {
volatile uint32_t *reg1 = &TAMP->BKP8R;
for (int i = 0; i < 8; i++) {
*reg1 = 0;
reg1++;
}
}

@ -0,0 +1,132 @@
/*
* 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 <secure_aes.h>
#include STM32_HAL_H
#include <stdio.h>
#include <stm32u5xx_hal_cryp.h>
secbool secure_aes_init(void) {
RCC_OscInitTypeDef osc_init_def = {0};
osc_init_def.OscillatorType = RCC_OSCILLATORTYPE_SHSI;
osc_init_def.SHSIState = RCC_SHSI_ON;
// Enable SHSI clock
if (HAL_RCC_OscConfig(&osc_init_def) != HAL_OK) {
return secfalse;
}
// Enable SAES peripheral clock
__HAL_RCC_SAES_CLK_ENABLE();
return sectrue;
}
static void secure_aes_load_bhk(void) {
TAMP->BKP7R;
TAMP->BKP6R;
TAMP->BKP5R;
TAMP->BKP4R;
TAMP->BKP3R;
TAMP->BKP2R;
TAMP->BKP1R;
TAMP->BKP0R;
}
secbool secure_aes_encrypt(uint32_t* input, size_t size, uint32_t* output) {
CRYP_HandleTypeDef hcryp = {0};
uint32_t iv[] = {0, 0, 0, 0};
hcryp.Instance = SAES;
hcryp.Init.DataType = CRYP_NO_SWAP;
hcryp.Init.KeySelect = CRYP_KEYSEL_HSW;
hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
hcryp.Init.pKey = NULL;
hcryp.Init.pInitVect = iv;
hcryp.Init.Algorithm = CRYP_AES_ECB;
hcryp.Init.Header = NULL;
hcryp.Init.HeaderSize = 0;
hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD;
hcryp.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
hcryp.Init.KeyMode = CRYP_KEYMODE_NORMAL;
if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
return secfalse;
}
secure_aes_load_bhk();
if (HAL_CRYP_Encrypt(&hcryp, input, size, output, HAL_MAX_DELAY) != HAL_OK) {
return secfalse;
}
HAL_CRYP_DeInit(&hcryp);
return sectrue;
}
secbool secure_aes_decrypt(uint32_t* input, size_t size, uint32_t* output) {
CRYP_HandleTypeDef hcryp = {0};
uint32_t iv[] = {0, 0, 0, 0};
hcryp.Instance = SAES;
hcryp.Init.DataType = CRYP_NO_SWAP;
hcryp.Init.KeySelect = CRYP_KEYSEL_HSW;
hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
hcryp.Init.pKey = NULL;
hcryp.Init.pInitVect = iv;
hcryp.Init.Algorithm = CRYP_AES_ECB;
hcryp.Init.Header = NULL;
hcryp.Init.HeaderSize = 0;
hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
hcryp.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
hcryp.Init.KeyMode = CRYP_KEYMODE_NORMAL;
if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
return secfalse;
}
secure_aes_load_bhk();
if (HAL_CRYP_Decrypt(&hcryp, input, size, output, HAL_MAX_DELAY) != HAL_OK) {
return secfalse;
}
HAL_CRYP_DeInit(&hcryp);
return sectrue;
}
void secure_aes_test() {
static uint32_t plain_text[4] = {1, 2, 3, 4};
static uint32_t encrypted_text[4];
static uint32_t decrypted_text[4];
secbool status;
status = secure_aes_encrypt(plain_text, sizeof(plain_text), encrypted_text);
printf("encryption done (status=%d)\n", status == sectrue);
status = secure_aes_decrypt(encrypted_text, sizeof(encrypted_text),
decrypted_text);
printf("decryption done (status=%d)\n", status == sectrue);
}

@ -0,0 +1,563 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32u5xx_hal_conf.h
* @author MCD Application Team
* @brief HAL configuration file.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32U5xx_HAL_CONF_H
#define STM32U5xx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#define USE_USB_HS
#define USE_USB_HS_INTERNAL_PHY
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
/*#define HAL_ADC_MODULE_ENABLED */
/*#define HAL_MDF_MODULE_ENABLED */
/*#define HAL_COMP_MODULE_ENABLED */
/*#define HAL_CORDIC_MODULE_ENABLED */
/*#define HAL_CRC_MODULE_ENABLED */
/*#define HAL_CRYP_MODULE_ENABLED */
/*#define HAL_DAC_MODULE_ENABLED */
#define HAL_DMA2D_MODULE_ENABLED
#define HAL_DSI_MODULE_ENABLED
/*#define HAL_FDCAN_MODULE_ENABLED */
/*#define HAL_FMAC_MODULE_ENABLED */
#define HAL_GFXMMU_MODULE_ENABLED
/*#define HAL_GPU2D_MODULE_ENABLED */
#define HAL_GTZC_MODULE_ENABLED
/*#define HAL_HASH_MODULE_ENABLED */
/*#define HAL_HRTIM_MODULE_ENABLED */
/*#define HAL_IRDA_MODULE_ENABLED */
/*#define HAL_IWDG_MODULE_ENABLED */
#define HAL_I2C_MODULE_ENABLED
/*#define HAL_I2S_MODULE_ENABLED */
/*#define HAL_LPTIM_MODULE_ENABLED */
#define HAL_LTDC_MODULE_ENABLED
/*#define HAL_NAND_MODULE_ENABLED */
/*#define HAL_NOR_MODULE_ENABLED */
/*#define HAL_OPAMP_MODULE_ENABLED */
/*#define HAL_OSPI_MODULE_ENABLED */
/*#define HAL_OTFDEC_MODULE_ENABLED */
/*#define HAL_PKA_MODULE_ENABLED */
/*#define HAL_QSPI_MODULE_ENABLED */
/*#define HAL_RNG_MODULE_ENABLED */
#define HAL_RTC_MODULE_ENABLED
/*#define HAL_SAI_MODULE_ENABLED */
#define HAL_CRYP_MODULE_ENABLED
/*#define HAL_SD_MODULE_ENABLED */
/*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
/*#define HAL_SPI_MODULE_ENABLED */
/*#define HAL_SRAM_MODULE_ENABLED */
/*#define HAL_TIM_MODULE_ENABLED */
/*#define HAL_TSC_MODULE_ENABLED */
/*#define HAL_RAMCFG_MODULE_ENABLED */
#define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */
/*#define HAL_DCMI_MODULE_ENABLED */
/*#define HAL_PSSI_MODULE_ENABLED */
#define HAL_ICACHE_MODULE_ENABLED
/*#define HAL_DCACHE_MODULE_ENABLED */
#define HAL_PCD_MODULE_ENABLED
/*#define HAL_HCD_MODULE_ENABLED */
/*#define HAL_XSPI_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_EXTI_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
/* ########################## Oscillator Values adaptation
* ####################*/
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your
* application. This value is used by the RCC HAL module to compute the system
* frequency (when HSE is used as system clock source, directly or through the
* PLL).
*/
#if !defined(HSE_VALUE)
#define HSE_VALUE 16000000UL /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined(HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal Multiple Speed oscillator (MSI) default value.
* This value is the default MSI range value after Reset.
*/
#if !defined(MSI_VALUE)
#define MSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system
* frequency (when HSI is used as system clock source, directly or through the
* PLL).
*/
#if !defined(HSI_VALUE)
#define HSI_VALUE 16000000UL /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and
* RNG. This internal oscillator is mainly dedicated to provide a high precision
* clock to the USB peripheral by means of a special Clock Recovery System (CRS)
* circuitry. When the CRS is not used, the HSI48 RC oscillator runs on it
* default frequency which is subject to manufacturing process variations.
*/
#if !defined(HSI48_VALUE)
#define HSI48_VALUE \
48000000UL /*!< Value of the Internal High Speed oscillator for USB \
FS/SDMMC/RNG in Hz. The real value my vary depending on \
manufacturing process variations.*/
#endif /* HSI48_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
#if !defined(LSI_VALUE)
#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz \
The real value may vary depending on the \
variations in voltage and temperature.*/
/**
* @brief External Low Speed oscillator (LSE) value.
* This value is used by the UART, RTC HAL module to compute the system
* frequency
*/
#if !defined(LSE_VALUE)
#define LSE_VALUE \
32768UL /*!< Value of the External Low Speed oscillator in Hz */
#endif /* LSE_VALUE */
#if !defined(LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */
#endif /* LSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for SAI1 peripheral
* This value is used by the RCC HAL module to compute the SAI1 & SAI2
* clock source frequency.
*/
#if !defined(EXTERNAL_SAI1_CLOCK_VALUE)
#define EXTERNAL_SAI1_CLOCK_VALUE \
48000UL /*!< Value of the SAI1 External clock source in Hz*/
#endif /* EXTERNAL_SAI1_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE 3300UL /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY \
(15UL) /*!< tick interrupt priority (lowest by default) */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 1U /*!< Enable prefetch */
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## Register callback feature configuration ############### */
/**
* @brief Set below the peripheral configuration to "1U" to add the support
* of HAL callback registration/unregistration feature for the HAL
* driver(s). This allows user application to provide specific callback
* functions thanks to HAL_PPP_RegisterCallback() rather than overwriting
* the default weak callback functions (see each stm32u5xx_hal_ppp.h file
* for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef
* for each PPP peripheral).
*/
#define USE_HAL_ADC_REGISTER_CALLBACKS \
0U /* ADC register callback disabled */
#define USE_HAL_COMP_REGISTER_CALLBACKS \
0U /* COMP register callback disabled */
#define USE_HAL_CORDIC_REGISTER_CALLBACKS \
0U /* CORDIC register callback disabled */
#define USE_HAL_CRYP_REGISTER_CALLBACKS \
0U /* CRYP register callback disabled */
#define USE_HAL_DAC_REGISTER_CALLBACKS \
0U /* DAC register callback disabled */
#define USE_HAL_DCMI_REGISTER_CALLBACKS \
0U /* DCMI register callback disabled */
#define USE_HAL_DMA2D_REGISTER_CALLBACKS \
0U /* DMA2D register callback disabled */
#define USE_HAL_DSI_REGISTER_CALLBACKS \
0U /* DSI register callback disabled */
#define USE_HAL_ETH_REGISTER_CALLBACKS \
0U /* ETH register callback disabled */
#define USE_HAL_FDCAN_REGISTER_CALLBACKS \
0U /* FDCAN register callback disabled */
#define USE_HAL_FMAC_REGISTER_CALLBACKS \
0U /* FMAC register callback disabled */
#define USE_HAL_HASH_REGISTER_CALLBACKS \
0U /* HASH register callback disabled */
#define USE_HAL_HCD_REGISTER_CALLBACKS \
0U /* HCD register callback disabled */
#define USE_HAL_GFXMMU_REGISTER_CALLBACKS \
0U /* GFXMMU register callback disabled */
#define USE_HAL_GPU2D_REGISTER_CALLBACKS \
0U /* GPU2D register callback disabled */
#define USE_HAL_I2C_REGISTER_CALLBACKS \
0U /* I2C register callback disabled */
#define USE_HAL_IWDG_REGISTER_CALLBACKS \
0U /* IWDG register callback disabled */
#define USE_HAL_IRDA_REGISTER_CALLBACKS \
0U /* IRDA register callback disabled */
#define USE_HAL_LPTIM_REGISTER_CALLBACKS \
0U /* LPTIM register callback disabled */
#define USE_HAL_LTDC_REGISTER_CALLBACKS \
0U /* LTDC register callback disabled */
#define USE_HAL_MDF_REGISTER_CALLBACKS \
0U /* MDF register callback disabled */
#define USE_HAL_MMC_REGISTER_CALLBACKS \
0U /* MMC register callback disabled */
#define USE_HAL_NAND_REGISTER_CALLBACKS \
0U /* NAND register callback disabled */
#define USE_HAL_NOR_REGISTER_CALLBACKS \
0U /* NOR register callback disabled */
#define USE_HAL_OPAMP_REGISTER_CALLBACKS \
0U /* MDIO register callback disabled */
#define USE_HAL_OTFDEC_REGISTER_CALLBACKS \
0U /* OTFDEC register callback disabled */
#define USE_HAL_PCD_REGISTER_CALLBACKS \
0U /* PCD register callback disabled */
#define USE_HAL_PKA_REGISTER_CALLBACKS \
0U /* PKA register callback disabled */
#define USE_HAL_RAMCFG_REGISTER_CALLBACKS \
0U /* RAMCFG register callback disabled */
#define USE_HAL_RNG_REGISTER_CALLBACKS \
0U /* RNG register callback disabled */
#define USE_HAL_RTC_REGISTER_CALLBACKS \
0U /* RTC register callback disabled */
#define USE_HAL_SAI_REGISTER_CALLBACKS \
0U /* SAI register callback disabled */
#define USE_HAL_SD_REGISTER_CALLBACKS \
0U /* SD register callback disabled */
#define USE_HAL_SDRAM_REGISTER_CALLBACKS \
0U /* SDRAM register callback disabled */
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS \
0U /* SMARTCARD register callback disabled */
#define USE_HAL_SMBUS_REGISTER_CALLBACKS \
0U /* SMBUS register callback disabled */
#define USE_HAL_SPI_REGISTER_CALLBACKS \
0U /* SPI register callback disabled */
#define USE_HAL_SRAM_REGISTER_CALLBACKS \
0U /* SRAM register callback disabled */
#define USE_HAL_TIM_REGISTER_CALLBACKS \
0U /* TIM register callback disabled */
#define USE_HAL_TSC_REGISTER_CALLBACKS \
0U /* TSC register callback disabled */
#define USE_HAL_UART_REGISTER_CALLBACKS \
0U /* UART register callback disabled */
#define USE_HAL_USART_REGISTER_CALLBACKS \
0U /* USART register callback disabled */
#define USE_HAL_WWDG_REGISTER_CALLBACKS \
0U /* WWDG register callback disabled */
#define USE_HAL_OSPI_REGISTER_CALLBACKS \
0U /* OSPI register callback disabled */
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 0U
/* ################## SDMMC peripheral configuration #########################
*/
#define USE_SD_TRANSCEIVER 0U /*!< use uSD Transceiver */
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32u5xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32u5xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_ICACHE_MODULE_ENABLED
#include "stm32u5xx_hal_icache.h"
#endif /* HAL_ICACHE_MODULE_ENABLED */
#ifdef HAL_DCACHE_MODULE_ENABLED
#include "stm32u5xx_hal_dcache.h"
#endif /* HAL_DCACHE_MODULE_ENABLED */
#ifdef HAL_GTZC_MODULE_ENABLED
#include "stm32u5xx_hal_gtzc.h"
#endif /* HAL_GTZC_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32u5xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_DMA2D_MODULE_ENABLED
#include "stm32u5xx_hal_dma2d.h"
#endif /* HAL_DMA2D_MODULE_ENABLED */
#ifdef HAL_DSI_MODULE_ENABLED
#include "stm32u5xx_hal_dsi.h"
#endif /* HAL_DSI_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32u5xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_PKA_MODULE_ENABLED
#include "stm32u5xx_hal_pka.h"
#endif /* HAL_PKA_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32u5xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_COMP_MODULE_ENABLED
#include "stm32u5xx_hal_comp.h"
#endif /* HAL_COMP_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32u5xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32u5xx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED
#include "stm32u5xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32u5xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_HASH_MODULE_ENABLED
#include "stm32u5xx_hal_hash.h"
#endif /* HAL_HASH_MODULE_ENABLED */
#ifdef HAL_SRAM_MODULE_ENABLED
#include "stm32u5xx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */
#ifdef HAL_MMC_MODULE_ENABLED
#include "stm32u5xx_hal_mmc.h"
#endif /* HAL_MMC_MODULE_ENABLED */
#ifdef HAL_NOR_MODULE_ENABLED
#include "stm32u5xx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */
#ifdef HAL_NAND_MODULE_ENABLED
#include "stm32u5xx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32u5xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32u5xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32u5xx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
#ifdef HAL_LTDC_MODULE_ENABLED
#include "stm32u5xx_hal_ltdc.h"
#endif /* HAL_LTDC_MODULE_ENABLED */
#ifdef HAL_OPAMP_MODULE_ENABLED
#include "stm32u5xx_hal_opamp.h"
#endif /* HAL_OPAMP_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32u5xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_OSPI_MODULE_ENABLED
#include "stm32u5xx_hal_ospi.h"
#endif /* HAL_OSPI_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32u5xx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32u5xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
#include "stm32u5xx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SD_MODULE_ENABLED
#include "stm32u5xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32u5xx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32u5xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32u5xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_TSC_MODULE_ENABLED
#include "stm32u5xx_hal_tsc.h"
#endif /* HAL_TSC_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32u5xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32u5xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32u5xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32u5xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32u5xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32u5xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
#include "stm32u5xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_CORDIC_MODULE_ENABLED
#include "stm32u5xx_hal_cordic.h"
#endif /* HAL_CORDIC_MODULE_ENABLED */
#ifdef HAL_DCMI_MODULE_ENABLED
#include "stm32u5xx_hal_dcmi.h"
#endif /* HAL_DCMI_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32u5xx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_FDCAN_MODULE_ENABLED
#include "stm32u5xx_hal_fdcan.h"
#endif /* HAL_FDCAN_MODULE_ENABLED */
#ifdef HAL_FMAC_MODULE_ENABLED
#include "stm32u5xx_hal_fmac.h"
#endif /* HAL_FMAC_MODULE_ENABLED */
#ifdef HAL_GFXMMU_MODULE_ENABLED
#include "stm32u5xx_hal_gfxmmu.h"
#endif /* HAL_GFXMMU_MODULE_ENABLED */
#ifdef HAL_GPU2D_MODULE_ENABLED
#include "stm32u5xx_hal_gpu2d.h"
#endif /* HAL_GPU2D_MODULE_ENABLED */
#ifdef HAL_OTFDEC_MODULE_ENABLED
#include "stm32u5xx_hal_otfdec.h"
#endif /* HAL_OTFDEC_MODULE_ENABLED */
#ifdef HAL_PSSI_MODULE_ENABLED
#include "stm32u5xx_hal_pssi.h"
#endif /* HAL_PSSI_MODULE_ENABLED */
#ifdef HAL_RAMCFG_MODULE_ENABLED
#include "stm32u5xx_hal_ramcfg.h"
#endif /* HAL_RAMCFG_MODULE_ENABLED */
#ifdef HAL_MDF_MODULE_ENABLED
#include "stm32u5xx_hal_mdf.h"
#endif /* HAL_MDF_MODULE_ENABLED */
#ifdef HAL_XSPI_MODULE_ENABLED
#include "stm32u5xx_hal_xspi.h"
#endif /* HAL_XSPI_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr: If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) \
((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t *file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* STM32U5xx_HAL_CONF_H */

@ -0,0 +1 @@
../../firmware/systemview.h

@ -0,0 +1,192 @@
/*
* 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 <irq.h>
#include <supervise.h>
#include <tamper.h>
#include STM32_HAL_H
// Fixes a typo in CMSIS Device library for STM32U5
#undef TAMP_CR3_ITAMP7NOER_Msk
#undef TAMP_CR3_ITAMP7NOER
#define TAMP_CR3_ITAMP7NOER_Msk (0x1UL << TAMP_CR3_ITAMP7NOER_Pos)
#define TAMP_CR3_ITAMP7NOER TAMP_CR3_ITAMP7NOER_Msk
void tamper_init() {
RCC_PeriphCLKInitTypeDef clk_init_def = {0};
RCC_OscInitTypeDef osc_init_def = {0};
// Enable LSI clock
osc_init_def.OscillatorType = RCC_OSCILLATORTYPE_LSI;
osc_init_def.LSIState = RCC_LSI_ON;
HAL_RCC_OscConfig(&osc_init_def);
// Select RTC peripheral clock source
clk_init_def.PeriphClockSelection = RCC_PERIPHCLK_RTC;
clk_init_def.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
HAL_RCCEx_PeriphCLKConfig(&clk_init_def);
// Enable RTC peripheral (tampers are part of it)
__HAL_RCC_RTC_ENABLE();
__HAL_RCC_RTCAPB_CLK_ENABLE();
// Clear all pending interrupts
// They may be some as RTC/TAMP peripherals resides inside the
// backup voltage domain
TAMP->SCR = TAMP_SCR_CTAMP2F | TAMP_SCR_CITAMP1F | TAMP_SCR_CITAMP2F |
TAMP_SCR_CITAMP3F | TAMP_SCR_CITAMP5F | TAMP_SCR_CITAMP6F |
TAMP_SCR_CITAMP7F | TAMP_SCR_CITAMP8F | TAMP_SCR_CITAMP9F |
TAMP_SCR_CITAMP11F | TAMP_SCR_CITAMP12F | TAMP_SCR_CITAMP13F;
NVIC_ClearPendingIRQ(TAMP_IRQn);
// Enable battery and power monitoring (!@# rework it)
RCC->AHB3ENR |= RCC_AHB3ENR_PWREN;
// HAL_PWR_EnableBkUpAccess();
HAL_PWREx_EnableMonitoring();
// HAL_PWR_DisableBkUpAccess();
// Enable all internal tampers (4th and 10th are intentionally skipped)
// We select all of them despite some of them are never triggered
TAMP->CR1 =
TAMP_CR1_ITAMP1E | // backup domain voltage monitoring
TAMP_CR1_ITAMP2E | // temperature monitoring
TAMP_CR1_ITAMP3E | // LSE monitoring (LSECSS)
TAMP_CR1_ITAMP5E | // RTC calendar overflow
TAMP_CR1_ITAMP6E | // JTAG/SWD access when RDP > 0
TAMP_CR1_ITAMP7E | // ADC4 analog watchdog monitoring 1
TAMP_CR1_ITAMP8E | // Monotonic counter 1 overflow
TAMP_CR1_ITAMP9E | // Crypto periherals fault (SAES, AES, PKA, TRNG)
TAMP_CR1_ITAMP11E | // IWDG reset when tamper flag is set
TAMP_CR1_ITAMP12E | // ADC4 analog watchdog monitoring 2
TAMP_CR1_ITAMP13E; // ADC4 analog watchdog monitoring 3
// Switch all internal tampers to the "confirmed" mode
// => all secrets all deleted when any tamper event is triggered
TAMP->CR3 = 0;
// Setup external tampers
// TAMP_IN2 active low, "confirmed" mode
TAMP->CR2 = 0;
// TAMP_CR2_TAMP2TRG;
// Set external tamper input filter
TAMP->FLTCR =
// TAMP_FLTCR_TAMPPUDIS | // disable pre-charge of TAMP_INx pins
(3 << TAMP_FLTCR_TAMPPRCH_Pos) | // pre-charge 8 RTCCLK cycles
(2 << TAMP_FLTCR_TAMPFLT_Pos) | // activated after 4 same samples
(7 << TAMP_FLTCR_TAMPFREQ_Pos); // sampling period RTCCLK / 256 (128Hz)
// Enable all interrupts for all internal tampers
TAMP->IER = TAMP_IER_TAMP2IE | TAMP_IER_ITAMP1IE | TAMP_IER_ITAMP2IE |
TAMP_IER_ITAMP3IE | TAMP_IER_ITAMP5IE | TAMP_IER_ITAMP6IE |
TAMP_IER_ITAMP7IE | TAMP_IER_ITAMP8IE | TAMP_IER_ITAMP9IE |
TAMP_IER_ITAMP11IE | TAMP_IER_ITAMP12IE | TAMP_IER_ITAMP13IE;
// Enable TAMP interrupt at NVIC controller
NVIC_SetPriority(TAMP_IRQn, IRQ_PRI_TAMP);
NVIC_EnableIRQ(TAMP_IRQn);
}
// Interrupt handle for all tamper events
// It displays an error message
void TAMP_IRQHandler(void) {
const char* reason = "UNKNOWN";
uint32_t sr = TAMP->SR;
if (sr & TAMP_SR_TAMP1F) {
reason = "INPUT1";
} else if (sr & TAMP_SR_TAMP2F) {
reason = "INPUT2";
} else if (sr & TAMP_SR_ITAMP1F) {
reason = "VOLTAGE";
} else if (sr & TAMP_SR_ITAMP2F) {
reason = "TEMPERATURE";
} else if (sr & TAMP_SR_ITAMP3F) {
reason = "LSE CLOCK";
} else if (sr & TAMP_SR_ITAMP5F) {
reason = "RTC OVERFLOW";
} else if (sr & TAMP_SR_ITAMP6F) {
reason = "SWD ACCESS";
} else if (sr & TAMP_SR_ITAMP7F) {
reason = "ANALOG WDG1";
} else if (sr & TAMP_SR_ITAMP8F) {
reason = "MONO COUNTER";
} else if (sr & TAMP_SR_ITAMP9F) {
reason = "CRYPTO ERROR";
} else if (sr & TAMP_SR_ITAMP11F) {
reason = "IWDG";
} else if (sr & TAMP_SR_ITAMP12F) {
reason = "ANALOG WDG2";
} else if (sr & TAMP_SR_ITAMP13F) {
reason = "ANALOG WDG3";
}
error_shutdown("INTERNAL TAMPER", reason);
}
// Triggers ITAMP5 by overflowing RTC date/time
static void tamper_test_rtc_overflow(void) {
RTC_HandleTypeDef hrtc;
RTC_DateTypeDef date = {0};
RTC_TimeTypeDef time = {0};
// Initialize RTC and select BCD format for date & time
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
hrtc.Init.BinMode = RTC_BINARY_NONE;
HAL_RTC_Init(&hrtc);
// set date 99/12/31
date.Year = 0x99;
date.Month = 0x12;
date.Date = 0x31;
date.WeekDay = 0x00;
HAL_RTC_SetDate(&hrtc, &date, RTC_FORMAT_BCD);
// set time 23:59:50
time.Hours = 0x23;
time.Minutes = 0x59;
time.Seconds = 0x50;
HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BCD);
}
// Triggers ITAMP8 by overflowing monotonic counter
static void tamper_test_counter_overflow(void) {
for (uint32_t i = 0; i < UINT32_MAX; i++) {
TAMP->COUNTR = 0;
}
TAMP->COUNTR = 0;
}
void tamper_test(uint32_t tamper_bit) {
if (tamper_bit & TAMP_CR1_ITAMP5E) {
tamper_test_rtc_overflow();
} else if (tamper_bit & TAMP_CR1_ITAMP8E) {
tamper_test_counter_overflow();
}
}

@ -0,0 +1,231 @@
#include "trustzone.h"
#ifdef BOARDLOADER
#include STM32_HAL_H
void trustzone_init(void) {
#if defined(__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U)
#if defined(SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U)
SAU_INIT_REGION(0);
#endif
#if defined(SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U)
SAU_INIT_REGION(1);
#endif
#if defined(SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U)
SAU_INIT_REGION(2);
#endif
#if defined(SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U)
SAU_INIT_REGION(3);
#endif
#if defined(SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U)
SAU_INIT_REGION(4);
#endif
#if defined(SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U)
SAU_INIT_REGION(5);
#endif
#if defined(SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U)
SAU_INIT_REGION(6);
#endif
#if defined(SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U)
SAU_INIT_REGION(7);
#endif
/* repeat this for all possible SAU regions */
#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */
#if defined(SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U)
SAU->CTRL =
((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) |
((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk);
#endif
#if defined(SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U)
SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk)) |
((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) &
SCB_SCR_SLEEPDEEPS_Msk);
SCB->AIRCR =
(SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk |
SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk)) |
((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) |
((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) &
SCB_AIRCR_SYSRESETREQS_Msk) |
((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) |
((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) &
SCB_AIRCR_BFHFNMINS_Msk);
#endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */
#if defined(__FPU_USED) && (__FPU_USED == 1U) && defined(TZ_FPU_NS_USAGE) && \
(TZ_FPU_NS_USAGE == 1U)
SCB->NSACR = (SCB->NSACR & ~(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)) |
((SCB_NSACR_CP10_11_VAL << SCB_NSACR_CP10_Pos) &
(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk));
FPU->FPCCR = (FPU->FPCCR & ~(FPU_FPCCR_TS_Msk | FPU_FPCCR_CLRONRETS_Msk |
FPU_FPCCR_CLRONRET_Msk)) |
((FPU_FPCCR_TS_VAL << FPU_FPCCR_TS_Pos) & FPU_FPCCR_TS_Msk) |
((FPU_FPCCR_CLRONRETS_VAL << FPU_FPCCR_CLRONRETS_Pos) &
FPU_FPCCR_CLRONRETS_Msk) |
((FPU_FPCCR_CLRONRET_VAL << FPU_FPCCR_CLRONRET_Pos) &
FPU_FPCCR_CLRONRET_Msk);
#endif
#if defined(NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U)
NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL;
#endif
#if defined(NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U)
NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL;
#endif
#if defined(NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U)
NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL;
#endif
#if defined(NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U)
NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL;
#endif
#if defined(NVIC_INIT_ITNS4) && (NVIC_INIT_ITNS4 == 1U)
NVIC->ITNS[4] = NVIC_INIT_ITNS4_VAL;
#endif
}
void trustzone_run(void) {
uint32_t index;
MPCBB_ConfigTypeDef MPCBB_desc;
/* Enable GTZC peripheral clock */
__HAL_RCC_GTZC1_CLK_ENABLE();
__HAL_RCC_GTZC2_CLK_ENABLE();
// HAL_GPIO_ConfigPinAttributes(GPIOA, 0xFFFF, GPIO_PIN_NSEC);
// HAL_GPIO_ConfigPinAttributes(GPIOB, 0xFFFF, GPIO_PIN_NSEC);
// HAL_GPIO_ConfigPinAttributes(GPIOC, 0xFFFF, GPIO_PIN_NSEC);
// HAL_GPIO_ConfigPinAttributes(GPIOD, 0xFFFF, GPIO_PIN_NSEC);
// HAL_GPIO_ConfigPinAttributes(GPIOE, 0xFFFF, GPIO_PIN_NSEC);
// HAL_GPIO_ConfigPinAttributes(GPIOF, 0xFFFF, GPIO_PIN_NSEC);
// HAL_GPIO_ConfigPinAttributes(GPIOG, 0xFFFF, GPIO_PIN_NSEC);
// HAL_GPIO_ConfigPinAttributes(GPIOH, 0xFFFF, GPIO_PIN_NSEC);
/* -------------------------------------------------------------------------*/
/* Memory isolation configuration */
/* Initializes the memory that secure application books for non secure */
/* -------------------------------------------------------------------------*/
/* -------------------------------------------------------------------------*/
/* Internal RAM : */
/* The booking is done through GTZC MPCBB. */
/* Internal SRAMs are secured by default and configured by block */
/* of 512 bytes. */
/* Internal SRAM3 (starting from 0x20040000) will be configured as */
/* fully non-secure. */
MPCBB_desc.SecureRWIllegalMode = GTZC_MPCBB_SRWILADIS_DISABLE;
MPCBB_desc.InvertSecureState = GTZC_MPCBB_INVSECSTATE_NOT_INVERTED;
MPCBB_desc.AttributeConfig.MPCBB_LockConfig_array[0] =
0x00000000U; /* Unlocked configuration */
for (index = 0; index < 52; index++) {
/* Non-secure blocks */
MPCBB_desc.AttributeConfig.MPCBB_SecConfig_array[index] = 0x00000000U;
MPCBB_desc.AttributeConfig.MPCBB_PrivConfig_array[index] = 0x00000000U;
}
if (HAL_GTZC_MPCBB_ConfigMem(SRAM1_BASE, &MPCBB_desc) != HAL_OK) {
/* Initialization Error */
while (1)
;
}
if (HAL_GTZC_MPCBB_ConfigMem(SRAM2_BASE, &MPCBB_desc) != HAL_OK) {
/* Initialization Error */
while (1)
;
}
if (HAL_GTZC_MPCBB_ConfigMem(SRAM3_BASE, &MPCBB_desc) != HAL_OK) {
/* Initialization Error */
while (1)
;
}
if (HAL_GTZC_MPCBB_ConfigMem(SRAM4_BASE, &MPCBB_desc) != HAL_OK) {
/* Initialization Error */
while (1)
;
}
if (HAL_GTZC_MPCBB_ConfigMem(SRAM5_BASE, &MPCBB_desc) != HAL_OK) {
/* Initialization Error */
while (1)
;
}
/* -------------------------------------------------------------------------*/
/* Internal Flash */
/* The booking is done in both IDAU/SAU and FLASH interface */
/* Setup done based on Flash dual-bank mode described with 1 area per bank */
/* Non-secure Flash memory area starting from 0x08100000 (Bank2) */
/* Flash memory is secured by default and modified with Option Byte Loading */
/* Insure SECWM2_PSTRT > SECWM2_PEND in order to have all Bank2 non-secure */
/* -------------------------------------------------------------------------*/
/* External OctoSPI memory */
/* The booking is done in both IDAU/SAU and GTZC MPCWM interface */
/* Default secure configuration */
/* Else need to use HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes() */
/* -------------------------------------------------------------------------*/
/* External NOR/FMC memory */
/* The booking is done in both IDAU/SAU and GTZC MPCWM interface */
/* Default secure configuration */
/* Else need to use HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes() */
/* -------------------------------------------------------------------------*/
/* External NAND/FMC memory */
/* The booking is done in both IDAU/SAU and GTZC MPCWM interface */
/* Default secure configuration */
/* Else need to use HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes() */
/* -------------------------------------------------------------------------*/
/* Peripheral isolation configuration */
/* Initializes the peripherals and features that secure application books */
/* for secure (RCC, PWR, RTC, EXTI, DMA, OTFDEC, etc..) or leave them to */
/* non-secure (GPIO (secured by default)) */
/* -------------------------------------------------------------------------*/
// /* Clear all illegal access flags in GTZC TZIC */
// if(HAL_GTZC_TZIC_ClearFlag(GTZC_PERIPH_ALL) != HAL_OK)
// {
// /* Initialization Error */
// while(1);
// }
//
// /* Enable all illegal access interrupts in GTZC TZIC */
// if(HAL_GTZC_TZIC_EnableIT(GTZC_PERIPH_ALL) != HAL_OK)
// {
// /* Initialization Error */
// while(1);
// }
//
// /* Enable GTZC secure interrupt */
// HAL_NVIC_SetPriority(GTZC_IRQn, 0, 0); /* Highest priority level */
// HAL_NVIC_EnableIRQ(GTZC_IRQn);
}
#endif

@ -0,0 +1 @@
../stm32f4/usb_hid-impl.h

@ -0,0 +1 @@
../stm32f4/usb_vcp-impl.h

@ -0,0 +1 @@
../stm32f4/usb_webusb-impl.h

@ -0,0 +1 @@
../stm32f4/usbd_ctlreq.c

@ -0,0 +1 @@
../stm32f4/usbd_ctlreq.h

@ -0,0 +1,177 @@
.syntax unified
.text
.global memset_reg
.type memset_reg, STT_FUNC
memset_reg:
// call with the following (note that the arguments are not validated prior to use):
// r0 - address of first word to write (inclusive)
// r1 - address of first word following the address in r0 to NOT write (exclusive)
// r2 - word value to be written
// both addresses in r0 and r1 needs to be divisible by 4!
.L_loop_begin:
str r2, [r0], 4 // store the word in r2 to the address in r0, post-indexed
cmp r0, r1
bne .L_loop_begin
bx lr
// Jump to address given in first argument R0 that points to next's stage's VTOR
// Clear memory and all registers before jump
.global jump_to
.type jump_to, STT_FUNC
jump_to:
ldr r1, =0
bl jump_to_with_flag
// Jump to address given in first argument R0 that points to next's stage's VTOR
// Clear memory and all registers before jump. Second argument R1 is copied to R11
// and kept after jump.
.global jump_to_with_flag
.type jump_to_with_flag, STT_FUNC
jump_to_with_flag:
mov r4, r0 // save input argument r0 (the address of the next stage's vector table) (r4 is callee save)
mov r11, r1 // save second argument in "flag" register because we'll be cleaning RAM
// this subroutine re-points the exception handlers before the C code
// that comprises them has been given a good environment to run.
// therefore, this code needs to disable interrupts before the VTOR
// update. then, the reset_handler of the next stage needs to re-enable interrupts.
// the following prevents activation of all exceptions except Non-Maskable Interrupt (NMI).
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.8:
// "there is no requirement to insert memory barrier instructions after CPSID".
cpsid f
// wipe memory at the end of the current stage of code
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =_stay_in_bootloader_flag_addr // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
mov lr, r4
// clear out the general purpose registers before the next stage's except the register with flag R11
ldr r0, =0
mov r1, r0
mov r2, r0
mov r3, r0
mov r4, r0
mov r5, r0
mov r6, r0
mov r7, r0
mov r8, r0
mov r9, r0
mov r10, r0
mov r12, r0
// give the next stage a fresh main stack pointer
ldr r0, [lr] // set r0 to the main stack pointer in the next stage's vector table
msr msp, r0 // give the next stage its main stack pointer
// point to the next stage's exception handlers
// AN321, section 4.11: "a memory barrier is not required after a VTOR update"
.set SCB_VTOR, 0xE000ED08 // reference "Cortex-M4 Devices Generic User Guide" section 4.3
ldr r0, =SCB_VTOR
str lr, [r0]
mov r0, r1 // zero out r0
// go on to the next stage
ldr lr, [lr, 4] // set lr to the next stage's reset_handler
bx lr
.global jump_to_unprivileged
.type jump_to_unprivileged, STT_FUNC
jump_to_unprivileged:
mov r4, r0 // save input argument r0 (the address of the next stage's vector table) (r4 is callee save)
// this subroutine re-points the exception handlers before the C code
// that comprises them has been given a good environment to run.
// therefore, this code needs to disable interrupts before the VTOR
// update. then, the reset_handler of the next stage needs to re-enable interrupts.
// the following prevents activation of all exceptions except Non-Maskable Interrupt (NMI).
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.8:
// "there is no requirement to insert memory barrier instructions after CPSID".
cpsid f
// wipe memory at the end of the current stage of code
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
// r2 - the word-sized value to be written
bl memset_reg
mov lr, r4
// clear out the general purpose registers before the next stage's code can run (even the NMI exception handler)
ldr r0, =0
mov r1, r0
mov r2, r0
mov r3, r0
mov r4, r0
mov r5, r0
mov r6, r0
mov r7, r0
mov r8, r0
mov r9, r0
mov r10, r0
mov r11, r0
mov r12, r0
// give the next stage a fresh main stack pointer
ldr r0, [lr] // set r0 to the main stack pointer in the next stage's vector table
msr msp, r0 // give the next stage its main stack pointer
// point to the next stage's exception handlers
// AN321, section 4.11: "a memory barrier is not required after a VTOR update"
.set SCB_VTOR, 0xE000ED08 // reference "Cortex-M4 Devices Generic User Guide" section 4.3
ldr r0, =SCB_VTOR
str lr, [r0]
mov r0, r1 // zero out r0
// go on to the next stage
ldr lr, [lr, 4] // set lr to the next stage's reset_handler
// switch to unprivileged mode
ldr r0, =1
msr control, r0
isb
// jump
bx lr
.global shutdown_privileged
.type shutdown_privileged, STT_FUNC
// The function must be called from the privileged mode
shutdown_privileged:
cpsid f // disable all exceptions (except for NMI), the instruction is ignored in unprivileged mode
// if the exceptions weren't disabled, an exception handler (for example systick handler)
// could be called after the memory is erased, which would lead to another exception
ldr r0, =0
mov r1, r0
mov r2, r0
mov r3, r0
mov r4, r0
mov r5, r0
mov r6, r0
mov r7, r0
mov r8, r0
mov r9, r0
mov r10, r0
mov r11, r0
mov r12, r0
ldr lr, =0xffffffff
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram4_start // r0 - point to beginning of SRAM
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =1
msr control, r0 // jump to unprivileged mode
ldr r0, =0
b . // loop forever
.end

@ -0,0 +1,177 @@
.syntax unified
.text
.global default_handler
.type default_handler, STT_FUNC
default_handler:
b shutdown_privileged
.macro add_handler symbol_name:req
.word \symbol_name
.weak \symbol_name
.thumb_set \symbol_name, default_handler
.endm
// Reference:
// Table 62 - STM32F427 Reference manual (RM0090)
// Section B1.5 - ARMv7-M Architecture Reference Manual
.section .vector_table, "a"
vector_table:
.word main_stack_base // defined in linker script
add_handler reset_handler
add_handler NMI_Handler
add_handler HardFault_Handler
add_handler MemManage_Handler
add_handler BusFault_Handler
add_handler UsageFault_Handler
add_handler SecureFault_Handler
add_handler architecture_reserved_handler
add_handler architecture_reserved_handler
add_handler architecture_reserved_handler
add_handler SVC_Handler
add_handler DebugMon_Handler
add_handler architecture_reserved_handler
add_handler PendSV_Handler
add_handler SysTick_Handler
add_handler WWDG_IRQHandler
add_handler PVD_PVM_IRQHandler
add_handler RTC_IRQHandler
add_handler RTC_S_IRQHandler
add_handler TAMP_IRQHandler
add_handler RAMCFG_IRQHandler
add_handler FLASH_IRQHandler
add_handler FLASH_S_IRQHandler
add_handler GTZC_IRQHandler
add_handler RCC_IRQHandler
add_handler RCC_S_IRQHandler
add_handler EXTI0_IRQHandler
add_handler EXTI1_IRQHandler
add_handler EXTI2_IRQHandler
add_handler EXTI3_IRQHandler
add_handler EXTI4_IRQHandler
add_handler EXTI5_IRQHandler
add_handler EXTI6_IRQHandler
add_handler EXTI7_IRQHandler
add_handler EXTI8_IRQHandler
add_handler EXTI9_IRQHandler
add_handler EXTI10_IRQHandler
add_handler EXTI11_IRQHandler
add_handler EXTI12_IRQHandler
add_handler EXTI13_IRQHandler
add_handler EXTI14_IRQHandler
add_handler EXTI15_IRQHandler
add_handler IWDG_IRQHandler
add_handler SAES_IRQHandler
add_handler GPDMA1_Channel0_IRQHandler
add_handler GPDMA1_Channel1_IRQHandler
add_handler GPDMA1_Channel2_IRQHandler
add_handler GPDMA1_Channel3_IRQHandler
add_handler GPDMA1_Channel4_IRQHandler
add_handler GPDMA1_Channel5_IRQHandler
add_handler GPDMA1_Channel6_IRQHandler
add_handler GPDMA1_Channel7_IRQHandler
add_handler ADC1_2_IRQHandler
add_handler DAC1_IRQHandler
add_handler FDCAN1_IT0_IRQHandler
add_handler FDCAN1_IT1_IRQHandler
add_handler TIM1_BRK_IRQHandler
add_handler TIM1_UP_IRQHandler
add_handler TIM1_TRG_COM_IRQHandler
add_handler TIM1_CC_IRQHandler
add_handler TIM2_IRQHandler
add_handler TIM3_IRQHandler
add_handler TIM4_IRQHandler
add_handler TIM5_IRQHandler
add_handler TIM6_IRQHandler
add_handler TIM7_IRQHandler
add_handler TIM8_BRK_IRQHandler
add_handler TIM8_UP_IRQHandler
add_handler TIM8_TRG_COM_IRQHandler
add_handler TIM8_CC_IRQHandler
add_handler I2C1_EV_IRQHandler
add_handler I2C1_ER_IRQHandler
add_handler I2C2_EV_IRQHandler
add_handler I2C2_ER_IRQHandler
add_handler SPI1_IRQHandler
add_handler SPI2_IRQHandler
add_handler USART1_IRQHandler
add_handler USART2_IRQHandler
add_handler USART3_IRQHandler
add_handler UART4_IRQHandler
add_handler UART5_IRQHandler
add_handler LPUART1_IRQHandler
add_handler LPTIM1_IRQHandler
add_handler LPTIM2_IRQHandler
add_handler TIM15_IRQHandler
add_handler TIM16_IRQHandler
add_handler TIM17_IRQHandler
add_handler COMP_IRQHandler
add_handler OTG_HS_IRQHandler
add_handler CRS_IRQHandler
add_handler FMC_IRQHandler
add_handler OCTOSPI1_IRQHandler
add_handler PWR_S3WU_IRQHandler
add_handler SDMMC1_IRQHandler
add_handler SDMMC2_IRQHandler
add_handler GPDMA1_Channel8_IRQHandler
add_handler GPDMA1_Channel9_IRQHandler
add_handler GPDMA1_Channel10_IRQHandler
add_handler GPDMA1_Channel11_IRQHandler
add_handler GPDMA1_Channel12_IRQHandler
add_handler GPDMA1_Channel13_IRQHandler
add_handler GPDMA1_Channel14_IRQHandler
add_handler GPDMA1_Channel15_IRQHandler
add_handler I2C3_EV_IRQHandler
add_handler I2C3_ER_IRQHandler
add_handler SAI1_IRQHandler
add_handler SAI2_IRQHandler
add_handler TSC_IRQHandler
add_handler AES_IRQHandler
add_handler RNG_IRQHandler
add_handler FPU_IRQHandler
add_handler HASH_IRQHandler
add_handler PKA_IRQHandler
add_handler LPTIM3_IRQHandler
add_handler SPI3_IRQHandler
add_handler I2C4_ER_IRQHandler
add_handler I2C4_EV_IRQHandler
add_handler MDF1_FLT0_IRQHandler
add_handler MDF1_FLT1_IRQHandler
add_handler MDF1_FLT2_IRQHandler
add_handler MDF1_FLT3_IRQHandler
add_handler UCPD1_IRQHandler
add_handler ICACHE_IRQHandler
add_handler OTFDEC1_IRQHandler
add_handler OTFDEC2_IRQHandler
add_handler LPTIM4_IRQHandler
add_handler DCACHE1_IRQHandler
add_handler ADF1_IRQHandler
add_handler ADC4_IRQHandler
add_handler LPDMA1_Channel0_IRQHandler
add_handler LPDMA1_Channel1_IRQHandler
add_handler LPDMA1_Channel2_IRQHandler
add_handler LPDMA1_Channel3_IRQHandler
add_handler DMA2D_IRQHandler
add_handler DCMI_PSSI_IRQHandler
add_handler OCTOSPI2_IRQHandler
add_handler MDF1_FLT4_IRQHandler
add_handler MDF1_FLT5_IRQHandler
add_handler CORDIC_IRQHandler
add_handler FMAC_IRQHandler
add_handler LSECSSD_IRQHandler
add_handler USART6_IRQHandler
add_handler I2C5_ER_IRQHandler
add_handler I2C5_EV_IRQHandler
add_handler I2C6_ER_IRQHandler
add_handler I2C6_EV_IRQHandler
add_handler HSPI1_IRQHandler
add_handler GPU2D_IRQHandler
add_handler GPU2D_ER_IRQHandler
add_handler GFXMMU_IRQHandler
add_handler LTDC_IRQHandler
add_handler LTDC_ER_IRQHandler
add_handler DSI_IRQHandler
add_handler DCACHE2_IRQHandler
.end

@ -0,0 +1,38 @@
/*
* 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/>.
*/
#ifndef TREZOR_HAL_TAMPER_H
#define TREZOR_HAL_TAMPER_H
#include <stdint.h>
// Tamper module enables the internal tamper detection on STM32 microcontroller
// as well as external tamper input if it's available on the device
// Initializes the tamper detection
void tamper_init(void);
// Triggers one of internal tampers.
// The function is intended for experimentation with internal tamper mechanism
// Use TAMP_CR1_xxx constants to as a parameter
// Only TAMP_CR1_ITAMP5E (RTC) and TAMP_CR1_ITAMP8E (monotonic counter)
// are supported
void tamper_test(uint32_t tamper_type);
#endif // TREZOR_HAL_TAMPER_H

@ -0,0 +1,574 @@
#ifndef __TREZORHAL_TRUSTZONE__
#define __TREZORHAL_TRUSTZONE__
#ifdef BOARDLOADER
#define CMSE_NS_CALL __attribute((cmse_nonsecure_call))
#define CMSE_NS_ENTRY __attribute((cmse_nonsecure_entry))
typedef void CMSE_NS_CALL (*funcptr)(void);
/* typedef for non-secure callback functions */
typedef funcptr funcptr_NS;
#include STM32_HAL_H
/*
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
*/
/*
// <e>Initialize Security Attribution Unit (SAU) CTRL register
*/
#define SAU_INIT_CTRL 1
/*
// <q> Enable SAU
// <i> Value for SAU->CTRL register bit ENABLE
*/
#define SAU_INIT_CTRL_ENABLE 0
/*
// <o> When SAU is disabled
// <0=> All Memory is Secure
// <1=> All Memory is Non-Secure
// <i> Value for SAU->CTRL register bit ALLNS
// <i> When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory
map configuration.
*/
#define SAU_INIT_CTRL_ALLNS 1
/*
// </e>
*/
/*
// <h>Initialize Security Attribution Unit (SAU) Address Regions
// <i>SAU configuration specifies regions to be one of:
// <i> - Secure and Non-Secure Callable
// <i> - Non-Secure
// <i>Note: All memory regions not configured by SAU are Secure
*/
#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */
/*
// <e>Initialize SAU Region 0
// <i> Setup SAU Region 0 memory attributes
*/
#define SAU_INIT_REGION0 0
/*
// <o>Start Address <0-0xFFFFFFE0>
*/
#define SAU_INIT_START0 0x0C1FE000 /* start address of SAU region 0 */
/*
// <o>End Address <0x1F-0xFFFFFFFF>
*/
#define SAU_INIT_END0 0x0C1FFFFF /* end address of SAU region 0 */
/*
// <o>Region is
// <0=>Non-Secure
// <1=>Secure, Non-Secure Callable
*/
#define SAU_INIT_NSC0 1
/*
// </e>
*/
/*
// <e>Initialize SAU Region 1
// <i> Setup SAU Region 1 memory attributes
*/
#define SAU_INIT_REGION1 0
/*
// <o>Start Address <0-0xFFFFFFE0>
*/
#define SAU_INIT_START1 0x08200000 /* start address of SAU region 1 */
/*
// <o>End Address <0x1F-0xFFFFFFFF>
*/
#define SAU_INIT_END1 0x083FFFFF /* end address of SAU region 1 */
/*
// <o>Region is
// <0=>Non-Secure
// <1=>Secure, Non-Secure Callable
*/
#define SAU_INIT_NSC1 0
/*
// </e>
*/
/*
// <e>Initialize SAU Region 2
// <i> Setup SAU Region 2 memory attributes
*/
#define SAU_INIT_REGION2 0
/*
// <o>Start Address <0-0xFFFFFFE0>
*/
#define SAU_INIT_START2 0x200D0000 /* start address of SAU region 2 */
/*
// <o>End Address <0x1F-0xFFFFFFFF>
*/
#define SAU_INIT_END2 0x2026FFFF /* end address of SAU region 2 */
/*
// <o>Region is
// <0=>Non-Secure
// <1=>Secure, Non-Secure Callable
*/
#define SAU_INIT_NSC2 0
/*
// </e>
*/
/*
// <e>Initialize SAU Region 3
// <i> Setup SAU Region 3 memory attributes
*/
#define SAU_INIT_REGION3 0
/*
// <o>Start Address <0-0xFFFFFFE0>
*/
#define SAU_INIT_START3 0x40000000 /* start address of SAU region 3 */
/*
// <o>End Address <0x1F-0xFFFFFFFF>
*/
#define SAU_INIT_END3 0x4FFFFFFF /* end address of SAU region 3 */
/*
// <o>Region is
// <0=>Non-Secure
// <1=>Secure, Non-Secure Callable
*/
#define SAU_INIT_NSC3 0
/*
// </e>
*/
/*
// <e>Initialize SAU Region 4
// <i> Setup SAU Region 4 memory attributes
*/
#define SAU_INIT_REGION4 0
/*
// <o>Start Address <0-0xFFFFFFE0>
*/
#define SAU_INIT_START4 0x60000000 /* start address of SAU region 4 */
/*
// <o>End Address <0x1F-0xFFFFFFFF>
*/
#define SAU_INIT_END4 0xAFFFFFFF /* end address of SAU region 4 */
/*
// <o>Region is
// <0=>Non-Secure
// <1=>Secure, Non-Secure Callable
*/
#define SAU_INIT_NSC4 0
/*
// </e>
*/
/*
// <e>Initialize SAU Region 5
// <i> Setup SAU Region 5 memory attributes
*/
#define SAU_INIT_REGION5 0
/*
// <o>Start Address <0-0xFFFFFFE0>
*/
#define SAU_INIT_START5 0x0BF90000 /* start address of SAU region 5 */
/*
// <o>End Address <0x1F-0xFFFFFFFF>
*/
#define SAU_INIT_END5 0x0BFA8FFF /* end address of SAU region 5 */
/*
// <o>Region is
// <0=>Non-Secure
// <1=>Secure, Non-Secure Callable
*/
#define SAU_INIT_NSC5 0
/*
// </e>
*/
/*
// <e>Initialize SAU Region 6
// <i> Setup SAU Region 6 memory attributes
*/
#define SAU_INIT_REGION6 0
/*
// <o>Start Address <0-0xFFFFFFE0>
*/
#define SAU_INIT_START6 0x00000000 /* start address of SAU region 6 */
/*
// <o>End Address <0x1F-0xFFFFFFFF>
*/
#define SAU_INIT_END6 0x00000000 /* end address of SAU region 6 */
/*
// <o>Region is
// <0=>Non-Secure
// <1=>Secure, Non-Secure Callable
*/
#define SAU_INIT_NSC6 0
/*
// </e>
*/
/*
// <e>Initialize SAU Region 7
// <i> Setup SAU Region 7 memory attributes
*/
#define SAU_INIT_REGION7 0
/*
// <o>Start Address <0-0xFFFFFFE0>
*/
#define SAU_INIT_START7 0x00000000 /* start address of SAU region 7 */
/*
// <o>End Address <0x1F-0xFFFFFFFF>
*/
#define SAU_INIT_END7 0x00000000 /* end address of SAU region 7 */
/*
// <o>Region is
// <0=>Non-Secure
// <1=>Secure, Non-Secure Callable
*/
#define SAU_INIT_NSC7 0
/*
// </e>
*/
/*
// </h>
*/
/*
// <e>Setup behaviour of Sleep and Exception Handling
*/
#define SCB_CSR_AIRCR_INIT 0
/*
// <o> Deep Sleep can be enabled by
// <0=>Secure and Non-Secure state
// <1=>Secure state only
// <i> Value for SCB->CSR register bit DEEPSLEEPS
*/
#define SCB_CSR_DEEPSLEEPS_VAL 0
/*
// <o>System reset request accessible from
// <0=> Secure and Non-Secure state
// <1=> Secure state only
// <i> Value for SCB->AIRCR register bit SYSRESETREQS
*/
#define SCB_AIRCR_SYSRESETREQS_VAL 0
/*
// <o>Priority of Non-Secure exceptions is
// <0=> Not altered
// <1=> Lowered to 0x04-0x07
// <i> Value for SCB->AIRCR register bit PRIS
*/
#define SCB_AIRCR_PRIS_VAL 0
/*
// <o>BusFault, HardFault, and NMI target
// <0=> Secure state
// <1=> Non-Secure state
// <i> Value for SCB->AIRCR register bit BFHFNMINS
*/
#define SCB_AIRCR_BFHFNMINS_VAL 0
/*
// </e>
*/
/*
// <e>Setup behaviour of Floating Point Unit
*/
#define TZ_FPU_NS_USAGE 1
/*
// <o>Floating Point Unit usage
// <0=> Secure state only
// <3=> Secure and Non-Secure state
// <i> Value for SCB->NSACR register bits CP10, CP11
*/
#define SCB_NSACR_CP10_11_VAL 3
/*
// <o>Treat floating-point registers as Secure
// <0=> Disabled
// <1=> Enabled
// <i> Value for FPU->FPCCR register bit TS
*/
#define FPU_FPCCR_TS_VAL 0
/*
// <o>Clear on return (CLRONRET) accessibility
// <0=> Secure and Non-Secure state
// <1=> Secure state only
// <i> Value for FPU->FPCCR register bit CLRONRETS
*/
#define FPU_FPCCR_CLRONRETS_VAL 0
/*
// <o>Clear floating-point caller saved registers on exception return
// <0=> Disabled
// <1=> Enabled
// <i> Value for FPU->FPCCR register bit CLRONRET
*/
#define FPU_FPCCR_CLRONRET_VAL 1
/*
// </e>
*/
/*
// <h>Setup Interrupt Target
*/
/*
// <e>Initialize ITNS 0 (Interrupts 0..31)
*/
#define NVIC_INIT_ITNS0 1
/*
// Interrupts 0..31
// <o.0> WWDG_IRQn <0=> Secure state <1=> Non-Secure state
// <o.1> PVD_PVM_IRQn <0=> Secure state <1=> Non-Secure state
// <o.2> RTC_IRQn <0=> Secure state <1=> Non-Secure state
// <o.3> RTC_S_IRQn <0=> Secure state <1=> Non-Secure state
// <o.4> TAMP_IRQn <0=> Secure state <1=> Non-Secure state
// <o.5> RAMCFG_IRQn <0=> Secure state <1=> Non-Secure state
// <o.6> FLASH_IRQn <0=> Secure state <1=> Non-Secure state
// <o.7> FLASH_S_IRQn <0=> Secure state <1=> Non-Secure state
// <o.8> GTZC_IRQn <0=> Secure state <1=> Non-Secure state
// <o.9> RCC_IRQn <0=> Secure state <1=> Non-Secure state
// <o.10> RCC_S_IRQn <0=> Secure state <1=> Non-Secure state
// <o.11> EXTI0_IRQn <0=> Secure state <1=> Non-Secure state
// <o.12> EXTI1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.13> EXTI2_IRQn <0=> Secure state <1=> Non-Secure state
// <o.14> EXTI3_IRQn <0=> Secure state <1=> Non-Secure state
// <o.15> EXTI4_IRQn <0=> Secure state <1=> Non-Secure state
// <o.16> EXTI5_IRQn <0=> Secure state <1=> Non-Secure state
// <o.17> EXTI6_IRQn <0=> Secure state <1=> Non-Secure state
// <o.18> EXTI7_IRQn <0=> Secure state <1=> Non-Secure state
// <o.19> EXTI8_IRQn <0=> Secure state <1=> Non-Secure state
// <o.20> EXTI9_IRQn <0=> Secure state <1=> Non-Secure state
// <o.21> EXTI10_IRQn <0=> Secure state <1=> Non-Secure state
// <o.22> EXTI11_IRQn <0=> Secure state <1=> Non-Secure state
// <o.23> EXTI12_IRQn <0=> Secure state <1=> Non-Secure state
// <o.24> EXTI13_IRQn <0=> Secure state <1=> Non-Secure state
// <o.25> EXTI14_IRQn <0=> Secure state <1=> Non-Secure state
// <o.26> EXTI15_IRQn <0=> Secure state <1=> Non-Secure state
// <o.27> IWDG_IRQn <0=> Secure state <1=> Non-Secure state
// <o.29> GPDMA1_Channel0_IRQn <0=> Secure state <1=> Non-Secure state
// <o.30> GPDMA1_Channel1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.31> GPDMA1_Channel2_IRQn <0=> Secure state <1=> Non-Secure state
*/
#define NVIC_INIT_ITNS0_VAL 0x00000000
/*
// </e>
*/
/*
// <e>Initialize ITNS 1 (Interrupts 32..63)
*/
#define NVIC_INIT_ITNS1 1
/*
// Interrupts 32..63
// <o.0> GPDMA1_Channel3_IRQn <0=> Secure state <1=> Non-Secure state
// <o.1> GPDMA1_Channel4_IRQn <0=> Secure state <1=> Non-Secure state
// <o.2> GPDMA1_Channel5_IRQn <0=> Secure state <1=> Non-Secure state
// <o.3> GPDMA1_Channel6_IRQn <0=> Secure state <1=> Non-Secure state
// <o.4> GPDMA1_Channel7_IRQn <0=> Secure state <1=> Non-Secure state
// <o.5> ADC1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.6> DAC1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.7> FDCAN1_IT0_IRQn <0=> Secure state <1=> Non-Secure state
// <o.8> FDCAN1_IT1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.9> TIM1_BRK_IRQn <0=> Secure state <1=> Non-Secure state
// <o.10> TIM1_UP_IRQn <0=> Secure state <1=> Non-Secure state
// <o.11> TIM1_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state
// <o.12> TIM1_CC_IRQn <0=> Secure state <1=> Non-Secure state
// <o.13> TIM2_IRQn <0=> Secure state <1=> Non-Secure state
// <o.14> TIM3_IRQn <0=> Secure state <1=> Non-Secure state
// <o.15> TIM4_IRQn <0=> Secure state <1=> Non-Secure state
// <o.16> TIM5_IRQn <0=> Secure state <1=> Non-Secure state
// <o.17> TIM6_IRQn <0=> Secure state <1=> Non-Secure state
// <o.18> TIM7_IRQn <0=> Secure state <1=> Non-Secure state
// <o.19> TIM8_BRK_IRQn <0=> Secure state <1=> Non-Secure state
// <o.20> TIM8_UP_IRQn <0=> Secure state <1=> Non-Secure state
// <o.21> TIM8_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state
// <o.22> TIM8_CC_IRQn <0=> Secure state <1=> Non-Secure state
// <o.23> I2C1_EV_IRQn <0=> Secure state <1=> Non-Secure state
// <o.24> I2C1_ER_IRQn <0=> Secure state <1=> Non-Secure state
// <o.25> I2C2_EV_IRQn <0=> Secure state <1=> Non-Secure state
// <o.26> I2C2_ER_IRQn <0=> Secure state <1=> Non-Secure state
// <o.27> SPI1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.28> SPI2_IRQn <0=> Secure state <1=> Non-Secure state
// <o.29> USART1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.30> USART2_IRQn <0=> Secure state <1=> Non-Secure state
// <o.31> USART3_IRQn <0=> Secure state <1=> Non-Secure state
*/
#define NVIC_INIT_ITNS1_VAL 0x00000000
/*
// </e>
*/
/*
// <e>Initialize ITNS 2 (Interrupts 64..95)
*/
#define NVIC_INIT_ITNS2 1
/*
// Interrupts 64..95
// <o.0> UART4_IRQn <0=> Secure state <1=> Non-Secure state
// <o.1> UART5_IRQn <0=> Secure state <1=> Non-Secure state
// <o.2> LPUART1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.3> LPTIM1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.4> LPTIM2_IRQn <0=> Secure state <1=> Non-Secure state
// <o.5> TIM15_IRQn <0=> Secure state <1=> Non-Secure state
// <o.6> TIM16_IRQn <0=> Secure state <1=> Non-Secure state
// <o.7> TIM17_IRQn <0=> Secure state <1=> Non-Secure state
// <o.8> COMP_IRQn <0=> Secure state <1=> Non-Secure state
// <o.9> OTG_HS_IRQn <0=> Secure state <1=> Non-Secure state
// <o.10> CRS_IRQn <0=> Secure state <1=> Non-Secure state
// <o.11> FMC_IRQn <0=> Secure state <1=> Non-Secure state
// <o.12> OCTOSPI1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.13> PWR_S3WU_IRQn <0=> Secure state <1=> Non-Secure state
// <o.14> SDMMC1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.15> SDMMC2_IRQn <0=> Secure state <1=> Non-Secure state
// <o.16> GPDMA1_Channel8_IRQn <0=> Secure state <1=> Non-Secure state
// <o.17> GPDMA1_Channel9_IRQn <0=> Secure state <1=> Non-Secure state
// <o.18> GPDMA1_Channel10_IRQn <0=> Secure state <1=> Non-Secure state
// <o.19> GPDMA1_Channel11_IRQn <0=> Secure state <1=> Non-Secure state
// <o.20> GPDMA1_Channel12_IRQn <0=> Secure state <1=> Non-Secure state
// <o.21> GPDMA1_Channel13_IRQn <0=> Secure state <1=> Non-Secure state
// <o.22> GPDMA1_Channel14_IRQn <0=> Secure state <1=> Non-Secure state
// <o.23> GPDMA1_Channel15_IRQn <0=> Secure state <1=> Non-Secure state
// <o.24> I2C3_EV_IRQn <0=> Secure state <1=> Non-Secure state
// <o.25> I2C3_ER_IRQn <0=> Secure state <1=> Non-Secure state
// <o.26> SAI1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.27> SAI2_IRQn <0=> Secure state <1=> Non-Secure state
// <o.28> TSC_IRQn <0=> Secure state <1=> Non-Secure state
// <o.30> RNG_IRQn <0=> Secure state <1=> Non-Secure state
// <o.31> FPU_IRQn <0=> Secure state <1=> Non-Secure state
*/
#define NVIC_INIT_ITNS2_VAL 0x00000000
/*
// </e>
*/
/*
// <e>Initialize ITNS 3 (Interrupts 96..127)
*/
#define NVIC_INIT_ITNS3 1
/*
// Interrupts 96..127
// <o.0> HASH_IRQn <0=> Secure state <1=> Non-Secure state
// <o.2> LPTIM3_IRQn <0=> Secure state <1=> Non-Secure state
// <o.3> SPI3_IRQn <0=> Secure state <1=> Non-Secure state
// <o.4> I2C4_ER_IRQn <0=> Secure state <1=> Non-Secure state
// <o.5> I2C4_EV_IRQn <0=> Secure state <1=> Non-Secure state
// <o.6> MDF1_FLT0_IRQn <0=> Secure state <1=> Non-Secure state
// <o.7> MDF1_FLT1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.8> MDF1_FLT2_IRQn <0=> Secure state <1=> Non-Secure state
// <o.9> MDF1_FLT3_IRQn <0=> Secure state <1=> Non-Secure state
// <o.10> UCPD1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.11> ICACHE_IRQn <0=> Secure state <1=> Non-Secure state
// <o.14> LPTIM4_IRQn <0=> Secure state <1=> Non-Secure state
// <o.15> DCACHE1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.16> ADF1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.17> ADC4_IRQn <0=> Secure state <1=> Non-Secure state
// <o.18> LPDMA1_Channel0_IRQn <0=> Secure state <1=> Non-Secure state
// <o.19> LPDMA1_Channel1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.20> LPDMA1_Channel2_IRQn <0=> Secure state <1=> Non-Secure state
// <o.21> LPDMA1_Channel3_IRQn <0=> Secure state <1=> Non-Secure state
// <o.22> DMA2D_IRQn <0=> Secure state <1=> Non-Secure state
// <o.23> DCMI_PSSI_IRQn <0=> Secure state <1=> Non-Secure state
// <o.24> OCTOSPI2_IRQn <0=> Secure state <1=> Non-Secure state
// <o.25> MDF1_FLT4_IRQn <0=> Secure state <1=> Non-Secure state
// <o.26> MDF1_FLT5_IRQn <0=> Secure state <1=> Non-Secure state
// <o.27> CORDIC_IRQn <0=> Secure state <1=> Non-Secure state
// <o.28> FMAC_IRQn <0=> Secure state <1=> Non-Secure state
// <o.30> USART6_IRQn <0=> Secure state <1=> Non-Secure state
// <o.31> I2C5_ER_IRQn <0=> Secure state <1=> Non-Secure state
*/
#define NVIC_INIT_ITNS3_VAL 0x00000000
/*
// </e>
*/
/*
// <e>Initialize ITNS 4 (Interrupts 109..138)
*/
#define NVIC_INIT_ITNS4 1
/*
// Interrupts 96..138
// <o.0> I2C5_EV_IRQn <0=> Secure state <1=> Non-Secure state
// <o.1> I2C6_ER_IRQn <0=> Secure state <1=> Non-Secure state
// <o.2> I2C6_EV_IRQn <0=> Secure state <1=> Non-Secure state
// <o.3> HSPI1_IRQn <0=> Secure state <1=> Non-Secure state
// <o.4> GPU2D_IRQn <0=> Secure state <1=> Non-Secure state
// <o.5> GPU2D_ER_IRQn <0=> Secure state <1=> Non-Secure state
// <o.6> GFXMMU_IRQn <0=> Secure state <1=> Non-Secure state
// <o.7> LTDC_IRQn <0=> Secure state <1=> Non-Secure state
// <o.8> LTDC_ER_IRQn <0=> Secure state <1=> Non-Secure state
// <o.9> DSI_IRQn <0=> Secure state <1=> Non-Secure state
// <o.10> DCACHE2_IRQn <0=> Secure state <1=> Non-Secure state
*/
#define NVIC_INIT_ITNS4_VAL 0x00000000
/*
// </e>
*/
/*
// </h>
*/
/*
max 8 SAU regions.
SAU regions are defined in partition.h
*/
#define SAU_INIT_REGION(n) \
SAU->RNR = (n & SAU_RNR_REGION_Msk); \
SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \
SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \
((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U
extern void trustzone_init(void);
extern void trustzone_run(void);
#endif
#endif

@ -1,4 +1,5 @@
#define SENSITIVE
#define FLASH_BYTE_ACCESS 1
void emulator_poll_events(void);

@ -39,6 +39,7 @@ def stm32f4_common_files(env, defines, sources, paths):
sources += [
"embed/trezorhal/stm32f4/board_capabilities.c",
"embed/trezorhal/stm32f4/common.c",
"embed/trezorhal/stm32f4/fault_handlers.c",
"embed/trezorhal/stm32f4/flash.c",
"embed/trezorhal/stm32f4/lowlevel.c",
"embed/trezorhal/stm32f4/mpu.c",
@ -47,6 +48,7 @@ def stm32f4_common_files(env, defines, sources, paths):
"embed/trezorhal/stm32f4/random_delays.c",
"embed/trezorhal/stm32f4/rng.c",
"embed/trezorhal/stm32f4/vectortable.s",
"vendor/trezor-storage/flash_common_f4.c",
]
# boardloader needs separate assembler for some function unencumbered by various FW+bootloader hacks
@ -67,4 +69,7 @@ def stm32f4_common_files(env, defines, sources, paths):
"-I../../vendor/micropython/lib/stm32lib/CMSIS/STM32F4xx/Include;"
"-I../../vendor/micropython/lib/cmsis/inc;"
"-DSTM32_HAL_H=<stm32f4xx.h>"
"-DSTM32F4"
)
env.get("ENV")["SUFFIX"] = "stm32f4"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save