1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-20 21:38:26 +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();
// 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;
}

View File

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

View File

@ -167,14 +167,14 @@ __attribute__((noreturn)) int main(int argc, char **argv) {
bootloader_main();
hal_delay(3000);
jump_to(NULL);
jump_to(0);
}
void mpu_config_bootloader(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 =
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_off(void);
void display_set_little_endian(void);
void jump_to(void *addr);
void jump_to(uint32_t address);
void ensure_compatible_settings(void);
#endif

View File

@ -349,7 +349,7 @@ void real_jump_to_firmware(void) {
ensure_compatible_settings();
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

View File

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

View File

@ -294,7 +294,7 @@ int main(void) {
// do not check any trust flags on header, proceed
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;
}

View File

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

View File

@ -60,7 +60,7 @@ SECTIONS {
KEEP(*(.header));
} >FLASH AT>FLASH
.flash : ALIGN(512) {
.flash : ALIGN(1024) {
KEEP(*(.vector_table));
. = ALIGN(4);
*(.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
size_t offset = firstskip;
size_t offset = IMAGE_CODE_ALIGN(firstskip);
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) {
size_t bytes_to_check = MIN(IMAGE_CHUNK_SIZE - (offset % IMAGE_CHUNK_SIZE),
end_offset - offset);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,8 @@ __attribute__((noreturn)) static void _reboot_to_bootloader(
__attribute__((noreturn)) static void _reboot_to_bootloader(
boot_command_t boot_command) {
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 (;;)
;
}

View File

@ -103,19 +103,32 @@ class FirmwareImage(Struct):
Consists of firmware header and code block.
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_end: int
_code_offset: int
code: bytes
SUBCON = c.Struct(
"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" / c.Bytes(c.this.header.code_length),
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":
return Model.from_hw_model(self.header.hw_model).hash_params()
@ -167,7 +180,7 @@ class FirmwareImage(Struct):
class VendorFirmware(Struct):
"""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)
firmware: FirmwareImage = subcon(FirmwareImage)

View File

@ -65,6 +65,9 @@ class Model(Enum):
def hash_params(self) -> "FirmwareHashParameters":
return MODEL_HASH_PARAMS_MAP[self]
def code_alignment(self) -> int:
return MODEL_CODE_ALIGNMENT_MAP[self]
@dataclass
class ModelKeys:
@ -331,6 +334,17 @@ MODEL_HASH_PARAMS_MAP = {
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
TREZOR_ONE_V1V2 = LEGACY_V1V2