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:
parent
03199cd553
commit
354dad617d
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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]);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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*);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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*);
|
||||||
|
@ -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*);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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*);
|
||||||
|
@ -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*);
|
||||||
|
@ -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 (;;)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user