Skip to content

Commit aa979aa

Browse files
committed
fixup! refactor(core): update bootloader from coreapp, using syscalls (and smcalls)
1 parent 35c37af commit aa979aa

File tree

11 files changed

+101
-39
lines changed

11 files changed

+101
-39
lines changed

core/embed/projects/firmware/main.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,25 @@
4141
#include <util/rsod.h>
4242
#include "rust_ui_common.h"
4343

44+
#include <blake2s.h>
45+
4446
#ifdef USE_SECP256K1_ZKP
4547
#include "zkp_context.h"
4648
#endif
4749

50+
#define CONCAT_NAME_HELPER(prefix, name, suffix) prefix##name##suffix
51+
#define CONCAT_NAME(name, var) CONCAT_NAME_HELPER(BOOTLOADER_, name, var)
52+
53+
#if BOOTLOADER_QA
54+
// QA bootloaders
55+
#define BOOTLOADER_00 CONCAT_NAME(MODEL_INTERNAL_NAME_TOKEN, _QA_00)
56+
#define BOOTLOADER_FF CONCAT_NAME(MODEL_INTERNAL_NAME_TOKEN, _QA_FF)
57+
#else
58+
// normal bootloaders
59+
#define BOOTLOADER_00 CONCAT_NAME(MODEL_INTERNAL_NAME_TOKEN, _00)
60+
#define BOOTLOADER_FF CONCAT_NAME(MODEL_INTERNAL_NAME_TOKEN, _FF)
61+
#endif
62+
4863
// symbols from bootloader.bin => bootloader.o
4964
extern const void _deflated_bootloader_start;
5065
extern const void _deflated_bootloader_size;
@@ -75,8 +90,12 @@ int main_func(uint32_t cmd, void *arg) {
7590
const uint8_t *data = (const uint8_t *)&_deflated_bootloader_start;
7691
const size_t len = (size_t)&_deflated_bootloader_size;
7792

93+
uint8_t hash_00[] = BOOTLOADER_00;
94+
uint8_t hash_FF[] = BOOTLOADER_FF;
95+
7896
// Check if the boardloader is valid and replace it if not
79-
bool bl_update_required = bl_check_check();
97+
bool bl_update_required =
98+
bl_check_check(hash_00, hash_FF, BLAKE2S_DIGEST_LENGTH);
8099
update_required |= bl_update_required;
81100

82101
#endif

core/embed/sys/smcall/stm32/smcall_dispatch.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,10 @@ __attribute((no_stack_protector)) void smcall_handler(uint32_t *args,
7171
} break;
7272

7373
case SMCALL_BL_CHECK_CHECK: {
74-
args[0] = bl_check_check();
74+
const uint8_t *hash_00 = (const uint8_t *)args[0];
75+
const uint8_t *hash_FF = (const uint8_t *)args[1];
76+
size_t hash_len = args[2];
77+
args[0] = bl_check_check__verified(hash_00, hash_FF, hash_len);
7578
} break;
7679

7780
case SMCALL_BL_CHECK_REPLACE: {

core/embed/sys/smcall/stm32/smcall_stubs.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ void bootargs_get_args(boot_args_t *args) {
3939
// bl_check.h
4040
// =============================================================================
4141

42-
bool bl_check_check(void) {
43-
return (bool)smcall_invoke0(SMCALL_BL_CHECK_CHECK);
42+
bool bl_check_check(const uint8_t *hash_00, const uint8_t *hash_FF,
43+
size_t hash_len) {
44+
return (bool)smcall_invoke3((uint32_t)hash_00, (uint32_t)hash_FF,
45+
(uint32_t)hash_len, SMCALL_BL_CHECK_CHECK);
4446
}
4547

4648
void bl_check_replace(const uint8_t *data, size_t len) {

core/embed/sys/smcall/stm32/smcall_verifiers.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,23 @@ void bootargs_get_args__verified(boot_args_t *args) {
6060

6161
// ---------------------------------------------------------------------
6262

63+
bool bl_check_check__verified(const uint8_t *hash_00, const uint8_t *hash_FF,
64+
size_t hash_len) {
65+
if (!probe_read_access(hash_00, hash_len)) {
66+
goto access_violation;
67+
}
68+
69+
if (!probe_read_access(hash_FF, hash_len)) {
70+
goto access_violation;
71+
}
72+
73+
return bl_check_check(hash_00, hash_FF, hash_len);
74+
75+
access_violation:
76+
apptask_access_violation();
77+
return false;
78+
}
79+
6380
void bl_check_replace__verified(const uint8_t *data, size_t len) {
6481
if (!probe_read_access(data, len)) {
6582
goto access_violation;

core/embed/sys/smcall/stm32/smcall_verifiers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ void bootargs_get_args__verified(boot_args_t *args);
3333

3434
#include <util/bl_check.h>
3535

36+
bool bl_check_check__verified(const uint8_t *hash_00, const uint8_t *hash_FF,
37+
size_t hash_len);
38+
3639
void bl_check_replace__verified(const uint8_t *data, size_t len);
3740

3841
// ---------------------------------------------------------------------

core/embed/sys/syscall/stm32/syscall_dispatch.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,10 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
171171
} break;
172172

173173
case SYSCALL_BL_CHECK_CHECK: {
174-
args[0] = bl_check_check();
174+
const uint8_t *hash_00 = (const uint8_t *)args[0];
175+
const uint8_t *hash_FF = (const uint8_t *)args[1];
176+
size_t hash_len = args[2];
177+
args[0] = bl_check_check__verified(hash_00, hash_FF, hash_len);
175178
} break;
176179

177180
case SYSCALL_BL_CHECK_REPLACE: {

core/embed/sys/syscall/stm32/syscall_stubs.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,10 @@ void sysevents_poll(const sysevents_t *awaited, sysevents_t *signalled,
8888
// bl_check.h
8989
// =============================================================================
9090

91-
bool bl_check_check(void) {
92-
return (bool)syscall_invoke0(SYSCALL_BL_CHECK_CHECK);
91+
bool bl_check_check(const uint8_t *hash_00, const uint8_t *hash_FF,
92+
size_t hash_len) {
93+
return (bool)syscall_invoke3((uint32_t)hash_00, (uint32_t)hash_FF,
94+
(uint32_t)hash_len, SYSCALL_BL_CHECK_CHECK);
9395
}
9496

9597
void bl_check_replace(const uint8_t *data, size_t len) {

core/embed/sys/syscall/stm32/syscall_verifiers.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,23 @@ void sysevents_poll__verified(const sysevents_t *awaited,
6464

6565
// ---------------------------------------------------------------------
6666

67+
bool bl_check_check__verified(const uint8_t *hash_00, const uint8_t *hash_FF,
68+
size_t hash_len) {
69+
if (!probe_read_access(hash_00, hash_len)) {
70+
goto access_violation;
71+
}
72+
73+
if (!probe_read_access(hash_FF, hash_len)) {
74+
goto access_violation;
75+
}
76+
77+
return bl_check_check(hash_00, hash_FF, hash_len);
78+
79+
access_violation:
80+
apptask_access_violation();
81+
return false;
82+
};
83+
6784
void bl_check_replace__verified(const uint8_t *data, size_t len) {
6885
if (!probe_read_access(data, len)) {
6986
goto access_violation;

core/embed/sys/syscall/stm32/syscall_verifiers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ void reboot_and_upgrade__verified(const uint8_t hash[32]);
4646

4747
// ---------------------------------------------------------------------
4848

49+
bool bl_check_check__verified(const uint8_t *hash_00, const uint8_t *hash_FF,
50+
size_t hash_len);
51+
4952
#include <util/bl_check.h>
5053
void bl_check_replace__verified(const uint8_t *data, size_t len);
5154

core/embed/util/bl_check/bl_check.c

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,10 @@
3030
#include "memzero.h"
3131
#include "uzlib.h"
3232

33-
#define CONCAT_NAME_HELPER(prefix, name, suffix) prefix##name##suffix
34-
#define CONCAT_NAME(name, var) CONCAT_NAME_HELPER(BOOTLOADER_, name, var)
35-
36-
#if BOOTLOADER_QA
37-
// QA bootloaders
38-
#define BOOTLOADER_00 CONCAT_NAME(MODEL_INTERNAL_NAME_TOKEN, _QA_00)
39-
#define BOOTLOADER_FF CONCAT_NAME(MODEL_INTERNAL_NAME_TOKEN, _QA_FF)
40-
#else
41-
// normal bootloaders
42-
#define BOOTLOADER_00 CONCAT_NAME(MODEL_INTERNAL_NAME_TOKEN, _00)
43-
#define BOOTLOADER_FF CONCAT_NAME(MODEL_INTERNAL_NAME_TOKEN, _FF)
44-
#endif
45-
// clang-format on
46-
47-
static secbool latest_bootloader(const uint8_t *hash, int len) {
48-
if (len != 32) return secfalse;
49-
50-
uint8_t hash_00[] = BOOTLOADER_00;
51-
uint8_t hash_FF[] = BOOTLOADER_FF;
52-
53-
if (0 == memcmp(hash, hash_00, 32)) return sectrue;
54-
if (0 == memcmp(hash, hash_FF, 32)) return sectrue;
33+
static secbool hash_match(const uint8_t *hash, const uint8_t *hash_00,
34+
const uint8_t *hash_FF) {
35+
if (0 == memcmp(hash, hash_00, BLAKE2S_DIGEST_LENGTH)) return sectrue;
36+
if (0 == memcmp(hash, hash_FF, BLAKE2S_DIGEST_LENGTH)) return sectrue;
5537
return secfalse;
5638
}
5739

@@ -78,9 +60,14 @@ static void uzlib_prepare(struct uzlib_uncomp *decomp, uint8_t *window,
7860
uzlib_uncompress_init(decomp, window, window ? UZLIB_WINDOW_SIZE : 0);
7961
}
8062

81-
bool bl_check_check(void) {
63+
bool bl_check_check(const uint8_t *hash_00, const uint8_t *hash_FF,
64+
size_t hash_len) {
8265
mpu_mode_t mode = mpu_reconfig(MPU_MODE_BOOTUPDATE);
8366

67+
if (hash_len != BLAKE2S_DIGEST_LENGTH) {
68+
error_shutdown("Invalid bootloader hash length");
69+
}
70+
8471
// compute current bootloader hash
8572
uint8_t hash[BLAKE2S_DIGEST_LENGTH];
8673
const uint32_t bl_len = flash_area_get_size(&BOOTLOADER_AREA);
@@ -91,8 +78,8 @@ bool bl_check_check(void) {
9178
// ensure(known_bootloader(hash, BLAKE2S_DIGEST_LENGTH), "Unknown bootloader
9279
// detected");
9380

94-
// do we have the latest bootloader?
95-
if (sectrue == latest_bootloader(hash, BLAKE2S_DIGEST_LENGTH)) {
81+
// does the bootloader match?
82+
if (sectrue == hash_match(hash, hash_00, hash_FF)) {
9683
mpu_reconfig(mode);
9784
return false;
9885
}

core/embed/util/bl_check/inc/util/bl_check.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,21 @@
2222
#include <trezor_types.h>
2323

2424
/**
25-
* @brief Check bootloader hash against the installed bootloader.
25+
* @brief Verify the installed bootloader against expected hashes.
2626
*
27-
* Computes the hash of the provided bootloader image and compares it
28-
* with the hash of the currently installed bootloader.
27+
* Calculates the hash of the currently installed bootloader and compares
28+
* it against two known-good expected hashes.
2929
*
30-
* @return `true` if the hashes do not match (bootloader needs replacement),
31-
* `false` otherwise.
30+
* @param hash_00 Pointer to the expected hash for 0x00 padded image.
31+
* @param hash_FF Pointer to the expected hash for 0xFF padded image.
32+
* @param hash_len Length of each hash, in bytes.
33+
*
34+
* @return `true` if the installed bootloader's hash does not match either
35+
* of the expected hashes (indicating it should be replaced),
36+
* `false` if it matches one of them.
3237
*/
33-
bool bl_check_check(void);
38+
bool bl_check_check(const uint8_t *hash_00, const uint8_t *hash_FF,
39+
size_t hash_len);
3440

3541
/**
3642
* @brief Replace the currently installed bootloader.
@@ -40,4 +46,4 @@ bool bl_check_check(void);
4046
* @param data Pointer to the bootloader image data.
4147
* @param len Size of the bootloader data in bytes.
4248
*/
43-
void bl_check_replace(const uint8_t* data, size_t len);
49+
void bl_check_replace(const uint8_t *data, size_t len);

0 commit comments

Comments
 (0)