1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-03-21 02:26:10 +00:00

feat(core): add basic support for STM32U5

This commit is contained in:
tychovrahe 2023-06-28 10:51:30 +02:00 committed by TychoVrahe
parent 937b7d34d0
commit 8150636a81
115 changed files with 6245 additions and 173 deletions

View File

@ -0,0 +1 @@
Added basic support for STM32U5

View File

@ -41,21 +41,29 @@ TEST_LANG ?= "en"
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/stm32f2x.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')\"'
@ -289,10 +297,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"
@ -367,7 +377,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

View File

@ -65,19 +65,21 @@ SOURCE_MOD += [
'embed/lib/image.c',
'embed/lib/mini_printf.c',
'embed/lib/terminal.c',
'vendor/trezor-storage/flash_common.c',
]
SOURCE_BOARDLOADER = [
'embed/boardloader/startup.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)
FILE_SUFFIX= env.get('ENV')['SUFFIX']
LINKER_SCRIPT_SUFFIX= env.get('ENV')['LINKER_SCRIPT']
SOURCE_BOARDLOADER = [
f"embed/boardloader/startup_{FILE_SUFFIX}.s",
'embed/boardloader/main.c',
]
env.Replace(
CP='cp',
AS='arm-none-eabi-as',
@ -104,7 +106,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_{LINKER_SCRIPT_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/boardloader/boardloader.map -Wl,--warn-common -Wl,--print-memory-usage",
CPPPATH=[
'embed/boardloader',
'embed/lib',
@ -161,7 +163,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,
],
)

View File

@ -93,7 +93,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 = [
@ -102,15 +101,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)
@ -122,6 +112,19 @@ 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']
LINKER_SCRIPT_SUFFIX= env.get('ENV')['LINKER_SCRIPT']
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',
@ -148,7 +151,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_{LINKER_SCRIPT_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/bootloader/bootloader.map -Wl,--warn-common -Wl,--print-memory-usage',
CPPPATH=[
'embed/rust',
'embed/bootloader',
@ -267,7 +270,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,
], )

View File

@ -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
@ -94,16 +93,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)
@ -115,6 +104,18 @@ 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']
LINKER_SCRIPT_SUFFIX= env.get('ENV')['LINKER_SCRIPT']
SOURCE_BOOTLOADER = [
f'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',
@ -141,7 +142,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=f'-T embed/bootloader_ci/memory_{LINKER_SCRIPT_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/bootloader_ci/bootloader.map -Wl,--warn-common',
CPPPATH=[
'embed/bootloader_ci',
'embed/bootloader_ci/nanopb',
@ -209,7 +210,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,
], )

View File

@ -91,9 +91,13 @@ 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', 'T', 'R', 'DISC1'):
SOURCE_MOD += [
'vendor/trezor-storage/flash_common_f4.c',
]
if TREZOR_MODEL in ('1', ):
SOURCE_MOD += [
'embed/models/model_T1B1_layout.c',
@ -142,6 +146,8 @@ SOURCE_UNIX = [
'embed/unix/profile.c',
]
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)

View File

@ -58,7 +58,6 @@ SOURCE_MOD += [
'vendor/trezor-storage/norcow.c',
'vendor/trezor-storage/storage.c',
'vendor/trezor-storage/storage_utils.c',
'vendor/trezor-storage/flash_common.c',
]
# modtrezorcrypto
@ -345,16 +344,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"]:
@ -389,6 +378,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'
@ -837,23 +838,31 @@ BINARY_NAME += "-dirty" if tools.get_git_modified() else ""
BINARY_NAME += ".bin"
if TREZOR_MODEL in ('T', 'R', 'DISC1'):
if TREZOR_MODEL in ('1',):
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',):
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',

View File

@ -91,21 +91,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)
@ -117,6 +104,22 @@ 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']
LINKER_SCRIPT_SUFFIX= env.get('ENV')['LINKER_SCRIPT']
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',
@ -143,7 +146,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_{LINKER_SCRIPT_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/prodtest/prodtest.map -Wl,--warn-common',
CPPPATH=[
'embed/prodtest',
'embed/lib',
@ -225,7 +228,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,
], )

View File

@ -65,13 +65,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
@ -85,6 +78,15 @@ 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']
LINKER_SCRIPT_SUFFIX= env.get('ENV')['LINKER_SCRIPT']
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',
@ -111,7 +113,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_{LINKER_SCRIPT_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/reflash/reflash.map -Wl,--warn-common',
CPPPATH=[
'embed/reflash',
'embed/lib',
@ -182,7 +184,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,
], )

View File

@ -59,9 +59,13 @@ SOURCE_MOD += [
'vendor/trezor-storage/norcow.c',
'vendor/trezor-storage/storage.c',
'vendor/trezor-storage/storage_utils.c',
'vendor/trezor-storage/flash_common.c',
]
if TREZOR_MODEL in ('1', 'T', 'R', 'DISC1'):
SOURCE_MOD += [
'vendor/trezor-storage/flash_common_f4.c',
]
# modtrezorcrypto
CCFLAGS_MOD += '-Wno-sequence-point '
CPPPATH_MOD += [

View File

@ -0,0 +1 @@
Added basic support for STM32U5

View File

@ -27,8 +27,10 @@
#include "flash.h"
#include "image.h"
#include "model.h"
#include "mpu.h"
#include "rng.h"
#include "terminal.h"
#ifdef USE_SD_CARD
#include "sdcard.h"
#endif
@ -42,6 +44,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[] = {
@ -54,6 +62,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,
@ -194,12 +240,30 @@ 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
display_init();
display_clear();
@ -225,8 +289,15 @@ 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();
// g_boot_flag is preserved on STM32U5
jump_to(BOOTLOADER_START + IMAGE_HEADER_SIZE);
return 0;

View File

@ -0,0 +1,109 @@
/* Trezor v2 boardloader linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C004000, LENGTH = 48K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 0K /* 512K on U5G */
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);
/* reserve 256 bytes for bootloader arguments */
boot_args_start = ORIGIN(BOOT_ARGS);
boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS);
g_boot_args = (boot_args_start + 4);
g_boot_flag = boot_args_start;
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(8);
} >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) {
__fb_start = .;
*(.fb1*);
*(.gfxmmu_table*);
*(.framebuffer_select*);
. = ALIGN(4);
} >SRAM3
.fb2 : ALIGN(4) {
*(.fb2*);
__fb_end = .;
. = ALIGN(4);
} >SRAM5
/* Hard-coded address for capabilities structure */
.capabilities 0x0C00FF00 : {KEEP(*(.capabilities_section))}
}

View File

@ -0,0 +1,102 @@
.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
fill_ram:
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_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, =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
ldr r0, =sram6_start // r0 - point to beginning of SRAM
ldr r1, =sram6_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
clear_ram:
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
ldr r0, =sram6_start // r0 - point to beginning of SRAM
ldr r1, =sram6_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

View File

@ -0,0 +1 @@
Added basic support for STM32U5

View File

@ -28,7 +28,8 @@ void set_core_clock(int) {}
int bootloader_main(void);
bool sector_is_empty(const flash_area_t *area) {
// assuming storage is single subarea
bool storage_empty(const flash_area_t *area) {
const uint8_t *storage = flash_area_get_address(area, 0, 0);
size_t storage_size = flash_area_get_size(area);
for (size_t i = 0; i < storage_size; i++) {
@ -117,7 +118,7 @@ __attribute__((noreturn)) int main(int argc, char **argv) {
FIRMWARE_START = (uint8_t *)flash_area_get_address(&FIRMWARE_AREA, 0, 0);
// simulate non-empty storage so that we know whether it was erased or not
if (sector_is_empty(&STORAGE_AREAS[0])) {
if (storage_empty(&STORAGE_AREAS[0])) {
secbool ret = flash_area_write_word(&STORAGE_AREAS[0], 16, 0x12345678);
(void)ret;
}
@ -197,7 +198,7 @@ void mpu_config_off(void) {}
__attribute__((noreturn)) void jump_to(void *addr) {
bool storage_is_erased =
sector_is_empty(&STORAGE_AREAS[0]) && sector_is_empty(&STORAGE_AREAS[1]);
storage_empty(&STORAGE_AREAS[0]) && storage_empty(&STORAGE_AREAS[1]);
if (storage_is_erased) {
printf("STORAGE WAS ERASED\n");

View File

@ -23,8 +23,10 @@
#include "boot_internal.h"
#include "common.h"
#include "display.h"
#include "display_utils.h"
#include "flash.h"
#include "image.h"
#include "lowlevel.h"
#include "messages.pb.h"
#include "random_delays.h"
#include "secbool.h"
@ -77,9 +79,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 = {
@ -214,7 +217,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) {
@ -258,7 +261,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];
@ -317,11 +320,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
@ -357,6 +379,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) {
#else
@ -365,7 +399,21 @@ int bootloader_main(void) {
secbool stay_in_bootloader = secfalse;
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
@ -460,7 +508,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
@ -529,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);
@ -583,7 +635,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;
}
@ -633,6 +687,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);
}
@ -640,7 +698,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;
}
}
@ -648,13 +710,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)"); }

View File

@ -10,6 +10,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);

View File

@ -0,0 +1,107 @@
/* Trezor v2 bootloader linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C010000, LENGTH = 128K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 0
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);
/* reserve 256 bytes for bootloader arguments */
boot_args_start = ORIGIN(BOOT_ARGS);
boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS);
g_boot_args = (boot_args_start + 4);
g_boot_flag = boot_args_start;
_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) {
__fb_start = .;
*(.fb1*);
*(.gfxmmu_table*);
*(.framebuffer_select*);
. = ALIGN(4);
} >SRAM3
.fb2 : ALIGN(4) {
*(.fb2*);
__fb_end = .;
. = ALIGN(4);
} >SRAM5
}

View File

@ -637,7 +637,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
is_ilu = sectrue;
}
#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);
@ -666,6 +666,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);
}
@ -834,7 +837,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();

View File

@ -0,0 +1,78 @@
.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
ldr r0, =sram6_start // r0 - point to beginning of SRAM
ldr r1, =sram6_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, =__fb_start // r1 - point to beginning of framebuffer
bl memset_reg
ldr r0, =__fb_end // r0 - point to end of framebuffer
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]
//
ldr r0, =g_boot_flag
ldr r1, [r0]
ldr r0, =g_boot_command
str r1, [r0]
ldr r0, =g_boot_flag
mov r1, #0
str r1, [r0]
// 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
.bss
.global g_boot_command
g_boot_command:
.word 0
.end

View File

@ -0,0 +1 @@
Added basic support for STM32U5

View File

@ -9,7 +9,9 @@ MEMORY {
SRAM (wal) : ORIGIN = 0x20000000, LENGTH = 192K
}
main_stack_base = ORIGIN(CCMRAM) + LENGTH(CCMRAM); /* 8-byte aligned full descending stack */
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);
@ -44,17 +46,27 @@ SECTIONS {
. = ALIGN(512);
} >FLASH AT>FLASH
.stack : ALIGN(8) {
. = 16K; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
} >CCMRAM
.data : ALIGN(4) {
*(.data*);
. = ALIGN(512);
} >CCMRAM AT>FLASH
/DISCARD/ : {
*(.ARM.exidx*);
}
.bss : ALIGN(4) {
*(.bss*);
. = ALIGN(4);
} >CCMRAM
.stack : ALIGN(8) {
. = 4K; /* this acts as a build time assertion that at least this much memory is available for stack use */
} >CCMRAM
.buf : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
} >SRAM
}

View File

@ -0,0 +1,107 @@
/* Trezor v2 bootloader linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C010000, LENGTH = 128K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 0
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);
/* reserve 256 bytes for bootloader arguments */
boot_args_start = ORIGIN(BOOT_ARGS);
boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS);
g_boot_args = (boot_args_start + 4);
g_boot_flag = boot_args_start;
_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) {
__fb_start = .;
*(.fb1*);
*(.gfxmmu_table*);
*(.framebuffer_select*);
. = ALIGN(4);
} >SRAM3
.fb2 : ALIGN(4) {
*(.fb2*);
__fb_end = .;
. = ALIGN(4);
} >SRAM5
}

View File

@ -0,0 +1,78 @@
.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
ldr r0, =sram6_start // r0 - point to beginning of SRAM
ldr r1, =sram6_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, =__fb_start // r1 - point to beginning of framebuffer
bl memset_reg
ldr r0, =__fb_end // r0 - point to end of framebuffer
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]
//
ldr r0, =g_boot_flag
ldr r1, [r0]
ldr r0, =g_boot_command
str r1, [r0]
ldr r0, =g_boot_flag
mov r1, #0
str r1, [r0]
// 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
.bss
.global g_boot_command
g_boot_command:
.word 0
.end

View File

@ -48,6 +48,7 @@
#include "mpu.h"
#include "random_delays.h"
#include "rust_ui.h"
#include "secure_aes.h"
#include TREZOR_BOARD
@ -75,8 +76,11 @@
#ifdef USE_OPTIGA
#include "optiga_commands.h"
#include "optiga_transport.h"
#endif
#if defined USE_OPTIGA | defined STM32U5
#include "secret.h"
#endif
#include "unit_variant.h"
#ifdef SYSTEM_VIEW
@ -99,6 +103,10 @@ int main(void) {
rdi_start();
#endif
#ifdef STM32U5
check_oem_keys();
#endif
// reinitialize HAL for Trezor One
#if defined TREZOR_MODEL_1
HAL_Init();
@ -125,8 +133,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
@ -148,6 +155,10 @@ int main(void) {
set_core_clock(CLOCK_180_MHZ);
#endif
#ifdef STM32U5
secure_aes_init();
#endif
#ifdef USE_BUTTON
button_init();
#endif
@ -231,25 +242,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)"); }
// MicroPython builtin stubs
mp_import_stat_t mp_import_stat(const char *path) {

View File

@ -26,6 +26,7 @@ ccmram_end = ORIGIN(CCMRAM) + LENGTH(CCMRAM);
/* reserve 256 bytes for bootloader arguments */
boot_args_start = ORIGIN(BOOT_ARGS);
boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS);
g_boot_args = boot_args_start;
/* used by the startup code to wipe memory */
sram_start = ORIGIN(SRAM);

View File

@ -66,16 +66,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

View File

@ -0,0 +1,67 @@
.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
ldr r0, =sram6_start // r0 - point to beginning of SRAM
ldr r1, =sram6_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =boot_args_start // r0 - point to beginning of boot args
ldr r1, =boot_args_end // r1 - point to byte after the end of boot args
bl memset_reg
ldr r0, =sram3_start // r0 - point to beginning of SRAM
ldr r1, =__fb_start // r1 - point to beginning of framebuffer
bl memset_reg
ldr r0, =__fb_end // r0 - point to end of framebuffer
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

View File

@ -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 TRANSLATIONS_AREA;
extern const flash_area_t BOOTLOADER_AREA;
extern const flash_area_t FIRMWARE_AREA;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
Added basic support for STM32U5

View File

@ -669,5 +669,3 @@ int main(void) {
return 0;
}
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR!", "(HF)"); }

View File

@ -10,6 +10,7 @@ MEMORY {
}
main_stack_base = ORIGIN(SRAM) + LENGTH(SRAM); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM);
_estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */

View File

@ -0,0 +1,123 @@
/* TREZORv2 firmware linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 3648K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 0
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);
/* reserve 256 bytes for bootloader arguments */
boot_args_start = ORIGIN(BOOT_ARGS);
boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS);
g_boot_args = (boot_args_start + 4);
g_boot_flag= boot_args_start;
_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) {
__fb_start = .;
*(.fb1*);
*(.gfxmmu_table*);
*(.framebuffer_select*);
. = ALIGN(4);
} >SRAM3
.fb2 : ALIGN(4) {
*(.fb2*);
__fb_end = .;
. = ALIGN(4);
} >SRAM5
}

View File

@ -0,0 +1,67 @@
.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
ldr r0, =sram6_start // r0 - point to beginning of SRAM
ldr r1, =sram6_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =boot_args_start // r0 - point to beginning of boot args
ldr r1, =boot_args_end // r1 - point to byte after the end of boot args
bl memset_reg
ldr r0, =sram3_start // r0 - point to beginning of SRAM
ldr r1, =__fb_start // r1 - point to beginning of framebuffer
bl memset_reg
ldr r0, =__fb_end // r0 - point to end of framebuffer
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

View File

@ -0,0 +1,123 @@
/* TREZORv2 firmware linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 3648K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
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);
/* reserve 256 bytes for bootloader arguments */
boot_args_start = ORIGIN(BOOT_ARGS);
boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS);
g_boot_args = (boot_args_start + 4);
g_boot_flag = boot_args_start;
_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) {
__fb_start = .;
*(.fb1*);
*(.gfxmmu_table*);
*(.framebuffer_select*);
. = ALIGN(4);
} >SRAM3
.fb2 : ALIGN(4) {
*(.fb2*);
__fb_end = .;
. = ALIGN(4);
} >SRAM5
}

View File

@ -0,0 +1,67 @@
.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
ldr r0, =sram6_start // r0 - point to beginning of SRAM
ldr r1, =sram6_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =boot_args_start // r0 - point to beginning of boot args
ldr r1, =boot_args_end // r1 - point to byte after the end of boot args
bl memset_reg
ldr r0, =sram3_start // r0 - point to beginning of SRAM
ldr r1, =__fb_start // r1 - point to beginning of framebuffer
bl memset_reg
ldr r0, =__fb_end // r0 - point to end of framebuffer
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

View File

@ -447,7 +447,7 @@ fn generate_crypto_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")]

View File

@ -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"

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 EBB and (DHUK xor BHK) 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 ECB and (DHUK xor BHK) 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

View File

@ -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__))

View File

@ -0,0 +1,18 @@
#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 NMI_Handler(void) {
// Clock Security System triggered NMI
if ((RCC->CIR & RCC_CIR_CSSF) != 0) {
error_shutdown("INTERNAL ERROR", "(CS)");
}
}

View File

@ -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

View File

@ -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();

View File

@ -23,6 +23,8 @@
#include STM32_HAL_H
#include <stdint.h>
#define SENSITIVE
typedef enum {
CLOCK_180_MHZ = 0,
CLOCK_168_MHZ = 1,

View File

@ -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);
}

View File

@ -11,13 +11,13 @@
// Saves extra parameters for the bootloader
static void _copy_boot_args(const void *args, size_t args_size) {
// symbols imported from the linker script
extern uint8_t boot_args_start;
extern uint8_t g_boot_args;
extern uint8_t boot_args_end;
uint8_t *p = &boot_args_start;
uint8_t *p = &g_boot_args;
if (args != NULL && args_size > 0) {
size_t max_size = &boot_args_end - &boot_args_start;
size_t max_size = &boot_args_end - &g_boot_args;
size_t copy_size = MIN(args_size, max_size);
memcpy(p, args, copy_size);
p += args_size;
@ -28,6 +28,16 @@ static void _copy_boot_args(const void *args, size_t args_size) {
}
}
#ifdef STM32U5
extern uint32_t g_boot_flag;
__attribute__((noreturn)) static void _reboot_to_bootloader(
boot_command_t boot_command) {
g_boot_flag = boot_command;
__disable_irq();
delete_secrets();
NVIC_SystemReset();
}
#else
__attribute__((noreturn)) static void _reboot_to_bootloader(
boot_command_t boot_command) {
mpu_config_bootloader();
@ -35,6 +45,7 @@ __attribute__((noreturn)) static void _reboot_to_bootloader(
for (;;)
;
}
#endif
void svc_reboot_to_bootloader(boot_command_t boot_command, const void *args,
size_t args_size) {

View File

@ -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

View File

@ -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****/

View 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

View File

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

View File

@ -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 <string.h>
#include "common.h"
#include "display.h"
#include "secret.h"
#include "terminal.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
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
if (label) {
term_printf("%s\n", label);
}
if (msg) {
term_printf("%s\n", msg);
}
if (footer) {
term_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
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
term_printf("\nINTERNAL ERROR:\n");
if (expr) {
term_printf("expr: %s\n", expr);
}
if (msg) {
term_printf("msg : %s\n", msg);
}
if (file) {
term_printf("file: %s:%d\n", file, line);
}
if (func) {
term_printf("func: %s\n", func);
}
#ifdef SCM_REVISION
const uint8_t *rev = (const uint8_t *)SCM_REVISION;
term_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
rev[4]);
#endif
term_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
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
if (label) {
term_printf("%s\n", label);
}
if (msg) {
term_printf("%s\n", msg);
}
term_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");
}

View File

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

View File

@ -0,0 +1,22 @@
#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 GTZC_IRQHandler(void) { error_shutdown("INTERNAL ERROR", "(IA)"); }
void NMI_Handler(void) {
// Clock Security System triggered NMI
if ((RCC->CIFR & RCC_CIFR_CSSF) != 0) {
error_shutdown("INTERNAL ERROR", "(CS)");
}
}

View File

@ -0,0 +1,567 @@
/*
* 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;
uint32_t sec_start = 0;
uint32_t sec_end = 0;
uint32_t page_idx = 0;
bool secure = area->secure_area;
if (page >= 256) {
EraseInitStruct.Banks = FLASH_BANK_2;
page_idx = page - 256;
sec_start = (FLASH->SECWM2R1 & FLASH_SECWM1R1_SECWM1_PSTRT) >>
FLASH_SECWM1R1_SECWM1_PSTRT_Pos;
sec_end = (FLASH->SECWM2R1 & FLASH_SECWM1R1_SECWM1_PEND) >>
FLASH_SECWM1R1_SECWM1_PEND_Pos;
} else {
EraseInitStruct.Banks = FLASH_BANK_1;
page_idx = page;
sec_start = (FLASH->SECWM1R1 & FLASH_SECWM1R1_SECWM1_PSTRT) >>
FLASH_SECWM1R1_SECWM1_PSTRT_Pos;
sec_end = (FLASH->SECWM1R1 & FLASH_SECWM1R1_SECWM1_PEND) >>
FLASH_SECWM1R1_SECWM1_PEND_Pos;
}
if (page_idx < sec_start || page_idx > sec_end) {
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES_NS;
secure = false;
} else {
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
}
EraseInitStruct.Page = page_idx;
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, secure);
const uint32_t addr_end =
(uint32_t)flash_get_address(page + 1, 0, 0, secure);
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_area_erase_partial(const flash_area_t *area, uint32_t offset,
uint32_t *bytes_erased) {
ensure(flash_unlock_write(), NULL);
FLASH_EraseInitTypeDef EraseInitStruct;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.NbPages = 1;
*bytes_erased = 0;
int32_t page = flash_get_sector_num(area, offset / FLASH_PAGE_SIZE);
if (page >= 0 && page < FLASH_SECTOR_COUNT) {
uint32_t sec_start = 0;
uint32_t sec_end = 0;
uint32_t page_idx = 0;
bool secure = area->secure_area;
if (page >= 256) {
EraseInitStruct.Banks = FLASH_BANK_2;
page_idx = page - 256;
sec_start = (FLASH->SECWM2R1 & FLASH_SECWM1R1_SECWM1_PSTRT) >>
FLASH_SECWM1R1_SECWM1_PSTRT_Pos;
sec_end = (FLASH->SECWM2R1 & FLASH_SECWM1R1_SECWM1_PEND) >>
FLASH_SECWM1R1_SECWM1_PEND_Pos;
} else {
EraseInitStruct.Banks = FLASH_BANK_1;
page_idx = page;
sec_start = (FLASH->SECWM1R1 & FLASH_SECWM1R1_SECWM1_PSTRT) >>
FLASH_SECWM1R1_SECWM1_PSTRT_Pos;
sec_end = (FLASH->SECWM1R1 & FLASH_SECWM1R1_SECWM1_PEND) >>
FLASH_SECWM1R1_SECWM1_PEND_Pos;
}
if (page_idx < sec_start || page_idx > sec_end) {
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES_NS;
secure = false;
} else {
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
}
EraseInitStruct.Page = page_idx;
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, secure);
const uint32_t addr_end =
(uint32_t)flash_get_address(page + 1, 0, 0, secure);
for (uint32_t addr = addr_start; addr < addr_end; addr += 4) {
if (*((const uint32_t *)addr) != 0xFFFFFFFF) {
ensure(flash_lock_write(), NULL);
return secfalse;
}
}
ensure(flash_lock_write(), NULL);
*bytes_erased = FLASH_PAGE_SIZE;
return sectrue;
}
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;
}
secbool flash_write_block(uint16_t sector, uint32_t offset,
const flash_block_t block) {
return flash_write_quadword(sector, offset, block);
}

View File

@ -0,0 +1,441 @@
#include STM32_HAL_H
#include TREZOR_BOARD
#include "i2c.h"
#include "common.h"
static I2C_HandleTypeDef i2c_handle[I2C_COUNT];
typedef struct {
I2C_TypeDef *Instance;
GPIO_TypeDef *SclPort;
GPIO_TypeDef *SdaPort;
uint16_t SclPin;
uint16_t SdaPin;
uint8_t PinAF;
volatile uint32_t *ResetReg;
uint32_t ResetBit;
} i2c_instance_t;
i2c_instance_t i2c_defs[I2C_COUNT] = {
{
.Instance = I2C_INSTANCE_1,
.SclPort = I2C_INSTANCE_1_SCL_PORT,
.SdaPort = I2C_INSTANCE_1_SDA_PORT,
.SclPin = I2C_INSTANCE_1_SCL_PIN,
.SdaPin = I2C_INSTANCE_1_SDA_PIN,
.PinAF = I2C_INSTANCE_1_PIN_AF,
.ResetReg = I2C_INSTANCE_1_RESET_REG,
.ResetBit = I2C_INSTANCE_1_RESET_BIT,
},
#ifdef I2C_INSTANCE_2
{
.Instance = I2C_INSTANCE_2,
.SclPort = I2C_INSTANCE_2_SCL_PORT,
.SdaPort = I2C_INSTANCE_2_SDA_PORT,
.SclPin = I2C_INSTANCE_2_SCL_PIN,
.SdaPin = I2C_INSTANCE_2_SDA_PIN,
.PinAF = I2C_INSTANCE_2_PIN_AF,
.ResetReg = I2C_INSTANCE_2_RESET_REG,
.ResetBit = I2C_INSTANCE_2_RESET_BIT,
},
#endif
};
#ifndef I2C_VALID_TIMING_NBR
#define I2C_VALID_TIMING_NBR 128U
#endif /* I2C_VALID_TIMING_NBR */
#define I2C_SPEED_FREQ_STANDARD 0U /* 100 kHz */
#define I2C_SPEED_FREQ_FAST 1U /* 400 kHz */
#define I2C_SPEED_FREQ_FAST_PLUS 2U /* 1 MHz */
#define I2C_ANALOG_FILTER_DELAY_MIN 50U /* ns */
#define I2C_ANALOG_FILTER_DELAY_MAX 260U /* ns */
#define I2C_USE_ANALOG_FILTER 1U
#define I2C_DIGITAL_FILTER_COEF 0U
#define I2C_PRESC_MAX 16U
#define I2C_SCLDEL_MAX 16U
#define I2C_SDADEL_MAX 16U
#define I2C_SCLH_MAX 256U
#define I2C_SCLL_MAX 256U
#define SEC2NSEC 1000000000UL
/**
* @}
*/
/** @defgroup STM32U5x9J_DISCOVERY_BUS_Private_Types BUS Private Types
* @{
*/
typedef struct {
uint32_t freq; /* Frequency in Hz */
uint32_t freq_min; /* Minimum frequency in Hz */
uint32_t freq_max; /* Maximum frequency in Hz */
uint32_t hddat_min; /* Minimum data hold time in ns */
uint32_t vddat_max; /* Maximum data valid time in ns */
uint32_t sudat_min; /* Minimum data setup time in ns */
uint32_t lscl_min; /* Minimum low period of the SCL clock in ns */
uint32_t hscl_min; /* Minimum high period of SCL clock in ns */
uint32_t trise; /* Rise time in ns */
uint32_t tfall; /* Fall time in ns */
uint32_t dnf; /* Digital noise filter coefficient */
} I2C_Charac_t;
typedef struct {
uint32_t presc; /* Timing prescaler */
uint32_t tscldel; /* SCL delay */
uint32_t tsdadel; /* SDA delay */
uint32_t sclh; /* SCL high period */
uint32_t scll; /* SCL low period */
} I2C_Timings_t;
static I2C_Timings_t I2c_valid_timing[I2C_VALID_TIMING_NBR];
static uint32_t I2c_valid_timing_nbr = 0;
static const I2C_Charac_t I2C_Charac[] = {
[I2C_SPEED_FREQ_STANDARD] =
{
.freq = 100000,
.freq_min = 80000,
.freq_max = 120000,
.hddat_min = 0,
.vddat_max = 3450,
.sudat_min = 250,
.lscl_min = 4700,
.hscl_min = 4000,
.trise = 640,
.tfall = 20,
.dnf = I2C_DIGITAL_FILTER_COEF,
},
[I2C_SPEED_FREQ_FAST] =
{
.freq = 400000,
.freq_min = 320000,
.freq_max = 480000,
.hddat_min = 0,
.vddat_max = 900,
.sudat_min = 100,
.lscl_min = 1300,
.hscl_min = 600,
.trise = 250,
.tfall = 100,
.dnf = I2C_DIGITAL_FILTER_COEF,
},
[I2C_SPEED_FREQ_FAST_PLUS] =
{
.freq = 1000000,
.freq_min = 800000,
.freq_max = 1200000,
.hddat_min = 0,
.vddat_max = 450,
.sudat_min = 50,
.lscl_min = 500,
.hscl_min = 260,
.trise = 60,
.tfall = 100,
.dnf = I2C_DIGITAL_FILTER_COEF,
},
};
/**
* @brief Compute PRESC, SCLDEL and SDADEL.
* @param clock_src_freq I2C source clock in HZ.
* @param I2C_speed I2C frequency (index).
* @retval None.
*/
static void I2C_Compute_PRESC_SCLDEL_SDADEL(uint32_t clock_src_freq,
uint32_t I2C_speed) {
uint32_t prev_presc = I2C_PRESC_MAX;
uint32_t ti2cclk;
int32_t tsdadel_min;
int32_t tsdadel_max;
int32_t tscldel_min;
uint32_t presc;
uint32_t scldel;
uint32_t sdadel;
uint32_t tafdel_min;
uint32_t tafdel_max;
ti2cclk = (SEC2NSEC + (clock_src_freq / 2U)) / clock_src_freq;
tafdel_min = I2C_ANALOG_FILTER_DELAY_MIN;
tafdel_max = I2C_ANALOG_FILTER_DELAY_MAX;
/* tDNF = DNF x tI2CCLK
tPRESC = (PRESC+1) x tI2CCLK
SDADEL >= {tf +tHD;DAT(min) - tAF(min) - tDNF - [3 x tI2CCLK]} / {tPRESC}
SDADEL <= {tVD;DAT(max) - tr - tAF(max) - tDNF- [4 x tI2CCLK]} / {tPRESC}
*/
tsdadel_min =
(int32_t)I2C_Charac[I2C_speed].tfall +
(int32_t)I2C_Charac[I2C_speed].hddat_min - (int32_t)tafdel_min -
(int32_t)(((int32_t)I2C_Charac[I2C_speed].dnf + 3) * (int32_t)ti2cclk);
tsdadel_max =
(int32_t)I2C_Charac[I2C_speed].vddat_max -
(int32_t)I2C_Charac[I2C_speed].trise - (int32_t)tafdel_max -
(int32_t)(((int32_t)I2C_Charac[I2C_speed].dnf + 4) * (int32_t)ti2cclk);
/* {[tr+ tSU;DAT(min)] / [tPRESC]} - 1 <= SCLDEL */
tscldel_min = (int32_t)I2C_Charac[I2C_speed].trise +
(int32_t)I2C_Charac[I2C_speed].sudat_min;
if (tsdadel_min <= 0) {
tsdadel_min = 0;
}
if (tsdadel_max <= 0) {
tsdadel_max = 0;
}
for (presc = 0; presc < I2C_PRESC_MAX; presc++) {
for (scldel = 0; scldel < I2C_SCLDEL_MAX; scldel++) {
/* TSCLDEL = (SCLDEL+1) * (PRESC+1) * TI2CCLK */
uint32_t tscldel = (scldel + 1U) * (presc + 1U) * ti2cclk;
if (tscldel >= (uint32_t)tscldel_min) {
for (sdadel = 0; sdadel < I2C_SDADEL_MAX; sdadel++) {
/* TSDADEL = SDADEL * (PRESC+1) * TI2CCLK */
uint32_t tsdadel = (sdadel * (presc + 1U)) * ti2cclk;
if ((tsdadel >= (uint32_t)tsdadel_min) &&
(tsdadel <= (uint32_t)tsdadel_max)) {
if (presc != prev_presc) {
I2c_valid_timing[I2c_valid_timing_nbr].presc = presc;
I2c_valid_timing[I2c_valid_timing_nbr].tscldel = scldel;
I2c_valid_timing[I2c_valid_timing_nbr].tsdadel = sdadel;
prev_presc = presc;
I2c_valid_timing_nbr++;
if (I2c_valid_timing_nbr >= I2C_VALID_TIMING_NBR) {
return;
}
}
}
}
}
}
}
}
/**
* @brief Calculate SCLL and SCLH and find best configuration.
* @param clock_src_freq I2C source clock in HZ.
* @param I2C_speed I2C frequency (index).
* @retval config index (0 to I2C_VALID_TIMING_NBR], 0xFFFFFFFF for no valid
* config.
*/
static uint32_t I2C_Compute_SCLL_SCLH(uint32_t clock_src_freq,
uint32_t I2C_speed) {
uint32_t ret = 0xFFFFFFFFU;
uint32_t ti2cclk;
uint32_t ti2cspeed;
uint32_t prev_error;
uint32_t dnf_delay;
uint32_t clk_min;
uint32_t clk_max;
uint32_t scll;
uint32_t sclh;
uint32_t tafdel_min;
ti2cclk = (SEC2NSEC + (clock_src_freq / 2U)) / clock_src_freq;
ti2cspeed = (SEC2NSEC + (I2C_Charac[I2C_speed].freq / 2U)) /
I2C_Charac[I2C_speed].freq;
tafdel_min = I2C_ANALOG_FILTER_DELAY_MIN;
/* tDNF = DNF x tI2CCLK */
dnf_delay = I2C_Charac[I2C_speed].dnf * ti2cclk;
clk_max = SEC2NSEC / I2C_Charac[I2C_speed].freq_min;
clk_min = SEC2NSEC / I2C_Charac[I2C_speed].freq_max;
prev_error = ti2cspeed;
for (uint32_t count = 0; count < I2c_valid_timing_nbr; count++) {
/* tPRESC = (PRESC+1) x tI2CCLK*/
uint32_t tpresc = (I2c_valid_timing[count].presc + 1U) * ti2cclk;
for (scll = 0; scll < I2C_SCLL_MAX; scll++) {
/* tLOW(min) <= tAF(min) + tDNF + 2 x tI2CCLK + [(SCLL+1) x tPRESC ] */
uint32_t tscl_l =
tafdel_min + dnf_delay + (2U * ti2cclk) + ((scll + 1U) * tpresc);
/* The I2CCLK period tI2CCLK must respect the following conditions:
tI2CCLK < (tLOW - tfilters) / 4 and tI2CCLK < tHIGH */
if ((tscl_l > I2C_Charac[I2C_speed].lscl_min) &&
(ti2cclk < ((tscl_l - tafdel_min - dnf_delay) / 4U))) {
for (sclh = 0; sclh < I2C_SCLH_MAX; sclh++) {
/* tHIGH(min) <= tAF(min) + tDNF + 2 x tI2CCLK + [(SCLH+1) x tPRESC]
*/
uint32_t tscl_h =
tafdel_min + dnf_delay + (2U * ti2cclk) + ((sclh + 1U) * tpresc);
/* tSCL = tf + tLOW + tr + tHIGH */
uint32_t tscl = tscl_l + tscl_h + I2C_Charac[I2C_speed].trise +
I2C_Charac[I2C_speed].tfall;
if ((tscl >= clk_min) && (tscl <= clk_max) &&
(tscl_h >= I2C_Charac[I2C_speed].hscl_min) &&
(ti2cclk < tscl_h)) {
int32_t error = (int32_t)tscl - (int32_t)ti2cspeed;
if (error < 0) {
error = -error;
}
/* look for the timings with the lowest clock error */
if ((uint32_t)error < prev_error) {
prev_error = (uint32_t)error;
I2c_valid_timing[count].scll = scll;
I2c_valid_timing[count].sclh = sclh;
ret = count;
}
}
}
}
}
}
return ret;
}
/*
* @brief Compute I2C timing according current I2C clock source and required
* I2C clock.
* @param clock_src_freq I2C clock source in Hz.
* @param i2c_freq Required I2C clock in Hz.
* @retval I2C timing or 0 in case of error.
*/
static uint32_t I2C_GetTiming(uint32_t clock_src_freq, uint32_t i2c_freq) {
uint32_t ret = 0;
uint32_t speed;
uint32_t idx;
if ((clock_src_freq != 0U) && (i2c_freq != 0U)) {
for (speed = 0; speed <= (uint32_t)I2C_SPEED_FREQ_FAST_PLUS; speed++) {
if ((i2c_freq >= I2C_Charac[speed].freq_min) &&
(i2c_freq <= I2C_Charac[speed].freq_max)) {
I2C_Compute_PRESC_SCLDEL_SDADEL(clock_src_freq, speed);
idx = I2C_Compute_SCLL_SCLH(clock_src_freq, speed);
if (idx < I2C_VALID_TIMING_NBR) {
ret = ((I2c_valid_timing[idx].presc & 0x0FU) << 28) |
((I2c_valid_timing[idx].tscldel & 0x0FU) << 20) |
((I2c_valid_timing[idx].tsdadel & 0x0FU) << 16) |
((I2c_valid_timing[idx].sclh & 0xFFU) << 8) |
((I2c_valid_timing[idx].scll & 0xFFU) << 0);
}
break;
}
}
}
return ret;
}
void i2c_init_instance(uint16_t idx, i2c_instance_t *instance) {
if (i2c_handle[idx].Instance) {
return;
}
GPIO_InitTypeDef GPIO_InitStructure;
// configure CTP I2C SCL and SDA GPIO lines
GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed =
GPIO_SPEED_FREQ_LOW; // I2C is a KHz bus and low speed is still good into
// the low MHz
GPIO_InitStructure.Alternate = instance->PinAF;
GPIO_InitStructure.Pin = instance->SclPin;
HAL_GPIO_Init(instance->SclPort, &GPIO_InitStructure);
GPIO_InitStructure.Alternate = instance->PinAF;
GPIO_InitStructure.Pin = instance->SdaPin;
HAL_GPIO_Init(instance->SdaPort, &GPIO_InitStructure);
i2c_handle[idx].Instance = instance->Instance;
i2c_handle[idx].Init.Timing = I2C_GetTiming(HAL_RCC_GetPCLK1Freq(), 400000);
i2c_handle[idx].Init.OwnAddress1 = 0xFE; // master
i2c_handle[idx].Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
i2c_handle[idx].Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
i2c_handle[idx].Init.OwnAddress2 = 0;
i2c_handle[idx].Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
i2c_handle[idx].Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_OK != HAL_I2C_Init(&i2c_handle[idx])) {
ensure(secfalse, "I2C was not loaded properly.");
return;
}
}
void i2c_init(void) {
// enable I2C clock
I2C_INSTANCE_1_CLK_EN();
I2C_INSTANCE_1_SCL_CLK_EN();
I2C_INSTANCE_1_SDA_CLK_EN();
i2c_init_instance(0, &i2c_defs[0]);
#ifdef I2C_INSTANCE_2
I2C_INSTANCE_2_CLK_EN();
I2C_INSTANCE_2_SCL_CLK_EN();
I2C_INSTANCE_2_SDA_CLK_EN();
i2c_init_instance(1, &i2c_defs[1]);
#endif
}
void i2c_deinit(uint16_t idx) {
__HAL_RCC_I2C5_FORCE_RESET();
if (i2c_handle[idx].Instance) {
HAL_I2C_DeInit(&i2c_handle[idx]);
i2c_handle[idx].Instance = NULL;
}
}
void i2c_ensure_pin(GPIO_TypeDef *port, uint16_t GPIO_Pin,
GPIO_PinState PinState) {
HAL_GPIO_WritePin(port, GPIO_Pin, PinState);
while (HAL_GPIO_ReadPin(port, GPIO_Pin) != PinState)
;
}
void i2c_cycle(uint16_t idx) {
SET_BIT(*i2c_defs[idx].ResetReg, i2c_defs[idx].ResetBit);
CLEAR_BIT(*i2c_defs[idx].ResetReg, i2c_defs[idx].ResetBit);
}
HAL_StatusTypeDef i2c_transmit(uint16_t idx, uint8_t addr, uint8_t *data,
uint16_t len, uint32_t timeout) {
return HAL_I2C_Master_Transmit(&i2c_handle[idx], addr, data, len, timeout);
}
HAL_StatusTypeDef i2c_receive(uint16_t idx, uint8_t addr, uint8_t *data,
uint16_t len, uint32_t timeout) {
HAL_StatusTypeDef ret =
HAL_I2C_Master_Receive(&i2c_handle[idx], addr, data, len, timeout);
#ifdef USE_OPTIGA
if (idx == OPTIGA_I2C_INSTANCE) {
// apply GUARD_TIME as specified by the OPTIGA datasheet
// (only applies to the I2C bus to which the OPTIGA is connected)
hal_delay_us(50);
}
#endif
return ret;
}
HAL_StatusTypeDef i2c_mem_write(uint16_t idx, uint8_t addr, uint16_t mem_addr,
uint16_t mem_addr_size, uint8_t *data,
uint16_t len, uint32_t timeout) {
return HAL_I2C_Mem_Write(&i2c_handle[idx], addr, mem_addr, mem_addr_size,
data, len, timeout);
}
HAL_StatusTypeDef i2c_mem_read(uint16_t idx, uint8_t addr, uint16_t mem_addr,
uint16_t mem_addr_size, uint8_t *data,
uint16_t len, uint32_t timeout) {
return HAL_I2C_Mem_Read(&i2c_handle[idx], addr, mem_addr, mem_addr_size, data,
len, timeout);
}

View File

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

View File

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

View File

@ -0,0 +1,145 @@
.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!
cmp r0, r1
beq .L_loop_end
.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
.L_loop_end:
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
ldr r0, =sram6_start // r0 - point to beginning of SRAM
ldr r1, =sram6_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, =__fb_start // r1 - point to beginning of framebuffer
bl memset_reg
ldr r0, =__fb_end // r0 - point to end of framebuffer
ldr r1, =sram5_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 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, =sram6_start // r0 - point to beginning of SRAM
ldr r1, =sram6_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =boot_args_start // r0 - point to beginning of boot args
ldr r1, =boot_args_end // r1 - point to byte after the end of boot args
bl memset_reg
ldr r0, =sram3_start // r0 - point to beginning of SRAM
ldr r1, =__fb_start // r1 - point to beginning of framebuffer
bl memset_reg
ldr r0, =__fb_end // r0 - point to end of framebuffer
ldr r1, =sram5_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

View File

@ -0,0 +1,311 @@
/*
* 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 "common.h"
#include "flash.h"
#include "model.h"
#include TREZOR_BOARD
#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 2
#define WANT_WRP_PAGE_END 7
#else
#define WANT_RDP_LEVEL (OB_RDP_LEVEL_0)
#endif
#ifdef VDD_3V3
// BOR LEVEL 0: Reset level threshold is around 2.8 V
#define WANT_BOR_LEVEL (OB_BOR_LEVEL_4)
#define USE_PVD 1
#elif VDD_1V8
// BOR LEVEL 0: Reset level threshold is around 1.7 V
#define WANT_BOR_LEVEL (OB_BOR_LEVEL_0)
#else
#error "VDD_3V3 or VDD_1V8 must be defined"
#endif
#if defined STM32U5A9xx | defined STM32U5G9xx
#define SEC_AREA_1_PAGE_START 0
#define HDP_AREA_1_PAGE_END 1
#define SEC_AREA_1_PAGE_END 0xFF
#define SEC_AREA_2_PAGE_START 0
#define SEC_AREA_2_PAGE_END 0xFF
#elif define STM32U585xx
#define SEC_AREA_1_PAGE_START 0
#define HDP_AREA_1_PAGE_END 1
#define SEC_AREA_1_PAGE_END 0x7F
#define SEC_AREA_2_PAGE_START 0
#define SEC_AREA_2_PAGE_END 0x7F
#else
#error Unknown MCU
#endif
#define FLASH_OPTR_VALUE \
(FLASH_OPTR_TZEN | FLASH_OPTR_PA15_PUPEN | FLASH_OPTR_nBOOT0 | \
FLASH_OPTR_SRAM3_ECC | FLASH_OPTR_BKPRAM_ECC | FLASH_OPTR_DUALBANK | \
FLASH_OPTR_WWDG_SW | FLASH_OPTR_IWDG_STOP | FLASH_OPTR_IWDG_STDBY | \
FLASH_OPTR_IWDG_SW | FLASH_OPTR_SRAM_RST | FLASH_OPTR_nRST_SHDW | \
FLASH_OPTR_nRST_STDBY | FLASH_OPTR_nRST_STOP | WANT_BOR_LEVEL | \
(WANT_RDP_LEVEL << FLASH_OPTR_RDP_Pos))
#define FALSH_SECBOOTADD0R_VALUE \
((BOARDLOADER_START & 0xFFFFFF80) | FLASH_SECBOOTADD0R_BOOT_LOCK | 0x7C)
#define FLASH_SECWM1R1_VALUE \
(SEC_AREA_1_PAGE_START << FLASH_SECWM1R1_SECWM1_PSTRT_Pos | \
SEC_AREA_1_PAGE_END << FLASH_SECWM1R1_SECWM1_PEND_Pos | 0xFF00FF00)
#define FLASH_SECWM1R2_VALUE \
(HDP_AREA_1_PAGE_END << FLASH_SECWM1R2_HDP1_PEND_Pos | \
FLASH_SECWM1R2_HDP1EN | 0x7F007F00)
#define FLASH_SECWM2R1_VALUE \
(SEC_AREA_2_PAGE_START << FLASH_SECWM1R1_SECWM1_PSTRT_Pos | \
SEC_AREA_2_PAGE_END << 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
if (FLASH->WRP1AR != 0xFF00FFFF) {
return secfalse;
}
#endif
if (FLASH->WRP1BR != 0xFF00FFFF) {
return secfalse;
}
if (FLASH->WRP2AR != 0xFF00FFFF) {
return secfalse;
}
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);
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;
}
void check_oem_keys(void) {
ensure(((FLASH_S->NSSR & FLASH_NSSR_OEM1LOCK) == 0) * sectrue,
"OEM1 KEY SET");
ensure(((FLASH_S->NSSR & FLASH_NSSR_OEM2LOCK) == 0) * sectrue,
"OEM2 KEY SET");
}
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());
check_oem_keys();
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());
check_oem_keys();
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();
// Enable GPIO clocks
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
#ifdef USE_PVD
// 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);
#endif
}
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
}

View File

@ -0,0 +1,258 @@
/*
* 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_NS | LL_MPU_REGION_ALL_RW | LL_MPU_INSTRUCTION_ACCESS_DISABLE;
MPU->RLAR = REGION_END(PERIPH_BASE_NS + 0x20000000 - 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;
// Non-secure Flash
MPU->RNR = MPU_REGION_NUMBER7;
MPU->RBAR = FLASH_BASE_NS | LL_MPU_REGION_ALL_RW |
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
MPU->RLAR =
REGION_END(FLASH_BASE_NS + 0x400000 - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
// 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");
}

View File

@ -0,0 +1,212 @@
/*
* 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"
#include TREZOR_BOARD
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
#define DEFAULT_FREQ 160U
#define DEFAULT_PLLM 1
#define DEFAULT_PLLN (10 * PLLN_COEF) // 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
#ifdef HSE_16MHZ
#define PLLN_COEF 1U
#elif defined HSE_8MHZ
#define PLLN_COEF 2U
#else
#error Unsupported HSE frequency
#endif
// 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 * PLLN_COEF,
},
};
#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 in default 2-way mode
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();
}

View File

@ -0,0 +1,56 @@
/*
* 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;
}
void check_oem_keys(void);
#endif // TREZORHAL_STM32_H

View File

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

View File

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

View File

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

View File

@ -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++;
}
}

View File

@ -0,0 +1,117 @@
/*
* 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;
}

View File

@ -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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,217 @@
/*
* 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
// more flash efficient function than standard HAL
HAL_StatusTypeDef lsi_init(void) {
uint32_t tickstart = 0U;
FlagStatus pwrclkchanged = RESET;
/* Update LSI configuration in Backup Domain control register */
/* Requires to enable write access to Backup Domain of necessary */
if (__HAL_RCC_PWR_IS_CLK_DISABLED()) {
__HAL_RCC_PWR_CLK_ENABLE();
pwrclkchanged = SET;
}
if (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP)) {
/* Enable write access to Backup domain */
SET_BIT(PWR->DBPR, PWR_DBPR_DBP);
/* Wait for Backup domain Write protection disable */
tickstart = HAL_GetTick();
while (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP)) {
if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) {
/* Restore clock configuration if changed */
if (pwrclkchanged == SET) {
__HAL_RCC_PWR_CLK_DISABLE();
}
return HAL_TIMEOUT;
}
}
}
uint32_t bdcr_temp = RCC->BDCR;
if (RCC_LSI_DIV1 != (bdcr_temp & RCC_BDCR_LSIPREDIV)) {
if (((bdcr_temp & RCC_BDCR_LSIRDY) == RCC_BDCR_LSIRDY) &&
((bdcr_temp & RCC_BDCR_LSION) != RCC_BDCR_LSION)) {
/* If LSIRDY is set while LSION is not enabled, LSIPREDIV can't be updated
*/
/* The LSIPREDIV cannot be changed if the LSI is used by the IWDG or by
* the RTC */
/* Restore clock configuration if changed */
if (pwrclkchanged == SET) {
__HAL_RCC_PWR_CLK_DISABLE();
}
return HAL_ERROR;
}
/* Turn off LSI before changing RCC_BDCR_LSIPREDIV */
if ((bdcr_temp & RCC_BDCR_LSION) == RCC_BDCR_LSION) {
__HAL_RCC_LSI_DISABLE();
tickstart = HAL_GetTick();
/* Wait till LSI is disabled */
while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) != 0U)
;
}
/* Set LSI division factor */
MODIFY_REG(RCC->BDCR, RCC_BDCR_LSIPREDIV, 0);
}
/* Enable the Internal Low Speed oscillator (LSI) */
__HAL_RCC_LSI_ENABLE();
/* Wait till LSI is ready */
while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) == 0U)
;
/* Restore clock configuration if changed */
if (pwrclkchanged == SET) {
__HAL_RCC_PWR_CLK_DISABLE();
}
return HAL_OK;
}
void tamper_init(void) {
RCC_PeriphCLKInitTypeDef clk_init_def = {0};
// Enable LSI clock
lsi_init();
// 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();
PWR->BDCR1 |= PWR_BDCR1_MONEN;
// 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;
TAMP->SCR = 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);
}

View File

@ -0,0 +1,200 @@
#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();
/* -------------------------------------------------------------------------*/
/* 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. */
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++) {
MPCBB_desc.AttributeConfig.MPCBB_SecConfig_array[index] = 0xFFFFFFFFU;
MPCBB_desc.AttributeConfig.MPCBB_PrivConfig_array[index] = 0x00000000U;
}
HAL_GTZC_MPCBB_ConfigMem(SRAM1_BASE, &MPCBB_desc);
HAL_GTZC_MPCBB_ConfigMem(SRAM2_BASE, &MPCBB_desc);
HAL_GTZC_MPCBB_ConfigMem(SRAM3_BASE, &MPCBB_desc);
HAL_GTZC_MPCBB_ConfigMem(SRAM4_BASE, &MPCBB_desc);
#if defined STM32U5A9xx | defined STM32U5G9xx
HAL_GTZC_MPCBB_ConfigMem(SRAM5_BASE, &MPCBB_desc);
#endif
#if defined STM32U5G9xx
HAL_GTZC_MPCBB_ConfigMem(SRAM6_BASE, &MPCBB_desc);
#endif
/* -------------------------------------------------------------------------*/
/* Internal Flash */
/* The booking is done in both IDAU/SAU and FLASH interface */
/* 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)) */
/* -------------------------------------------------------------------------*/
#if defined STM32U5A9xx | defined STM32U5G9xx
HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_LTDC, GTZC_TZSC_PERIPH_SEC);
HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_DSI, GTZC_TZSC_PERIPH_SEC);
HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_GFXMMU,
GTZC_TZSC_PERIPH_SEC);
HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_GFXMMU_REG,
GTZC_TZSC_PERIPH_SEC);
#endif
HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_DMA2D, GTZC_TZSC_PERIPH_SEC);
/* Clear all illegal access flags in GTZC TZIC */
HAL_GTZC_TZIC_ClearFlag(GTZC_PERIPH_ALL);
/* Enable all illegal access interrupts in GTZC TZIC */
HAL_GTZC_TZIC_EnableIT(GTZC_PERIPH_ALL);
/* Enable GTZC secure interrupt */
HAL_NVIC_SetPriority(GTZC_IRQn, 0, 0); /* Highest priority level */
HAL_NVIC_EnableIRQ(GTZC_IRQn);
}
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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