TrustZone POC (firmware split)

cepetr/u5/tz-poc
cepetr 6 months ago
parent 966ced9579
commit 5160cbc2f9

@ -12,6 +12,9 @@ BOOTLOADER_EMU_BUILD_DIR = $(BUILD_DIR)/bootloader_emu
PRODTEST_BUILD_DIR = $(BUILD_DIR)/prodtest
REFLASH_BUILD_DIR = $(BUILD_DIR)/reflash
FIRMWARE_BUILD_DIR = $(BUILD_DIR)/firmware
FW_SS_BUILD_DIR = $(BUILD_DIR)/fw_ss
FW_CS_BUILD_DIR = $(BUILD_DIR)/fw_cs
FW_AP_BUILD_DIR = $(BUILD_DIR)/fw_ap
UNIX_BUILD_DIR = $(BUILD_DIR)/unix
RUST_BUILD_DIR = $(BUILD_DIR)/rust
@ -223,6 +226,32 @@ build_firmware: templates build_cross ## build firmware with frozen modules
DISABLE_OPTIGA="$(DISABLE_OPTIGA)" \
$(FIRMWARE_BUILD_DIR)/firmware.bin
build_fw_ss: templates build_cross ## build secure services firmware (experiment)
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" \
TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" \
PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" \
BOOTLOADER_QA="$(BOOTLOADER_QA)" BOOTLOADER_DEVEL="$(BOOTLOADER_DEVEL)" \
DISABLE_OPTIGA="$(DISABLE_OPTIGA)" \
$(FW_SS_BUILD_DIR)/fw_ss.bin
build_fw_cs: templates build_cross ## build secure services firmware (experiment)
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" \
TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" \
PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" \
BOOTLOADER_QA="$(BOOTLOADER_QA)" BOOTLOADER_DEVEL="$(BOOTLOADER_DEVEL)" \
DISABLE_OPTIGA="$(DISABLE_OPTIGA)" \
$(FW_CS_BUILD_DIR)/fw_cs.bin
build_fw_ap: templates build_cross ## build secure services firmware (experiment)
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" \
TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" \
PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" \
BOOTLOADER_QA="$(BOOTLOADER_QA)" BOOTLOADER_DEVEL="$(BOOTLOADER_DEVEL)" \
DISABLE_OPTIGA="$(DISABLE_OPTIGA)" \
$(FW_AP_BUILD_DIR)/fw_ap.bin
build_fw: build_fw_ss build_fw_cs build_fw_ap
build_unix: templates ## build unix port
$(SCONS) CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) \
TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" \
@ -268,6 +297,9 @@ clean_reflash: ## clean reflash build
clean_firmware: ## clean firmware build
rm -rf $(FIRMWARE_BUILD_DIR) $(RUST_BUILD_DIR)
clean_fw_ss: ## clean secure services firmware build (experimental)
rm -rf $(FW_SS_BUILD_DIR)
clean_unix: ## clean unix build
rm -rf $(UNIX_BUILD_DIR) $(RUST_BUILD_DIR)
@ -298,6 +330,17 @@ else
$(OPENOCD) -c "init; reset halt; flash write_image erase $< $(FIRMWARE_START); exit"
endif
flash_fw_ss: $(FW_SS_BUILD_DIR)/fw_ss.bin ## flash secure service firmware using OpenOCD (experiment)
$(OPENOCD) -c "init; reset halt; flash write_image erase $< 0x0C050000; exit"
flash_fw_cs: $(FW_CS_BUILD_DIR)/fw_cs.bin ## flash core service firmware using OpenOCD (experiment)
$(OPENOCD) -c "init; reset halt; flash write_image erase $< 0x08090000; exit"
flash_fw_ap: $(FW_AP_BUILD_DIR)/fw_ap.bin ## flash application firmware using OpenOCD (experiment)
$(OPENOCD) -c "init; reset halt; flash write_image erase $< 0x080D0000; exit"
flash_fw: flash_fw_ss flash_fw_cs flash_fw_ap ## flash ss/cs/ap
flash_combine: $(PRODTEST_BUILD_DIR)/combined.bin ## flash combined using OpenOCD
$(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit"

@ -103,6 +103,7 @@ env.Replace(
'-fsingle-precision-constant -fdata-sections -ffunction-sections '
'-ffreestanding '
'-fstack-protector-all '
'-mcmse '
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB',
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",

@ -148,6 +148,7 @@ env.Replace(
'-fsingle-precision-constant -fdata-sections -ffunction-sections '
'-ffreestanding '
'-fstack-protector-all '
'-mcmse '
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB',
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',

@ -0,0 +1,107 @@
# pylint: disable=E0602
# fmt: off
import os
import tools
from site_scons.boards import get_hw_model_as_number
PRODUCTION = ARGUMENTS.get('PRODUCTION', '0') == '1'
BOOTLOADER_QA = ARGUMENTS.get('BOOTLOADER_QA', '0') == '1'
BOOTLOADER_DEVEL = ARGUMENTS.get('BOOTLOADER_DEVEL', '0') == '1'
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
env = Environment(ENV=os.environ, CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DBOOTLOADER_QA={int(BOOTLOADER_QA)}")
FILE_SUFFIX= env.get('ENV')['SUFFIX']
SOURCE_FIRMWARE = [
'embed/fw_ap/main.c',
'embed/fw_ap/core_api.S',
'embed/fw_ap/libc_syscalls.c',
'embed/fw_ap/startup.S',
]
env.Replace(
CAT='cat',
DD='dd',
CP='cp',
SED='sed',
AS='arm-none-eabi-as',
AR='arm-none-eabi-ar',
CC='arm-none-eabi-gcc',
LINK='arm-none-eabi-gcc',
SIZE='arm-none-eabi-size',
STRIP='arm-none-eabi-strip',
OBJCOPY='arm-none-eabi-objcopy', )
env.Replace(
TREZOR_MODEL=TREZOR_MODEL,)
if TREZOR_MODEL in ('1',):
LD_VARIANT = '' if EVERYTHING else '_min'
else:
LD_VARIANT = ''
env.Replace(
COPT=env.get('ENV').get('OPTIMIZE', '-O0'),
CCFLAGS='$COPT '
'-g3 '
'-nostdlib '
'-std=gnu11 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -fno-common '
'-fsingle-precision-constant -fdata-sections -ffunction-sections '
'-ffreestanding '
'-fstack-protector-all '
+ env.get('ENV')["CPU_CCFLAGS"],
LINKFLAGS='-T embed/fw_ap/memory_${TREZOR_MODEL}%s.ld -Wl,--gc-sections -Wl,--print-memory-usage -Wl,-Map=build/fw_ap/fw_ap.map -Wl,--warn-common build/fw_ss/fw_ss_cmse.o' % LD_VARIANT,
CPPPATH=[
'.',
'embed/fw_ap',
],
CPPDEFINES=[
'TREZOR_MODEL_'+TREZOR_MODEL,
f'HW_MODEL={get_hw_model_as_number("D002")}',
'HW_REVISION=0',
],
ASFLAGS=env.get('ENV')['CPU_ASFLAGS'],
ASPPFLAGS='$CFLAGS $CCFLAGS',
)
env.Replace(
PYTHON='python',
)
#
# Program objects
#
source_files = SOURCE_FIRMWARE
obj_program = []
obj_program.extend(env.Object(source=SOURCE_FIRMWARE))
MODEL_IDENTIFIER = tools.get_model_identifier(TREZOR_MODEL)
program_elf = env.Command(
target='fw_ap.elf',
source=obj_program,
action=
'$LINK -o $TARGET $CCFLAGS $CFLAGS $SOURCES $LINKFLAGS -lc_nano -lm -lgcc',
)
BINARY_NAME = f"build/fw_ap/fw_ap-{tools.get_model_identifier(TREZOR_MODEL)}"
BINARY_NAME += "-" + tools.get_version('embed/fw_ap/version.h')
BINARY_NAME += "-" + tools.get_git_revision_short_hash()
BINARY_NAME += "-dirty" if tools.get_git_modified() else ""
BINARY_NAME += ".bin"
action_bin=[
'$OBJCOPY -O binary -j .flash -j .data $SOURCE ${TARGET}',
'$CP $TARGET ' + BINARY_NAME,
]
program_bin = env.Command(
target='fw_ap.bin',
source=program_elf,
action=action_bin,
)

@ -0,0 +1,365 @@
# pylint: disable=E0602
# fmt: off
import os
import tools
BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0')
PRODUCTION = ARGUMENTS.get('PRODUCTION', '0') == '1'
BOOTLOADER_QA = ARGUMENTS.get('BOOTLOADER_QA', '0') == '1'
BOOTLOADER_DEVEL = ARGUMENTS.get('BOOTLOADER_DEVEL', '0') == '1'
EVERYTHING = BITCOIN_ONLY != '1'
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
PYOPT = ARGUMENTS.get('PYOPT', '1')
DISABLE_OPTIGA = ARGUMENTS.get('DISABLE_OPTIGA', '0') == '1'
FEATURE_FLAGS = {
"RDI": False,
"SECP256K1_ZKP": False, # required for trezor.crypto.curve.bip340 (BIP340/Taproot)
"SYSTEM_VIEW": False,
}
FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga"]
if DISABLE_OPTIGA and PYOPT == '0':
FEATURES_WANTED.remove("optiga")
CCFLAGS_MOD = ''
CPPPATH_MOD = []
CPPDEFINES_MOD = []
SOURCE_MOD = []
CPPDEFINES_HAL = []
SOURCE_HAL = []
PATH_HAL = []
FROZEN = False
if TREZOR_MODEL in ('1', 'R'):
FONT_NORMAL='Font_PixelOperator_Regular_8'
FONT_DEMIBOLD='Font_Unifont_Bold_16'
FONT_BOLD='Font_PixelOperator_Bold_8'
FONT_MONO='Font_PixelOperatorMono_Regular_8'
FONT_BIG='Font_Unifont_Regular_16'
elif TREZOR_MODEL in ('T', 'DISC1', 'DISC2'):
FONT_NORMAL='Font_TTHoves_Regular_21'
FONT_DEMIBOLD='Font_TTHoves_DemiBold_21'
FONT_BOLD='Font_TTHoves_Bold_17'
FONT_MONO='Font_RobotoMono_Medium_20'
FONT_BIG=None
# modtrezorconfig
CPPPATH_MOD += [
'embed/extmod/modtrezorconfig',
'vendor/trezor-storage',
]
SOURCE_MOD += [
'vendor/trezor-storage/norcow.c',
'vendor/trezor-storage/storage.c',
'vendor/trezor-storage/flash_area.c',
'vendor/trezor-crypto/memzero.c',
]
# modtrezorcrypto
CCFLAGS_MOD += '-Wno-sequence-point '
CPPPATH_MOD += [
'vendor/trezor-crypto',
]
CPPDEFINES_MOD += [
'AES_128',
'AES_192',
('USE_BIP32_CACHE', '0'),
('USE_KECCAK', '1'),
('USE_ETHEREUM', '1' if EVERYTHING else '0'),
('USE_MONERO', '1' if EVERYTHING else '0'),
('USE_CARDANO', '1' if EVERYTHING else '0'),
('USE_NEM', '1' if (EVERYTHING and TREZOR_MODEL != "R") else '0'),
('USE_EOS', '1' if (EVERYTHING and TREZOR_MODEL != "R") else '0'),
]
SOURCE_MOD += [
'embed/lib/buffers.c',
'embed/lib/display.c',
'embed/lib/colors.c',
'embed/lib/fonts/fonts.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/image.c',
'embed/lib/mini_printf.c',
]
if EVERYTHING:
SOURCE_MOD += [
'vendor/trezor-crypto/cardano.c',
'vendor/trezor-crypto/monero/base58.c',
'vendor/trezor-crypto/monero/serialize.c',
'vendor/trezor-crypto/monero/xmr.c',
]
# libsecp256k1-zkp
if FEATURE_FLAGS["SECP256K1_ZKP"]:
CPPPATH_MOD += [
'vendor/secp256k1-zkp',
'vendor/secp256k1-zkp/src',
'vendor/secp256k1-zkp/include',
]
CPPDEFINES_MOD += [
'USE_SECP256K1_ZKP',
'USE_SECP256K1_ZKP_ECDSA',
('SECP256K1_CONTEXT_SIZE', '180'),
'USE_ASM_ARM',
'USE_EXTERNAL_ASM',
'USE_EXTERNAL_DEFAULT_CALLBACKS',
('ECMULT_GEN_PREC_BITS', '2'),
('ECMULT_WINDOW_SIZE', '8'),
'ENABLE_MODULE_GENERATOR',
'ENABLE_MODULE_RECOVERY',
'ENABLE_MODULE_SCHNORRSIG',
'ENABLE_MODULE_EXTRAKEYS',
]
SOURCE_MOD_SECP256K1_ZKP = [
'vendor/secp256k1-zkp/src/secp256k1.c',
'vendor/secp256k1-zkp/src/precomputed_ecmult.c',
'vendor/secp256k1-zkp/src/precomputed_ecmult_gen.c',
'vendor/secp256k1-zkp/src/asm/field_10x26_arm.s'
]
SOURCE_MOD += [
'vendor/trezor-crypto/zkp_context.c',
'vendor/trezor-crypto/zkp_ecdsa.c',
'vendor/trezor-crypto/zkp_bip340.c',
]
CPPDEFINES_MOD += [
'TREZOR_UI2',
]
if FEATURE_FLAGS["RDI"]:
CPPDEFINES_MOD += ['RDI']
if FEATURE_FLAGS["SYSTEM_VIEW"]:
SOURCE_FIRMWARE += [
'embed/segger/SEGGER/SEGGER_SYSVIEW_Config_NoOS.c',
'embed/segger/SEGGER/SEGGER_SYSVIEW.c',
'embed/segger/SEGGER/SEGGER_RTT.c',
'embed/segger/SEGGER/SEGGER_RTT_ASM_ARMv7M.S',
'embed/segger/SEGGER/Syscalls/SEGGER_RTT_Syscalls_GCC.c',
'embed/fw_cs/systemview.c',
]
CPPPATH_MOD += [
'embed/segger/SEGGER/',
'embed/segger/Config/',
]
CPPDEFINES_MOD += ['SYSTEM_VIEW']
CCFLAGS_MOD += '-DSYSTEM_VIEW '
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('DEMIBOLD', FONT_DEMIBOLD, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MONO', FONT_MONO, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BIG', FONT_BIG, CPPDEFINES_MOD, SOURCE_MOD)
env = Environment(ENV=os.environ, CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DPYOPT={PYOPT} -DBOOTLOADER_QA={int(BOOTLOADER_QA)} -DBITCOIN_ONLY={BITCOIN_ONLY}")
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/fw_cs/jump_unprivileged.s',
'embed/fw_cs/svc_handler_low.s',
'embed/fw_cs/svc_handler.c',
'embed/fw_cs/core_api_impl.c',
'embed/fw_cs/header.S',
'embed/fw_cs/main.c',
f'embed/fw_cs/startup_{FILE_SUFFIX}.S',
]
if TREZOR_MODEL in ('T', 'DISC1', 'DISC2'):
UI_LAYOUT = 'UI_LAYOUT_TT'
ui_layout_feature = 'model_tt'
elif TREZOR_MODEL in ('1', 'R'):
UI_LAYOUT = 'UI_LAYOUT_TR'
ui_layout_feature = 'model_tr'
else:
raise ValueError('Unknown Trezor model')
if 'sd_card' in FEATURES_AVAILABLE:
SDCARD = True
else:
SDCARD = False
env.Replace(
CAT='cat',
DD='dd',
CP='cp',
SED='sed',
AS='arm-none-eabi-as',
AR='arm-none-eabi-ar',
CC='arm-none-eabi-gcc',
LINK='arm-none-eabi-gcc',
SIZE='arm-none-eabi-size',
STRIP='arm-none-eabi-strip',
OBJCOPY='arm-none-eabi-objcopy', )
env.Replace(
TREZOR_MODEL=TREZOR_MODEL,)
if TREZOR_MODEL in ('1',):
LD_VARIANT = '' if EVERYTHING else '_min'
else:
LD_VARIANT = ''
env.Replace(
COPT=env.get('ENV').get('OPTIMIZE', '-O0'),
CCFLAGS='$COPT '
'-g3 '
'-nostdlib '
'-std=gnu11 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -fno-common '
'-fsingle-precision-constant -fdata-sections -ffunction-sections '
'-ffreestanding '
'-fstack-protector-all '
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
LINKFLAGS='-T embed/fw_cs/memory_${TREZOR_MODEL}%s.ld -Wl,--gc-sections -Wl,--print-memory-usage -Wl,-Map=build/fw_cs/fw_cs.map -Wl,--warn-common build/fw_ss/fw_ss_cmse.o' % LD_VARIANT,
CPPPATH=[
'.',
'embed/rust',
'embed/fw_cs',
'embed/lib',
'embed/models',
'embed/trezorhal',
'embed/extmod/modtrezorui',
] + CPPPATH_MOD + PATH_HAL,
CPPDEFINES=[
'FIRMWARE',
'TREZOR_MODEL_'+TREZOR_MODEL,
'USE_HAL_DRIVER',
'ARM_USER_MODE',
UI_LAYOUT,
] + CPPDEFINES_MOD + CPPDEFINES_HAL,
ASFLAGS=env.get('ENV')['CPU_ASFLAGS'],
ASPPFLAGS='$CFLAGS $CCFLAGS',
)
env.Replace(
HEADERTOOL='tools/headertool.py',
PYTHON='python',
MAKEVERSIONHDR='$PYTHON vendor/micropython/py/makeversionhdr.py',
MAKEMODULEDEFS='$PYTHON vendor/micropython/py/makemoduledefs.py',
MAKECMAKELISTS='$PYTHON tools/make_cmakelists.py',
)
#
# Program objects
#
source_files = SOURCE_MOD + SOURCE_FIRMWARE + SOURCE_HAL
obj_program = []
obj_program.extend(env.Object(source=SOURCE_MOD))
obj_program.extend(env.Object(source=SOURCE_FIRMWARE))
obj_program.extend(env.Object(source=SOURCE_HAL))
env.Replace(
ALLSOURCES=source_files,
ALLDEFS=tools.get_defs_for_cmake(env['CPPDEFINES'] + [f"PRODUCTION={int(PRODUCTION)}", f"BOOTLOADER_QA={int(BOOTLOADER_QA)}", f"PYOPT={PYOPT}", f"BITCOIN_ONLY={BITCOIN_ONLY}"]))
cmake_gen = env.Command(
target='CMakeLists.txt',
source='',
action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS',
)
MODEL_IDENTIFIER = tools.get_model_identifier(TREZOR_MODEL)
BOOTLOADER_SUFFIX = MODEL_IDENTIFIER
if BOOTLOADER_QA:
BOOTLOADER_SUFFIX += '_qa'
# select vendor header
if BOOTLOADER_QA or BOOTLOADER_DEVEL:
vendor = "dev_DO_NOT_SIGN_signed_dev"
elif not PRODUCTION:
vendor = "unsafe_signed_prod"
else:
if TREZOR_MODEL in ('T',):
vendor = "satoshilabs_signed_prod"
elif BITCOIN_ONLY == '1':
vendor = "trezor_btconly_signed_prod"
else:
vendor = "trezor_signed_prod"
VENDORHEADER = f'embed/vendorheader/{MODEL_IDENTIFIER}/vendorheader_{vendor}.bin'
if TREZOR_MODEL not in ('1',):
obj_program.extend(
env.Command(
target='embed/fw_cs/vendorheader.o',
source=VENDORHEADER,
action='$OBJCOPY -I binary -O elf32-littlearm -B arm'
' --rename-section .data=.vendorheader,alloc,load,readonly,contents'
' $SOURCE $TARGET', ))
if TREZOR_MODEL not in ('DISC1', 'DISC2'):
tools.embed_binary(
obj_program,
env,
'bootloader',
'embed/fw_cs/bootloaders/bootloader.o',
f'embed/fw_cs/bootloaders/bootloader_{BOOTLOADER_SUFFIX}.bin',
)
program_elf = env.Command(
target='fw_cs.elf',
source=obj_program,
action=
'$LINK -o $TARGET $CCFLAGS $CFLAGS $SOURCES $LINKFLAGS -lc_nano -lm -lgcc',
)
if CMAKELISTS != 0:
env.Depends(program_elf, cmake_gen)
BINARY_NAME = f"build/fw_cs/fw_cs-{tools.get_model_identifier(TREZOR_MODEL)}"
if not EVERYTHING:
BINARY_NAME += "-btconly"
BINARY_NAME += "-" + tools.get_version('embed/fw_cs/version.h')
BINARY_NAME += "-" + tools.get_git_revision_short_hash()
BINARY_NAME += "-dirty" if tools.get_git_modified() else ""
BINARY_NAME += ".bin"
if TREZOR_MODEL in ('1',):
action_bin=[
'$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:
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='fw_cs.bin',
source=program_elf,
action=action_bin,
)

@ -0,0 +1,364 @@
# pylint: disable=E0602
# fmt: off
import os
import tools
BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0')
PRODUCTION = ARGUMENTS.get('PRODUCTION', '0') == '1'
BOOTLOADER_QA = ARGUMENTS.get('BOOTLOADER_QA', '0') == '1'
BOOTLOADER_DEVEL = ARGUMENTS.get('BOOTLOADER_DEVEL', '0') == '1'
EVERYTHING = BITCOIN_ONLY != '1'
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
PYOPT = ARGUMENTS.get('PYOPT', '1')
DISABLE_OPTIGA = ARGUMENTS.get('DISABLE_OPTIGA', '0') == '1'
FEATURE_FLAGS = {
"RDI": False,
"SECP256K1_ZKP": False, # required for trezor.crypto.curve.bip340 (BIP340/Taproot)
"SYSTEM_VIEW": False,
}
FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga"]
if DISABLE_OPTIGA and PYOPT == '0':
FEATURES_WANTED.remove("optiga")
CCFLAGS_MOD = ''
CPPPATH_MOD = []
CPPDEFINES_MOD = []
SOURCE_MOD = []
CPPDEFINES_HAL = []
SOURCE_HAL = []
PATH_HAL = []
FROZEN = False
if TREZOR_MODEL in ('1', 'R'):
FONT_NORMAL='Font_PixelOperator_Regular_8'
FONT_DEMIBOLD='Font_Unifont_Bold_16'
FONT_BOLD='Font_PixelOperator_Bold_8'
FONT_MONO='Font_PixelOperatorMono_Regular_8'
FONT_BIG='Font_Unifont_Regular_16'
elif TREZOR_MODEL in ('T', 'DISC1', 'DISC2'):
FONT_NORMAL='Font_TTHoves_Regular_21'
FONT_DEMIBOLD='Font_TTHoves_DemiBold_21'
FONT_BOLD='Font_TTHoves_Bold_17'
FONT_MONO='Font_RobotoMono_Medium_20'
FONT_BIG=None
# modtrezorconfig
CPPPATH_MOD += [
'embed/extmod/modtrezorconfig',
'vendor/trezor-storage',
]
SOURCE_MOD += [
'vendor/trezor-storage/norcow.c',
'vendor/trezor-storage/storage.c',
'vendor/trezor-storage/flash_area.c',
'vendor/trezor-crypto/memzero.c',
]
# modtrezorcrypto
CCFLAGS_MOD += '-Wno-sequence-point '
CPPPATH_MOD += [
'vendor/trezor-crypto',
]
CPPDEFINES_MOD += [
'AES_128',
'AES_192',
('USE_BIP32_CACHE', '0'),
('USE_KECCAK', '1'),
('USE_ETHEREUM', '1' if EVERYTHING else '0'),
('USE_MONERO', '1' if EVERYTHING else '0'),
('USE_CARDANO', '1' if EVERYTHING else '0'),
('USE_NEM', '1' if (EVERYTHING and TREZOR_MODEL != "R") else '0'),
('USE_EOS', '1' if (EVERYTHING and TREZOR_MODEL != "R") else '0'),
]
SOURCE_MOD += [
'embed/lib/buffers.c',
'embed/lib/display.c',
'embed/lib/colors.c',
'embed/lib/fonts/fonts.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/image.c',
'embed/lib/mini_printf.c',
]
if EVERYTHING:
SOURCE_MOD += [
'vendor/trezor-crypto/cardano.c',
'vendor/trezor-crypto/monero/base58.c',
'vendor/trezor-crypto/monero/serialize.c',
'vendor/trezor-crypto/monero/xmr.c',
]
# libsecp256k1-zkp
if FEATURE_FLAGS["SECP256K1_ZKP"]:
CPPPATH_MOD += [
'vendor/secp256k1-zkp',
'vendor/secp256k1-zkp/src',
'vendor/secp256k1-zkp/include',
]
CPPDEFINES_MOD += [
'USE_SECP256K1_ZKP',
'USE_SECP256K1_ZKP_ECDSA',
('SECP256K1_CONTEXT_SIZE', '180'),
'USE_ASM_ARM',
'USE_EXTERNAL_ASM',
'USE_EXTERNAL_DEFAULT_CALLBACKS',
('ECMULT_GEN_PREC_BITS', '2'),
('ECMULT_WINDOW_SIZE', '8'),
'ENABLE_MODULE_GENERATOR',
'ENABLE_MODULE_RECOVERY',
'ENABLE_MODULE_SCHNORRSIG',
'ENABLE_MODULE_EXTRAKEYS',
]
SOURCE_MOD_SECP256K1_ZKP = [
'vendor/secp256k1-zkp/src/secp256k1.c',
'vendor/secp256k1-zkp/src/precomputed_ecmult.c',
'vendor/secp256k1-zkp/src/precomputed_ecmult_gen.c',
'vendor/secp256k1-zkp/src/asm/field_10x26_arm.s'
]
SOURCE_MOD += [
'vendor/trezor-crypto/zkp_context.c',
'vendor/trezor-crypto/zkp_ecdsa.c',
'vendor/trezor-crypto/zkp_bip340.c',
]
CPPDEFINES_MOD += [
'TREZOR_UI2',
]
if FEATURE_FLAGS["RDI"]:
CPPDEFINES_MOD += ['RDI']
if FEATURE_FLAGS["SYSTEM_VIEW"]:
SOURCE_FIRMWARE += [
'embed/segger/SEGGER/SEGGER_SYSVIEW_Config_NoOS.c',
'embed/segger/SEGGER/SEGGER_SYSVIEW.c',
'embed/segger/SEGGER/SEGGER_RTT.c',
'embed/segger/SEGGER/SEGGER_RTT_ASM_ARMv7M.S',
'embed/segger/SEGGER/Syscalls/SEGGER_RTT_Syscalls_GCC.c',
'embed/fw_ss/systemview.c',
]
CPPPATH_MOD += [
'embed/segger/SEGGER/',
'embed/segger/Config/',
]
CPPDEFINES_MOD += ['SYSTEM_VIEW']
CCFLAGS_MOD += '-DSYSTEM_VIEW '
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('DEMIBOLD', FONT_DEMIBOLD, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MONO', FONT_MONO, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BIG', FONT_BIG, CPPDEFINES_MOD, SOURCE_MOD)
env = Environment(ENV=os.environ, CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DPYOPT={PYOPT} -DBOOTLOADER_QA={int(BOOTLOADER_QA)} -DBITCOIN_ONLY={BITCOIN_ONLY}")
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/fw_ss/header.S',
'embed/fw_ss/asm_helpers.S',
'embed/fw_ss/secure_api.c',
'embed/fw_ss/main.c',
f'embed/fw_ss/startup_{FILE_SUFFIX}.S',
]
if TREZOR_MODEL in ('T', 'DISC1', 'DISC2'):
UI_LAYOUT = 'UI_LAYOUT_TT'
ui_layout_feature = 'model_tt'
elif TREZOR_MODEL in ('1', 'R'):
UI_LAYOUT = 'UI_LAYOUT_TR'
ui_layout_feature = 'model_tr'
else:
raise ValueError('Unknown Trezor model')
if 'sd_card' in FEATURES_AVAILABLE:
SDCARD = True
else:
SDCARD = False
env.Replace(
CAT='cat',
DD='dd',
CP='cp',
SED='sed',
AS='arm-none-eabi-as',
AR='arm-none-eabi-ar',
CC='arm-none-eabi-gcc',
LINK='arm-none-eabi-gcc',
SIZE='arm-none-eabi-size',
STRIP='arm-none-eabi-strip',
OBJCOPY='arm-none-eabi-objcopy', )
env.Replace(
TREZOR_MODEL=TREZOR_MODEL,)
if TREZOR_MODEL in ('1',):
LD_VARIANT = '' if EVERYTHING else '_min'
else:
LD_VARIANT = ''
env.Replace(
COPT=env.get('ENV').get('OPTIMIZE', '-O0'),
CCFLAGS='$COPT '
'-g3 '
'-nostdlib '
'-std=gnu11 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -fno-common '
'-fsingle-precision-constant -fdata-sections -ffunction-sections '
'-ffreestanding '
'-fstack-protector-all '
'-mcmse '
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
LINKFLAGS='-T embed/fw_ss/memory_${TREZOR_MODEL}%s.ld -Wl,--gc-sections -Wl,--print-memory-usage -Wl,-Map=build/fw_ss/fw_ss.map -Wl,--warn-common -Wl,--cmse-implib -Wl,--out-implib=build/fw_ss/fw_ss_cmse.o' % LD_VARIANT,
CPPPATH=[
'.',
'embed/rust',
'embed/fw_ss',
'embed/lib',
'embed/models',
'embed/trezorhal',
'embed/extmod/modtrezorui',
] + CPPPATH_MOD + PATH_HAL,
CPPDEFINES=[
'FIRMWARE',
'TREZOR_MODEL_'+TREZOR_MODEL,
'USE_HAL_DRIVER',
'ARM_USER_MODE',
UI_LAYOUT,
] + CPPDEFINES_MOD + CPPDEFINES_HAL,
ASFLAGS=env.get('ENV')['CPU_ASFLAGS'],
ASPPFLAGS='$CFLAGS $CCFLAGS',
)
env.Replace(
HEADERTOOL='tools/headertool.py',
PYTHON='python',
MAKEVERSIONHDR='$PYTHON vendor/micropython/py/makeversionhdr.py',
MAKEMODULEDEFS='$PYTHON vendor/micropython/py/makemoduledefs.py',
MAKECMAKELISTS='$PYTHON tools/make_cmakelists.py',
)
#
# Program objects
#
source_files = SOURCE_MOD + SOURCE_FIRMWARE + SOURCE_HAL
obj_program = []
obj_program.extend(env.Object(source=SOURCE_MOD))
obj_program.extend(env.Object(source=SOURCE_FIRMWARE))
obj_program.extend(env.Object(source=SOURCE_HAL))
env.Replace(
ALLSOURCES=source_files,
ALLDEFS=tools.get_defs_for_cmake(env['CPPDEFINES'] + [f"PRODUCTION={int(PRODUCTION)}", f"BOOTLOADER_QA={int(BOOTLOADER_QA)}", f"PYOPT={PYOPT}", f"BITCOIN_ONLY={BITCOIN_ONLY}"]))
cmake_gen = env.Command(
target='CMakeLists.txt',
source='',
action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS',
)
MODEL_IDENTIFIER = tools.get_model_identifier(TREZOR_MODEL)
BOOTLOADER_SUFFIX = MODEL_IDENTIFIER
if BOOTLOADER_QA:
BOOTLOADER_SUFFIX += '_qa'
# select vendor header
if BOOTLOADER_QA or BOOTLOADER_DEVEL:
vendor = "dev_DO_NOT_SIGN_signed_dev"
elif not PRODUCTION:
vendor = "unsafe_signed_prod"
else:
if TREZOR_MODEL in ('T',):
vendor = "satoshilabs_signed_prod"
elif BITCOIN_ONLY == '1':
vendor = "trezor_btconly_signed_prod"
else:
vendor = "trezor_signed_prod"
VENDORHEADER = f'embed/vendorheader/{MODEL_IDENTIFIER}/vendorheader_{vendor}.bin'
if TREZOR_MODEL not in ('1',):
obj_program.extend(
env.Command(
target='embed/fw_ss/vendorheader.o',
source=VENDORHEADER,
action='$OBJCOPY -I binary -O elf32-littlearm -B arm'
' --rename-section .data=.vendorheader,alloc,load,readonly,contents'
' $SOURCE $TARGET', ))
if TREZOR_MODEL not in ('DISC1', 'DISC2'):
tools.embed_binary(
obj_program,
env,
'bootloader',
'embed/fw_ss/bootloaders/bootloader.o',
f'embed/fw_ss/bootloaders/bootloader_{BOOTLOADER_SUFFIX}.bin',
)
program_elf = env.Command(
target='fw_ss.elf',
source=obj_program,
action=
'$LINK -o $TARGET $CCFLAGS $CFLAGS $SOURCES $LINKFLAGS -lc_nano -lm -lgcc',
)
if CMAKELISTS != 0:
env.Depends(program_elf, cmake_gen)
BINARY_NAME = f"build/fw_ss/fw_ss-{tools.get_model_identifier(TREZOR_MODEL)}"
if not EVERYTHING:
BINARY_NAME += "-btconly"
BINARY_NAME += "-" + tools.get_version('embed/fw_ss/version.h')
BINARY_NAME += "-" + tools.get_git_revision_short_hash()
BINARY_NAME += "-dirty" if tools.get_git_modified() else ""
BINARY_NAME += ".bin"
if TREZOR_MODEL in ('1',):
action_bin=[
'$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:
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_vectors -j .gnu.sgstubs -j .flash -j .data -j .sensitive -j .flash_fill $SOURCE ${TARGET}',
'$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''),
'$CP $TARGET ' + BINARY_NAME,
]
else:
raise Exception("Unknown MCU")
program_bin = env.Command(
target='fw_ss.bin',
source=program_elf,
action=action_bin,
)

@ -8,3 +8,6 @@ SConscript('SConscript.firmware', variant_dir='build/firmware', duplicate=False)
SConscript('SConscript.prodtest', variant_dir='build/prodtest', duplicate=False)
SConscript('SConscript.reflash', variant_dir='build/reflash', duplicate=False)
SConscript('SConscript.unix', variant_dir='build/unix', duplicate=False)
SConscript('SConscript.fw_ss', variant_dir='build/fw_ss', duplicate=False)
SConscript('SConscript.fw_cs', variant_dir='build/fw_cs', duplicate=False)
SConscript('SConscript.fw_ap', variant_dir='build/fw_ap', duplicate=False)

@ -0,0 +1,19 @@
#include <embed/fw_cs/svc_numbers.h>
.syntax unified
.text
.global core_print
.global core_get_secret
core_print:
svc #CORE_SVC_PRINT
bx lr
core_get_secret:
svc #CORE_SVC_GET_SECRET
bx lr
.end

@ -0,0 +1,168 @@
/*
******************************************************************************
File: syscalls.c
Info: Generated by Atollic TrueSTUDIO(R) 9.2.0 2019-04-13
The MIT License (MIT)
Copyright (c) 2018 STMicroelectronics
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************
*/
/* Includes */
#include <errno.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>
#include <time.h>
/* Variables */
#undef errno
extern int32_t errno;
uint8_t *__env[1] = {0};
uint8_t **environ = __env;
/* Functions */
void initialise_monitor_handles(void) {}
int _getpid(void) {
errno = ENOSYS;
return -1;
}
int _gettimeofday(struct timeval *ptimeval, void *ptimezone) {
errno = ENOSYS;
return -1;
}
int _kill(int32_t pid, int32_t sig) {
errno = ENOSYS;
return -1;
}
void _exit(int32_t status) {
while (1) {
} /* Make sure we hang here */
}
int _write(int32_t file, uint8_t *ptr, int32_t len) {
/* Implement your write code here, this is used by puts and printf for example
*/
/* return len; */
errno = ENOSYS;
return -1;
}
void *_sbrk(int32_t incr) {
extern char _heap_end; // Set by linker
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0) {
heap_end = &_heap_end;
}
prev_heap_end = heap_end;
heap_end += incr;
return prev_heap_end;
}
int _close(int32_t file) {
errno = ENOSYS;
return -1;
}
int _fstat(int32_t file, struct stat *st) {
errno = ENOSYS;
return -1;
}
int _isatty(int32_t file) {
errno = ENOSYS;
return 0;
}
int _lseek(int32_t file, int32_t ptr, int32_t dir) {
errno = ENOSYS;
return -1;
}
int _read(int32_t file, uint8_t *ptr, int32_t len) {
errno = ENOSYS;
return -1;
}
int _readlink(const char *path, char *buf, size_t bufsize) {
errno = ENOSYS;
return -1;
}
int _open(const uint8_t *path, int32_t flags, int32_t mode) {
errno = ENOSYS;
return -1;
}
int _wait(int32_t *status) {
errno = ENOSYS;
return -1;
}
int _unlink(const uint8_t *name) {
errno = ENOSYS;
return -1;
}
int _times(struct tms *buf) {
errno = ENOSYS;
return -1;
}
int _stat(const uint8_t *file, struct stat *st) {
errno = ENOSYS;
return -1;
}
int _symlink(const char *path1, const char *path2) {
errno = ENOSYS;
return -1;
}
int _link(const uint8_t *old, const uint8_t *new) {
errno = ENOSYS;
return -1;
}
int _fork(void) {
errno = ENOSYS;
return -1;
}
int _execve(const uint8_t *name, uint8_t *const *argv, uint8_t *const *env) {
errno = ENOSYS;
return -1;
}

@ -0,0 +1,46 @@
/*
* 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 <stdint.h>
#include <stdio.h>
#include <string.h>
#include "embed/fw_cs/core_api.h"
#include <embed/fw_ss/secure_api.h>
int main(void) { // UNPRIVILEGED APPLICATION
char text[64];
core_print("Unprivileged application is running...\n");
// get secret from privileged-world
snprintf(text, sizeof(text), "secret = %d\n", core_get_secret());
core_print(text);
// get secret from secure-world directly
snprintf(text, sizeof(text), "secret = %d\n", secure_get_secret());
core_print(text);
while (1)
;
return 0;
}

@ -0,0 +1,65 @@
/* TREZORv2 firmware linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x080D0000, LENGTH = 256K
SRAM1 (wal) : ORIGIN = 0x20040000, LENGTH = 128K
SRAM2 (wal) : ORIGIN = 0x200C8000, LENGTH = 16K
}
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2);
_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 wipe memory */
sram1_start = ORIGIN(SRAM1);
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
sram2_start = ORIGIN(SRAM2);
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
_heap_start = ADDR(.heap);
_heap_end = ADDR(.heap) + SIZEOF(.heap);
SECTIONS {
.flash : ALIGN(512) {
KEEP(*(.vector_table));
. = ALIGN(4);
*(.text*);
. = ALIGN(4);
*(.rodata*);
. = ALIGN(4);
KEEP(*(.bootloader));
*(.bootloader*);
. = ALIGN(512);
} >FLASH
.data : ALIGN(4) {
*(.data*);
. = ALIGN(512);
} >SRAM1 AT>FLASH
/DISCARD/ : {
*(.ARM.exidx*);
}
.bss : ALIGN(4) {
*(.bss*);
. = 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; /* Overflow causes UsageFault */
} >SRAM2
}

@ -0,0 +1,59 @@
.syntax unified
.text
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
sram1_loop:
str r2, [r0], #4
cmp r0, r1
bne sram1_loop
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
sram2_loop:
str r2, [r0], #4
cmp r0, r1
bne sram2_loop
// 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
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
ldr r0, =0xF1CD3A4D
ldr r1, = __stack_chk_guard
str r0, [r1]
// call static constructors
//bl __libc_init_array
reset: // just for the nice backtrace
// enter the application code
bl main
loop_forever:
b loop_forever
// ================================================================
// The minimal vector table for unprivileged application
.section .vector_table,"a",%progbits
vector_table:
.word _estack
.word reset_handler
.end

@ -0,0 +1,11 @@
#define VERSION_MAJOR 2
#define VERSION_MINOR 6
#define VERSION_PATCH 4
#define VERSION_BUILD 0
#define FIX_VERSION_MAJOR 2
#define FIX_VERSION_MINOR 4
#define FIX_VERSION_PATCH 0
#define FIX_VERSION_BUILD 0
#define VERSION_MONOTONIC 1

@ -0,0 +1,8 @@
#ifndef CORE_CALLS_H
#define CORE_CALLS_H
extern void core_print(char* text);
extern int core_get_secret(void);
#endif // CORE_CALLS_H

@ -0,0 +1,9 @@
#include <core_api.h>
#include <display.h>
#include <embed/fw_ss/secure_api.h>
void core_print(char* text) { display_printf("%s", text); }
int core_get_secret(void) { return secure_get_secret(); }

@ -0,0 +1,54 @@
.syntax unified
#include "version.h"
.section .header, "a"
.type g_header, %object
.size g_header, .-g_header
// Firmware header for both Trezor One and Trezor T.
// Trezor One must have bootloader version >= 1.8.0 (before that version the hdrlen used to be reset vector)
g_header:
.byte 'T','R','Z','F' // magic
.word g_header_end - g_header // hdrlen
#ifdef TREZOR_MODEL_T
.word 0 // expiry
#else
.word 1 // expiry
#endif
.word _codelen // codelen
.byte VERSION_MAJOR // vmajor
.byte VERSION_MINOR // vminor
.byte VERSION_PATCH // vpatch
.byte VERSION_BUILD // vbuild
.byte FIX_VERSION_MAJOR // fix_vmajor
.byte FIX_VERSION_MINOR // fix_vminor
.byte FIX_VERSION_PATCH // fix_vpatch
.byte FIX_VERSION_BUILD // fix_vbuild
.word HW_MODEL // type of the designated hardware
.byte HW_REVISION // revision of the designated hardware
.byte VERSION_MONOTONIC // monotonic version of the binary
. = . + 2 // reserved
. = . + 512 // hash1 ... hash16
#if !defined TREZOR_MODEL_1
// trezor-core header style
. = . + 415 // reserved
.byte 0 // sigmask
. = . + 64 // sig
#else
// model 1 compatibility header
. = . + 64 // sig1
. = . + 64 // sig2
. = . + 64 // sig3
.byte 0 // sigindex1
.byte 0 // sigindex2
.byte 0 // sigindex3
. = . + 220 // reserved
. = . + 65 // reserved
#endif
g_header_end:

@ -0,0 +1,47 @@
.syntax unified
.text
.global jump_unprivileged
// jump_unprivileged() can be called only from an exception handler
// (handler mode)
jump_unprivileged:
ldr r12, [r0, #0] // stack pointer
sub r12, r12, #32
msr PSP, r12
ldr r1, [r0, #0]
sub r1, r1, #16384 // stack limit
msr PSPLIM, r1
mov r1, #0
str r1, [r12, #0] // r0
str r1, [r12, #4] // r1
str r1, [r12, #8] // r2
str r1, [r12, #12] // r3
str r1, [r12, #16] // r12
str r1, [r12, #20] // lr
ldr r1, [r0, #4] // reset vector
bic r1, r1, #1
str r1, [r12, #24] // return address
ldr r1, = 0x01000000
str r1, [r12, #28] // xPSR
// set thread mode to unprivileged level
mrs r1, CONTROL
orr r1, r1, #1
msr CONTROL, r1
// return to Non-Secure Thread mode
// use Non-Secure PSP
ldr lr, = 0xFFFFFFBC
bx lr
.end

@ -0,0 +1,83 @@
/*
* 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 <stdint.h>
#include <stdio.h>
#include <string.h>
#include <display.h>
#include <mpu.h>
#include <touch.h>
#include "svc_numbers.h"
#include <embed/fw_ss/secure_api.h>
void jump_to_user_app(void) {
asm volatile( "svc %0" : : "i"(CORE_SVC_START_APP));
}
void enum_callback(void* context, int secret) {
display_printf("secret = %d\n", secret);
}
void core_init() {
HAL_Init();
mpu_config_cs();
touch_init();
display_reinit();
}
int main(void) { // CORE SERVICES
// Initialize hardware drivers
core_init();
display_printf("Core Services are running...\n");
// Call a function in the secure world
secure_enumerate_secrets(enum_callback, NULL);
{
uint8_t in_buff[64];
uint8_t out_buff[64];
// Test cmse_check_address_range() function
// OK
display_printf("%d\n", secure_process_buff(in_buff, sizeof(in_buff), out_buff, sizeof(out_buff)));
// in_buff in secure memory
display_printf("%d\n", secure_process_buff((void *)0x30000000, sizeof(in_buff), out_buff, sizeof(out_buff)));
// out buff in secure memory
display_printf("%d\n", secure_process_buff(in_buff, sizeof(in_buff), (void *)0x30000000, sizeof(out_buff)));
// out buff in read only memory
display_printf("%d\n", secure_process_buff(in_buff, sizeof(in_buff), (void *)0x08090000, sizeof(out_buff)));
}
HAL_Delay(500); // uses Non-Secure SysTick
// Configure MPU for the unprivileged application
// isolate_unprivileged_world();
// Jump to unprivileged user application
jump_to_user_app();
return 0;
}

@ -0,0 +1,128 @@
/* TREZORv2 firmware linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x08090000, LENGTH = 256K
SRAM1 (wal) : ORIGIN = 0x20020000, LENGTH = 128K
BOOT_ARGS (wal) : ORIGIN = 0x200BFF00, LENGTH = 0x100
SRAM2 (wal) : ORIGIN = 0x200C4000, LENGTH = 16K
SRAM3 (wal) : ORIGIN = 0x200D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x201A0000, LENGTH = 832K
SRAM6 (wal) : ORIGIN = 0x20270000, LENGTH = 0
SRAM4 (wal) : ORIGIN = 0x28000000, LENGTH = 16K
}
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2);
_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);
_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; /* Overflow causes UsageFault */
} >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
.boot_args : ALIGN(8) {
*(.boot_command*);
. = ALIGN(8);
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -0,0 +1,60 @@
.syntax unified
.text
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #32 // reserved for UsageFault exception
msr MSPLIM, r0
// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written
ldr r0, =sram1_start // r0 - point to beginning of SRAM
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram2_start // r0 - point to beginning of SRAM
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
bl memset_reg
ldr r0, =sram3_start // r0 - point to beginning of SRAM
ldr r1, =__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

@ -0,0 +1,40 @@
#include "core_api.h"
#include "svc_numbers.h"
#include <stdint.h>
#include <cmsis_gcc.h>
#define APP_FIRMWARE_VTBL 0x080D0000
extern void jump_unprivileged(uint32_t location);
// !!! SVC_Handler should have the second lowest priority in the system (just after PendSV_Handler)
// => SVC_Handler can be prememted by any interrupt
// !!! PendSV_Handler should be used for task switching (entering into app modules)
void SVC_C_Handler(uint32_t *svc_args) {
// Stack contains:
// r0, r1, r2, r3, r12, r14, the return address and xPSR
// First argument (r0) is svc_args[0]
// __LDRT(), __STRT() instrinsic function should be used to access unprivileged memory
uint8_t svc_number = ((uint8_t *)svc_args[6])[-2];
switch (svc_number) {
case CORE_SVC_PRINT:
core_print((char *)svc_args[0]);
break;
case CORE_SVC_GET_SECRET:
svc_args[0] = core_get_secret();
break;
case CORE_SVC_START_APP:
jump_unprivileged(APP_FIRMWARE_VTBL);
break;
}
}

@ -0,0 +1,15 @@
.syntax unified
.text
.global SVC_Handler
.thumb_func
SVC_Handler:
tst lr, #4
ite eq
mrseq r0, msp
mrsne r0, psp
b SVC_C_Handler
.end

@ -0,0 +1,11 @@
#ifndef CORE_SVC_NUMBERS_H
#define CORE_SVC_NUMBERS_H
// service calls
#define CORE_SVC_PRINT 1
#define CORE_SVC_GET_SECRET 2
// special service calls
#define CORE_SVC_START_APP 255
#endif // CORE_SVC_NUMBERS_H

@ -0,0 +1,11 @@
#define VERSION_MAJOR 2
#define VERSION_MINOR 6
#define VERSION_PATCH 4
#define VERSION_BUILD 0
#define FIX_VERSION_MAJOR 2
#define FIX_VERSION_MINOR 4
#define FIX_VERSION_PATCH 0
#define FIX_VERSION_BUILD 0
#define VERSION_MONOTONIC 1

@ -0,0 +1,22 @@
.syntax unified
.text
.global jump_unsecure
.set SCB_VTOR_NS, 0xE002ED08
jump_unsecure:
ldr r1, =SCB_VTOR_NS
str r0, [r1]
ldr r1, [r0, #0]
msr MSP_NS, r1
ldr r1, [r0, #4]
movs r0, #1
bics r1, r0 // bit0 == 0 => transition to Non-secure
bxns r1

@ -0,0 +1,54 @@
.syntax unified
#include "version.h"
.section .header, "a"
.type g_header, %object
.size g_header, .-g_header
// Firmware header for both Trezor One and Trezor T.
// Trezor One must have bootloader version >= 1.8.0 (before that version the hdrlen used to be reset vector)
g_header:
.byte 'T','R','Z','F' // magic
.word g_header_end - g_header // hdrlen
#ifdef TREZOR_MODEL_T
.word 0 // expiry
#else
.word 1 // expiry
#endif
.word _codelen // codelen
.byte VERSION_MAJOR // vmajor
.byte VERSION_MINOR // vminor
.byte VERSION_PATCH // vpatch
.byte VERSION_BUILD // vbuild
.byte FIX_VERSION_MAJOR // fix_vmajor
.byte FIX_VERSION_MINOR // fix_vminor
.byte FIX_VERSION_PATCH // fix_vpatch
.byte FIX_VERSION_BUILD // fix_vbuild
.word HW_MODEL // type of the designated hardware
.byte HW_REVISION // revision of the designated hardware
.byte VERSION_MONOTONIC // monotonic version of the binary
. = . + 2 // reserved
. = . + 512 // hash1 ... hash16
#if !defined TREZOR_MODEL_1
// trezor-core header style
. = . + 415 // reserved
.byte 0 // sigmask
. = . + 64 // sig
#else
// model 1 compatibility header
. = . + 64 // sig1
. = . + 64 // sig2
. = . + 64 // sig3
.byte 0 // sigindex1
.byte 0 // sigindex2
.byte 0 // sigindex3
. = . + 220 // reserved
. = . + 65 // reserved
#endif
g_header_end:

@ -0,0 +1,207 @@
/*
* 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 <stdint.h>
#include <stdio.h>
#include <string.h>
#include <display.h>
#include <touch.h>
#define CORE_SERVICE_VTBL 0x08091600
extern void jump_unsecure(uint32_t location);
void jump_to_core_services(void) { jump_unsecure(CORE_SERVICE_VTBL); }
// from linker
extern uint8_t _sgstubs_start;
extern uint8_t _sgstubs_end;
static void trustzone_configure_sau() {
// configure unsecure regions for core services & application
// Flash (Non-Secure)
SAU->RNR = 0;
SAU->RBAR = 0x08090000 & SAU_RBAR_BADDR_Msk;
SAU->RLAR = ((0x08110000 - 1) & SAU_RLAR_LADDR_Msk) | 0x01;
// Flash (Non-Secure callable)
SAU->RNR = 1;
SAU->RBAR = (uint32_t) &_sgstubs_start & SAU_RBAR_BADDR_Msk;
SAU->RLAR = (((uint32_t) &_sgstubs_end - 1) & SAU_RLAR_LADDR_Msk) | 0x01 | 0x02;
// SRAM1 (Non-Secure)
SAU->RNR = 2;
SAU->RBAR = 0x20020000 & SAU_RBAR_BADDR_Msk;
SAU->RLAR = ((0x20060000 - 1) & SAU_RLAR_LADDR_Msk) | 0x01;
// SRAM2 ((Non-Secure, stack)
SAU->RNR = 3;
SAU->RBAR = 0x200C4000 & SAU_RBAR_BADDR_Msk;
SAU->RLAR = ((0x200CC000 - 1) & SAU_RLAR_LADDR_Msk) | 0x01;
// SRAM3+5 (Non-Secure, fb1+fb2)
SAU->RNR = 4;
SAU->RBAR = 0x200D0000 & SAU_RBAR_BADDR_Msk;
SAU->RLAR = ((0x20270000 - 1) & SAU_RLAR_LADDR_Msk) | 0x01;
// PERIPHERAL (Non-Secure)
SAU->RNR = 5;
SAU->RBAR = PERIPH_BASE_NS & SAU_RBAR_BADDR_Msk;
SAU->RLAR =
((PERIPH_BASE_NS + 256 * 1024 * 1024 - 1) & SAU_RLAR_LADDR_Msk) | 0x01;
// GFXMMU (Non-Secure)
SAU->RNR = 6;
SAU->RBAR = GFXMMU_VIRTUAL_BUFFERS_BASE_NS & SAU_RBAR_BADDR_Msk;
SAU->RLAR = ((GFXMMU_VIRTUAL_BUFFERS_BASE_NS + 16 * 1024 * 1024 - 1) &
SAU_RLAR_LADDR_Msk) |
0x01;
// Enable SAU
SAU->CTRL = SAU_CTRL_ENABLE_Msk;
}
// Configure SRAM security
static void trustzone_configure_sram(void) {
MPCBB_ConfigTypeDef mpcbb = {0};
// No exceptions on illegal access
mpcbb.SecureRWIllegalMode = GTZC_MPCBB_SRWILADIS_DISABLE;
// Settings of SRAM clock in RCC is secure
mpcbb.InvertSecureState = GTZC_MPCBB_INVSECSTATE_NOT_INVERTED;
// Set configuration as unlocked
mpcbb.AttributeConfig.MPCBB_LockConfig_array[0] = 0x00000000U;
// Set all blocks unsecured & unprivileged
for (int index = 0; index < 52; index++) {
mpcbb.AttributeConfig.MPCBB_SecConfig_array[index] = 0x00000000U;
mpcbb.AttributeConfig.MPCBB_PrivConfig_array[index] = 0x00000000U;
}
HAL_GTZC_MPCBB_ConfigMem(SRAM3_BASE, &mpcbb);
HAL_GTZC_MPCBB_ConfigMem(SRAM4_BASE, &mpcbb);
#if defined STM32U5A9xx | defined STM32U5G9xx
HAL_GTZC_MPCBB_ConfigMem(SRAM5_BASE, &mpcbb);
#endif
// Set all blocks secured & unprivileged
for (int index = 0; index < 52; index++) {
mpcbb.AttributeConfig.MPCBB_SecConfig_array[index] = 0xFFFFFFFFU;
mpcbb.AttributeConfig.MPCBB_PrivConfig_array[index] = 0x00000000U;
}
// unsecure 256KB of SRAM1 for core services & app
for (int index = 8; index < 24; index++) {
mpcbb.AttributeConfig.MPCBB_SecConfig_array[index] = 0x00000000U;
}
HAL_GTZC_MPCBB_ConfigMem(SRAM1_BASE, &mpcbb);
// Set all blocks secured & unprivileged
for (int index = 0; index < 52; index++) {
mpcbb.AttributeConfig.MPCBB_SecConfig_array[index] = 0xFFFFFFFFU;
mpcbb.AttributeConfig.MPCBB_PrivConfig_array[index] = 0x00000000U;
}
// unsecure 32KB of SRAM2 (stack) for core services & app
mpcbb.AttributeConfig.MPCBB_SecConfig_array[1] = 0x00000000U;
mpcbb.AttributeConfig.MPCBB_SecConfig_array[2] = 0x00000000U;
HAL_GTZC_MPCBB_ConfigMem(SRAM2_BASE, &mpcbb);
}
// Configure FLASH security
static void trustzone_configure_flash(void) {
FLASH_BBAttributesTypeDef flash_bb = {0};
flash_bb.Bank = FLASH_BANK_1;
flash_bb.BBAttributesType = FLASH_BB_SEC;
HAL_FLASHEx_GetConfigBBAttributes(&flash_bb);
// Set 512KB (64 pages) after secure services unsecure
flash_bb.BBAttributes_array[2] = 0x000000FF;
flash_bb.BBAttributes_array[3] = 0x00000000;
flash_bb.BBAttributes_array[4] = 0xFFFFFF00;
HAL_FLASHEx_ConfigBBAttributes(&flash_bb);
}
static void trustzone_configure_peripherals(void) {
// Make all peripherals unsecure
HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_ALL, GTZC_TZSC_PERIPH_NSEC);
}
void isolate_unsecured_world(void) {
trustzone_configure_sau();
trustzone_configure_flash();
trustzone_configure_sram();
trustzone_configure_peripherals();
// SCB->AIRCR
// SYSRESETREQS <- ?,
// BFHFMINS <- BusFault, HarudFault, NMI Secure/Non-Secure
// SCB->SCR
// SLEEPDEEPS <- ?
// Select secure/unsecure flag for exception handlers
//
// Select secure/unsecure flag for interrupts
// NVIC_SetTargetState()
// PWR_SECCFGR -- Secure everything needed for secure services
// PWR_PRIVCFGR -- NSPRIV, SPRIV <- 1
// TODO
// RCC_SECCFGR -- Secure everything needed for secure services
// RCC_PRIVCFGR -- NSPRIV, SPRIV <- 1
// TODO
// SYSCFG_SECCFGR
// TODO
// GPIO -- Set selected PINs unsecure (all are secure by default)
// TODO
}
void platform_init() {
touch_init();
display_reinit();
}
int main(void) { // SECURE SERVICES
// Initialize hardware driver
platform_init();
display_printf("Secure services are running...\n");
HAL_Delay(500); // uses Secure SysTick
// Configure trust-zone
isolate_unsecured_world();
// Pass execution to unsecured core services
jump_to_core_services();
return 0;
}

@ -0,0 +1,147 @@
/* TREZORv2 firmware linker script */
ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 256K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 128K
BOOT_ARGS (wal) : ORIGIN = 0x300BFF00, LENGTH = 0x100
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 16K
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);
_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);
_codelen = ADDR(.flash_fill) + SIZEOF(.flash_fill) - ADDR(.flash_vectors);
_flash_start = ORIGIN(FLASH);
_flash_end = ORIGIN(FLASH) + LENGTH(FLASH);
_heap_start = ADDR(.heap);
_heap_end = ADDR(.heap) + SIZEOF(.heap);
_sgstubs_start = ADDR(.gnu.sgstubs);
_sgstubs_end = ADDR(.gnu.sgstubs) + SIZEOF(.gnu.sgstubs);
SECTIONS {
.vendorheader : ALIGN(4) {
KEEP(*(.vendorheader))
} >FLASH AT>FLASH
.header : ALIGN(4) {
KEEP(*(.header));
} >FLASH AT>FLASH
.flash_vectors : ALIGN(512) {
KEEP(*(.vector_table));
}
.gnu.sgstubs : ALIGN (32)
{
. = ALIGN(32);
KEEP(*(.gnu.sgstubs*));
. = ALIGN(32);
} > FLASH
.flash : ALIGN(4) {
*(.text*);
. = ALIGN(4);
*(.rodata*);
. = ALIGN(4);
KEEP(*(.bootloader));
*(.bootloader*);
. = ALIGN(512);
} >FLASH AT>FLASH
.data : ALIGN(4) {
*(.data*);
. = ALIGN(32);
} >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; /* Overflow causes UsageFault */
} >SRAM2
.sensitive : ALIGN(4) {
*(.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
.boot_args : ALIGN(8) {
*(.boot_command*);
. = ALIGN(8);
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
.flash_fill : {
BYTE(0);
. = ALIGN(512);
} > FLASH = 0x00
}

@ -0,0 +1,15 @@
- automatizace nastaveni sau a mpu (pouziti symbolu z linker skriptu)
- navrhnout hlavicku neprivilegovane aplikace
- navrh secure API, core API
// - dalsi zkoumani trustzone na STM32U5 (rozdeleni zodpovednosti mezi secure a privileged)
//- prozkoumat primy prechod z unsecure+unprivileged do secure+privileged
//- core_api, kopirovani a kontrola parametru, ochrana proti TOCTOU utoku
//- secure_api, kopirovani a kontrola parametru, cmse_check_address_range() (TT instrukce)
//- dalsich zkoumani Cortex-M33 (registry cpu)
//- nastudovovat zranitelnosti https://cactilab.github.io/assets/pdf/ret2ns2023.pdf
//- prechod secure -> unsecure, vynulovat registry

@ -0,0 +1,57 @@
#include "secure_api.h"
#include STM32_HAL_H
// When returning from or calling a callback from Secure to Non-Secure,
// all registers (r0-15, s0-31) are overwritten by constants, except
// for those that contain important information.
__attribute__((cmse_nonsecure_entry)) int secure_get_secret() {
return 987654321;
}
__attribute__((cmse_nonsecure_entry)) void secure_enumerate_secrets(
secure_enum_callback_t callback, void* callback_context) {
for (int i = 0; i < 5; i++) {
callback(callback_context, i);
}
}
typedef __attribute__((cmse_nonsecure_call)) secure_callback_t ns_secure_callback_t;
__attribute__((cmse_nonsecure_entry)) void secure_another_func(
secure_callback_t callback, void* callback_context) {
// make non-secure callback from normal function ptr
ns_secure_callback_t ns_callback = (ns_secure_callback_t) cmse_nsfptr_create(callback);
ns_callback(callback_context);
}
static inline const void * cmse_check_inbuff(const void * ptr, size_t size) {
return cmse_check_address_range((void *)ptr, size, CMSE_MPU_READ | CMSE_MPU_NONSECURE | CMSE_AU_NONSECURE);
}
static inline void * cmse_check_outbuff( void * ptr, size_t size) {
return cmse_check_address_range(ptr, size, CMSE_MPU_READWRITE | CMSE_MPU_NONSECURE | CMSE_AU_NONSECURE);
}
__attribute__((cmse_nonsecure_entry))
int secure_process_buff(const uint8_t * in_ptr, size_t in_size,
uint8_t * out_ptr, size_t out_size) {
if (! cmse_check_inbuff(in_ptr, in_size)) {
return -1;
}
if (! cmse_check_outbuff(out_ptr, out_size)) {
return -2;
}
return 0;
}

@ -0,0 +1,32 @@
#ifndef SECURE_API_H
#define SECURE_API_H
#include <stdint.h>
#include <stddef.h>
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#define CMSE_NONSECURE_CALL __attribute__((cmse_nonsecure_call))
#else
#define CMSE_NONSECURE_CALL
#endif
int secure_get_secret(void);
typedef void (*secure_enum_callback_t)(void* context,
int secret) CMSE_NONSECURE_CALL;
void secure_enumerate_secrets(secure_enum_callback_t callback,
void* callback_context);
typedef void (*secure_callback_t)(void * context);
void secure_another_function(secure_callback_t * callback, void * context);
int secure_process_buff(const uint8_t * in_ptr, size_t in_size,
uint8_t * out_ptr, size_t out_size);
#endif // SECURE_API_H

@ -0,0 +1,72 @@
.syntax unified
.text
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #32 // reserved for UsageFault exception
msr MSPLIM, r0
// 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

@ -0,0 +1,11 @@
#define VERSION_MAJOR 2
#define VERSION_MINOR 6
#define VERSION_PATCH 4
#define VERSION_BUILD 0
#define FIX_VERSION_MAJOR 2
#define FIX_VERSION_MINOR 4
#define FIX_VERSION_PATCH 0
#define FIX_VERSION_BUILD 0
#define VERSION_MONOTONIC 1

@ -264,7 +264,7 @@ secbool check_image_contents(const image_header *const hdr, uint32_t firstskip,
offset += bytes_to_check;
}
/*
// Check the padding to the end of the area
end_offset = flash_area_get_size(area);
@ -297,7 +297,7 @@ secbool check_image_contents(const image_header *const hdr, uint32_t firstskip,
offset += bytes_to_check;
}
}
}*/
return sectrue;
}

@ -25,5 +25,6 @@ void mpu_config_boardloader(void);
void mpu_config_bootloader(void);
void mpu_config_firmware(void);
void mpu_config_prodtest(void);
void mpu_config_cs(void);
#endif

@ -39,7 +39,7 @@ void svc_reboot_to_bootloader(void) {
}
}
void SVC_C_Handler(uint32_t *stack) {
/*void SVC_C_Handler(uint32_t *stack) {
uint8_t svc_number = ((uint8_t *)stack[6])[-2];
switch (svc_number) {
case SVC_ENABLE_IRQ:
@ -95,6 +95,6 @@ __attribute__((naked)) void SVC_Handler(void) {
" mrsne r0, psp \n" // Make R0 point to process stack pointer
" b SVC_C_Handler \n" // Off to C land
);
}
}*/
#endif // ARM_USER_MODE

@ -1103,7 +1103,7 @@ static int32_t LCD_Init(void) {
status = BSP_ERROR_PERIPH_FAILURE;
} else {
if (MX_LTDC_ConfigLayer(&hlcd_ltdc, LTDC_LAYER_1,
GFXMMU_VIRTUAL_BUFFER0_BASE_S) != HAL_OK) {
GFXMMU_VIRTUAL_BUFFER0_BASE) != HAL_OK) {
status = BSP_ERROR_PERIPH_FAILURE;
}
}
@ -1557,9 +1557,9 @@ void display_pixeldata(uint16_t c) {
uint32_t address = 0;
if (act_frame_buffer == 0) {
address = GFXMMU_VIRTUAL_BUFFER1_BASE_S;
address = GFXMMU_VIRTUAL_BUFFER1_BASE;
} else {
address = GFXMMU_VIRTUAL_BUFFER0_BASE_S;
address = GFXMMU_VIRTUAL_BUFFER0_BASE;
}
/* Get the rectangle start address */
@ -1596,9 +1596,9 @@ uint8_t *display_get_wr_addr(void) {
uint32_t address = 0;
if (act_frame_buffer == 0) {
address = GFXMMU_VIRTUAL_BUFFER1_BASE_S;
address = GFXMMU_VIRTUAL_BUFFER1_BASE;
} else {
address = GFXMMU_VIRTUAL_BUFFER0_BASE_S;
address = GFXMMU_VIRTUAL_BUFFER0_BASE;
}
/* Get the rectangle start address */
@ -1612,9 +1612,9 @@ uint32_t *display_get_fb_addr(void) {
uint32_t address = 0;
if (act_frame_buffer == 0) {
address = GFXMMU_VIRTUAL_BUFFER1_BASE_S;
address = GFXMMU_VIRTUAL_BUFFER1_BASE;
} else {
address = GFXMMU_VIRTUAL_BUFFER0_BASE_S;
address = GFXMMU_VIRTUAL_BUFFER0_BASE;
}
return (uint32_t *)address;
@ -1704,9 +1704,9 @@ void display_reinit(void) {
MX_LTDC_Reinit(&hlcd_ltdc);
if (act_frame_buffer == 0) {
MX_LTDC_ConfigLayer(&hlcd_ltdc, 0, GFXMMU_VIRTUAL_BUFFER0_BASE_S);
MX_LTDC_ConfigLayer(&hlcd_ltdc, 0, GFXMMU_VIRTUAL_BUFFER0_BASE);
} else {
MX_LTDC_ConfigLayer(&hlcd_ltdc, 0, GFXMMU_VIRTUAL_BUFFER1_BASE_S);
MX_LTDC_ConfigLayer(&hlcd_ltdc, 0, GFXMMU_VIRTUAL_BUFFER1_BASE);
}
}
void display_sync(void) {}
@ -1714,11 +1714,11 @@ void display_sync(void) {}
void display_refresh(void) {
if (act_frame_buffer == 0) {
act_frame_buffer = 1;
MX_LTDC_ConfigLayer(&hlcd_ltdc, 0, GFXMMU_VIRTUAL_BUFFER1_BASE_S);
MX_LTDC_ConfigLayer(&hlcd_ltdc, 0, GFXMMU_VIRTUAL_BUFFER1_BASE);
memcpy(PhysFrameBuffer0, PhysFrameBuffer1, sizeof(PhysFrameBuffer1));
} else {
act_frame_buffer = 0;
MX_LTDC_ConfigLayer(&hlcd_ltdc, 0, GFXMMU_VIRTUAL_BUFFER0_BASE_S);
MX_LTDC_ConfigLayer(&hlcd_ltdc, 0, GFXMMU_VIRTUAL_BUFFER0_BASE);
memcpy(PhysFrameBuffer1, PhysFrameBuffer0, sizeof(PhysFrameBuffer1));
}
}

@ -87,7 +87,7 @@ secbool flash_sector_erase(uint16_t sector) {
}
FLASH_EraseInitTypeDef EraseInitStruct = {
.TypeErase = FLASH_TYPEERASE_PAGES_NS,
.TypeErase = FLASH_TYPEERASE_PAGES,
.Banks = FLASH_BANK_1,
.Page = sector,
.NbPages = 1,
@ -98,9 +98,11 @@ secbool flash_sector_erase(uint16_t sector) {
EraseInitStruct.Page = sector - 256;
}
if (flash_sector_is_secure(sector)) {
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if (!flash_sector_is_secure(sector)) {
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES_NS;
}
#endif
uint32_t sector_error = 0;

@ -107,13 +107,18 @@ static void mpu_set_attributes() {
}
#define GFXMMU_BUFFERS_S GFXMMU_VIRTUAL_BUFFERS_BASE_S
#define GFXMMU_BUFFERS GFXMMU_VIRTUAL_BUFFERS_BASE
#define SIZE_16K (16 * 1024)
#define SIZE_48K (48 * 1024)
#define SIZE_32K (32 * 1024)
#define SIZE_64K (64 * 1024)
#define SIZE_128K (128 * 1024)
#define SIZE_192K (192 * 1024)
#define SIZE_256K (256 * 1024)
#define SIZE_320K (320 * 1024)
#define SIZE_512K (512 * 1024)
#define SIZE_768K (768 * 1024)
#define SIZE_2496K (2496 * 1024)
#define SIZE_3776K ((4096 - 320) * 1024)
#define SIZE_3904K ((4096 - 192) * 1024)
@ -173,4 +178,22 @@ void mpu_config_firmware() {
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
void mpu_config_cs() {
HAL_MPU_Disable();
mpu_set_attributes();
// clang-format off
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, FLASH_BASE + SIZE_320K, SIZE_512K, FLASH_CODE, NO, NO ); // Firmware
SET_REGION( 1, SRAM1_BASE, SIZE_2496K, SRAM, YES, YES ); // SRAM1/2/3/5
DIS_REGION( 2 );
SET_REGION( 3, GFXMMU_BUFFERS, SIZE_16M, SRAM, YES, NO ); // Frame buffer
SET_REGION( 4, PERIPH_BASE, SIZE_256M, PERIPHERAL, YES, NO ); // Peripherals
DIS_REGION( 5 );
SET_REGION( 6, FLASH_BASE + SIZE_320K + SIZE_512K, SIZE_256K,FLASH_CODE, NO, YES ); // Firmware
DIS_REGION( 7 );
// clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
void mpu_config_off(void) { HAL_MPU_Disable(); }

@ -27,7 +27,7 @@ def configure(
] = "-mthumb -mcpu=cortex-m33 -mfloat-abi=hard -mfpu=fpv5-sp-d16 "
env.get("ENV")[
"CPU_CCFLAGS"
] = "-mthumb -mcpu=cortex-m33 -mfloat-abi=hard -mfpu=fpv5-sp-d16 -mtune=cortex-m33 -mcmse "
] = "-mthumb -mcpu=cortex-m33 -mfloat-abi=hard -mfpu=fpv5-sp-d16 -mtune=cortex-m33 "
env.get("ENV")["RUST_TARGET"] = "thumbv8m.main-none-eabihf"
defines += [mcu]

Loading…
Cancel
Save