1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-21 05:48:23 +00:00

fix(core): fix vector table alignment on STM32U5

[no changelog]
This commit is contained in:
tychovrahe 2024-07-10 15:18:21 +02:00 committed by TychoVrahe
parent 03199cd553
commit 354dad617d
23 changed files with 64 additions and 16 deletions

View File

@ -340,7 +340,7 @@ int main(void) {
mpu_config_off(); mpu_config_off();
// g_boot_command is preserved on STM32U5 // g_boot_command is preserved on STM32U5
jump_to(BOOTLOADER_START + IMAGE_HEADER_SIZE); jump_to(IMAGE_CODE_ALIGN(BOOTLOADER_START + IMAGE_HEADER_SIZE));
return 0; return 0;
} }

View File

@ -46,7 +46,7 @@ boot_args_start = ORIGIN(BOOT_ARGS);
boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS); boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS);
SECTIONS { SECTIONS {
.vector_table : ALIGN(512) { .vector_table : ALIGN(1024) {
KEEP(*(.vector_table)); KEEP(*(.vector_table));
} >FLASH AT>FLASH } >FLASH AT>FLASH

View File

@ -167,14 +167,14 @@ __attribute__((noreturn)) int main(int argc, char **argv) {
bootloader_main(); bootloader_main();
hal_delay(3000); hal_delay(3000);
jump_to(NULL); jump_to(0);
} }
void mpu_config_bootloader(void) {} void mpu_config_bootloader(void) {}
void mpu_config_off(void) {} void mpu_config_off(void) {}
__attribute__((noreturn)) void jump_to(void *addr) { __attribute__((noreturn)) void jump_to(uint32_t address) {
bool storage_is_erased = bool storage_is_erased =
storage_empty(&STORAGE_AREAS[0]) && storage_empty(&STORAGE_AREAS[1]); storage_empty(&STORAGE_AREAS[0]) && storage_empty(&STORAGE_AREAS[1]);

View File

@ -16,7 +16,7 @@ void set_core_clock(int);
void mpu_config_bootloader(void); void mpu_config_bootloader(void);
void mpu_config_off(void); void mpu_config_off(void);
void display_set_little_endian(void); void display_set_little_endian(void);
void jump_to(void *addr); void jump_to(uint32_t address);
void ensure_compatible_settings(void); void ensure_compatible_settings(void);
#endif #endif

View File

@ -349,7 +349,7 @@ void real_jump_to_firmware(void) {
ensure_compatible_settings(); ensure_compatible_settings();
mpu_config_off(); mpu_config_off();
jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE); jump_to(IMAGE_CODE_ALIGN(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE));
} }
#ifdef STM32U5 #ifdef STM32U5

View File

@ -52,7 +52,7 @@ SECTIONS {
KEEP(*(.header)); KEEP(*(.header));
} >FLASH AT>FLASH } >FLASH AT>FLASH
.flash : ALIGN(512) { .flash : ALIGN(1024) {
KEEP(*(.vector_table)); KEEP(*(.vector_table));
. = ALIGN(4); . = ALIGN(4);
*(.text*); *(.text*);

View File

@ -294,7 +294,7 @@ int main(void) {
// do not check any trust flags on header, proceed // do not check any trust flags on header, proceed
mpu_config_off(); mpu_config_off();
jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE); jump_to(IMAGE_CODE_ALIGN(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE));
return 0; return 0;
} }

View File

@ -52,7 +52,7 @@ SECTIONS {
KEEP(*(.header)); KEEP(*(.header));
} >FLASH AT>FLASH } >FLASH AT>FLASH
.flash : ALIGN(512) { .flash : ALIGN(1024) {
KEEP(*(.vector_table)); KEEP(*(.vector_table));
. = ALIGN(4); . = ALIGN(4);
*(.text*); *(.text*);

View File

@ -60,7 +60,7 @@ SECTIONS {
KEEP(*(.header)); KEEP(*(.header));
} >FLASH AT>FLASH } >FLASH AT>FLASH
.flash : ALIGN(512) { .flash : ALIGN(1024) {
KEEP(*(.vector_table)); KEEP(*(.vector_table));
. = ALIGN(4); . = ALIGN(4);
*(.text*); *(.text*);

View File

@ -245,9 +245,19 @@ secbool check_image_contents(const image_header *const hdr, uint32_t firstskip,
} }
// Check the firmware integrity, calculate and compare hashes // Check the firmware integrity, calculate and compare hashes
size_t offset = firstskip; size_t offset = IMAGE_CODE_ALIGN(firstskip);
size_t end_offset = offset + hdr->codelen; size_t end_offset = offset + hdr->codelen;
// Check area between headers and code
uint32_t padding_size = offset - firstskip;
const uint8_t *addr =
(uint8_t *)flash_area_get_address(area, firstskip, padding_size);
for (size_t i = 0; i < padding_size; i++) {
if (*addr != 0) {
return secfalse;
}
}
while (offset < end_offset) { while (offset < end_offset) {
size_t bytes_to_check = MIN(IMAGE_CHUNK_SIZE - (offset % IMAGE_CHUNK_SIZE), size_t bytes_to_check = MIN(IMAGE_CHUNK_SIZE - (offset % IMAGE_CHUNK_SIZE),
end_offset - offset); end_offset - offset);

View File

@ -35,6 +35,9 @@
#define FIRMWARE_IMAGE_MAGIC 0x465A5254 // TRZF #define FIRMWARE_IMAGE_MAGIC 0x465A5254 // TRZF
#define IMAGE_CODE_ALIGN(addr) \
((((uint32_t)(uintptr_t)addr) + (CODE_ALIGNMENT - 1)) & ~(CODE_ALIGNMENT - 1))
typedef struct { typedef struct {
uint32_t magic; uint32_t magic;
uint32_t hdrlen; uint32_t hdrlen;

View File

@ -23,6 +23,7 @@
#define IMAGE_CHUNK_SIZE (128 * 1024) #define IMAGE_CHUNK_SIZE (128 * 1024)
#define IMAGE_HASH_BLAKE2S #define IMAGE_HASH_BLAKE2S
#define BOARD_CAPABILITIES_ADDR 0x0800BF00 #define BOARD_CAPABILITIES_ADDR 0x0800BF00
#define CODE_ALIGNMENT 0x200
// SHARED WITH MAKEFILE // SHARED WITH MAKEFILE
#define FLASH_START 0x08000000 #define FLASH_START 0x08000000

View File

@ -26,6 +26,7 @@
#define IMAGE_CHUNK_SIZE SIZE_256K #define IMAGE_CHUNK_SIZE SIZE_256K
#define IMAGE_HASH_SHA256 #define IMAGE_HASH_SHA256
#define BOARD_CAPABILITIES_ADDR 0x0C00FF00 #define BOARD_CAPABILITIES_ADDR 0x0C00FF00
#define CODE_ALIGNMENT 0x400
// SHARED WITH MAKEFILE // SHARED WITH MAKEFILE
#define FLASH_START 0x0C000000 #define FLASH_START 0x0C000000

View File

@ -11,6 +11,7 @@
#define IMAGE_CHUNK_SIZE (64 * 1024) #define IMAGE_CHUNK_SIZE (64 * 1024)
#define IMAGE_HASH_SHA256 #define IMAGE_HASH_SHA256
#define CODE_ALIGNMENT 0x200
// SHARED WITH MAKEFILE // SHARED WITH MAKEFILE
#define FLASH_START 0x08000000 #define FLASH_START 0x08000000

View File

@ -23,6 +23,7 @@
#define IMAGE_CHUNK_SIZE (128 * 1024) #define IMAGE_CHUNK_SIZE (128 * 1024)
#define IMAGE_HASH_BLAKE2S #define IMAGE_HASH_BLAKE2S
#define BOARD_CAPABILITIES_ADDR 0x0800BF00 #define BOARD_CAPABILITIES_ADDR 0x0800BF00
#define CODE_ALIGNMENT 0x200
// SHARED WITH MAKEFILE // SHARED WITH MAKEFILE
#define FLASH_START 0x08000000 #define FLASH_START 0x08000000

View File

@ -23,6 +23,7 @@
#define IMAGE_CHUNK_SIZE (128 * 1024) #define IMAGE_CHUNK_SIZE (128 * 1024)
#define IMAGE_HASH_BLAKE2S #define IMAGE_HASH_BLAKE2S
#define BOARD_CAPABILITIES_ADDR 0x0800BF00 #define BOARD_CAPABILITIES_ADDR 0x0800BF00
#define CODE_ALIGNMENT 0x200
// SHARED WITH MAKEFILE // SHARED WITH MAKEFILE
#define FLASH_START 0x08000000 #define FLASH_START 0x08000000

View File

@ -24,6 +24,7 @@
#define IMAGE_CHUNK_SIZE (128 * 1024) #define IMAGE_CHUNK_SIZE (128 * 1024)
#define IMAGE_HASH_SHA256 #define IMAGE_HASH_SHA256
#define BOARD_CAPABILITIES_ADDR 0x0C00FF00 #define BOARD_CAPABILITIES_ADDR 0x0C00FF00
#define CODE_ALIGNMENT 0x200
// SHARED WITH MAKEFILE // SHARED WITH MAKEFILE
#define FLASH_START 0x0C000000 #define FLASH_START 0x0C000000

View File

@ -24,6 +24,7 @@
#define IMAGE_CHUNK_SIZE (128 * 1024) #define IMAGE_CHUNK_SIZE (128 * 1024)
#define IMAGE_HASH_SHA256 #define IMAGE_HASH_SHA256
#define BOARD_CAPABILITIES_ADDR 0x0C00FF00 #define BOARD_CAPABILITIES_ADDR 0x0C00FF00
#define CODE_ALIGNMENT 0x200
// SHARED WITH MAKEFILE // SHARED WITH MAKEFILE
#define FLASH_START 0x0C000000 #define FLASH_START 0x0C000000

View File

@ -59,7 +59,7 @@ SECTIONS {
KEEP(*(.header)); KEEP(*(.header));
} >FLASH AT>FLASH } >FLASH AT>FLASH
.flash : ALIGN(512) { .flash : ALIGN(1024) {
KEEP(*(.vector_table)); KEEP(*(.vector_table));
. = ALIGN(4); . = ALIGN(4);
*(.text*); *(.text*);

View File

@ -60,7 +60,7 @@ SECTIONS {
KEEP(*(.header)); KEEP(*(.header));
} >FLASH AT>FLASH } >FLASH AT>FLASH
.flash : ALIGN(512) { .flash : ALIGN(1024) {
KEEP(*(.vector_table)); KEEP(*(.vector_table));
. = ALIGN(4); . = ALIGN(4);
*(.text*); *(.text*);

View File

@ -22,7 +22,8 @@ __attribute__((noreturn)) static void _reboot_to_bootloader(
__attribute__((noreturn)) static void _reboot_to_bootloader( __attribute__((noreturn)) static void _reboot_to_bootloader(
boot_command_t boot_command) { boot_command_t boot_command) {
mpu_config_bootloader(); mpu_config_bootloader();
jump_to_with_flag(BOOTLOADER_START + IMAGE_HEADER_SIZE, boot_command); jump_to_with_flag(IMAGE_CODE_ALIGN(BOOTLOADER_START + IMAGE_HEADER_SIZE),
boot_command);
for (;;) for (;;)
; ;
} }

View File

@ -103,19 +103,32 @@ class FirmwareImage(Struct):
Consists of firmware header and code block. Consists of firmware header and code block.
This is the expected format of firmware binaries for Trezor One, or bootloader images This is the expected format of firmware binaries for Trezor One, or bootloader images
for Trezor T.""" for Trezor core models."""
header: FirmwareHeader = subcon(FirmwareHeader) header: FirmwareHeader = subcon(FirmwareHeader)
_header_end: int
_code_offset: int _code_offset: int
code: bytes code: bytes
SUBCON = c.Struct( SUBCON = c.Struct(
"header" / FirmwareHeader.SUBCON, "header" / FirmwareHeader.SUBCON,
"_header_end" / c.Tell,
"padding"
/ c.Padding(
lambda this: FirmwareImage.calc_padding(
this.header.hw_model, this._header_end
)
),
"_code_offset" / c.Tell, "_code_offset" / c.Tell,
"code" / c.Bytes(c.this.header.code_length), "code" / c.Bytes(c.this.header.code_length),
c.Terminated, c.Terminated,
) )
@staticmethod
def calc_padding(hw_model: bytes, len: int) -> int:
alignment = Model.from_hw_model(hw_model).code_alignment()
return ((len + alignment - 1) & ~(alignment - 1)) - len
def get_hash_params(self) -> "util.FirmwareHashParameters": def get_hash_params(self) -> "util.FirmwareHashParameters":
return Model.from_hw_model(self.header.hw_model).hash_params() return Model.from_hw_model(self.header.hw_model).hash_params()
@ -167,7 +180,7 @@ class FirmwareImage(Struct):
class VendorFirmware(Struct): class VendorFirmware(Struct):
"""Firmware image prefixed by a vendor header. """Firmware image prefixed by a vendor header.
This is the expected format of firmware binaries for Trezor T.""" This is the expected format of firmware binaries for Trezor core models."""
vendor_header: VendorHeader = subcon(VendorHeader) vendor_header: VendorHeader = subcon(VendorHeader)
firmware: FirmwareImage = subcon(FirmwareImage) firmware: FirmwareImage = subcon(FirmwareImage)

View File

@ -65,6 +65,9 @@ class Model(Enum):
def hash_params(self) -> "FirmwareHashParameters": def hash_params(self) -> "FirmwareHashParameters":
return MODEL_HASH_PARAMS_MAP[self] return MODEL_HASH_PARAMS_MAP[self]
def code_alignment(self) -> int:
return MODEL_CODE_ALIGNMENT_MAP[self]
@dataclass @dataclass
class ModelKeys: class ModelKeys:
@ -331,6 +334,17 @@ MODEL_HASH_PARAMS_MAP = {
Model.D002: D002_HASH_PARAMS, Model.D002: D002_HASH_PARAMS,
} }
MODEL_CODE_ALIGNMENT_MAP = {
Model.T1B1: 0x200,
Model.T2T1: 0x200,
Model.T2B1: 0x200,
Model.T3T1: 0x200,
Model.T3B1: 0x200,
Model.D001: 0x200,
Model.D002: 0x400,
}
# aliases # aliases
TREZOR_ONE_V1V2 = LEGACY_V1V2 TREZOR_ONE_V1V2 = LEGACY_V1V2