parent
966ced9579
commit
5160cbc2f9
@ -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,
|
||||
)
|
@ -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
|
Loading…
Reference in new issue