1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-25 14:50:57 +00:00

bootloader: refactor to save space

This commit is contained in:
Pavol Rusnak 2019-02-21 15:18:00 +01:00
parent 07231d936e
commit 400ac96873
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
6 changed files with 31 additions and 22 deletions

View File

@ -54,9 +54,9 @@ bool get_button_response(void)
return button.YesUp; return button.YesUp;
} }
static void show_halt(void) void show_halt(const char *line1, const char *line2)
{ {
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Unofficial firmware", "aborted.", NULL, "Unplug your TREZOR,", "reinstall firmware.", NULL); layoutDialog(&bmp_icon_error, NULL, NULL, NULL, line1, line2, NULL, "Unplug your TREZOR,", "reinstall firmware.", NULL);
shutdown(); shutdown();
} }
@ -66,14 +66,14 @@ static void show_unofficial_warning(const uint8_t *hash)
bool but = get_button_response(); bool but = get_button_response();
if (!but) { // no button was pressed -> halt if (!but) { // no button was pressed -> halt
show_halt(); show_halt("Unofficial firmware", "aborted.");
} }
layoutFirmwareFingerprint(hash); layoutFirmwareFingerprint(hash);
but = get_button_response(); but = get_button_response();
if (!but) { // no button was pressed -> halt if (!but) { // no button was pressed -> halt
show_halt(); show_halt("Unofficial firmware", "aborted.");
} }
// everything is OK, user pressed 2x Continue -> continue program // everything is OK, user pressed 2x Continue -> continue program

View File

@ -34,6 +34,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
void show_halt(const char *line1, const char *line2);
void layoutFirmwareFingerprint(const uint8_t *hash); void layoutFirmwareFingerprint(const uint8_t *hash);
bool get_button_response(void); bool get_button_response(void);

View File

@ -2,10 +2,13 @@
import sys import sys
import os import os
TOTALSIZE = 32768
MAXSIZE = TOTALSIZE - 32
fn = sys.argv[1] fn = sys.argv[1]
fs = os.stat(fn).st_size fs = os.stat(fn).st_size
if fs > 32768: if fs > MAXSIZE:
raise Exception('bootloader has to be smaller than 32768 bytes') raise Exception('bootloader has to be smaller than %d bytes (current size is %d)' % (MAXSIZE, fs))
with open(fn, 'ab') as f: with open(fn, 'ab') as f:
f.write(b'\x00' * (32768 - fs)) f.write(b'\x00' * (TOTALSIZE - fs))
f.close() f.close()

View File

@ -156,6 +156,14 @@ int signatures_new_ok(const image_header *hdr, uint8_t store_fingerprint[32])
return SIG_OK; return SIG_OK;
} }
int mem_is_empty(const uint8_t *src, uint32_t len)
{
for (uint32_t i = 0; i < len; i++) {
if (src[i]) return 0;
}
return 1;
}
int check_firmware_hashes(const image_header *hdr) int check_firmware_hashes(const image_header *hdr)
{ {
uint8_t hash[32]; uint8_t hash[32];
@ -174,7 +182,7 @@ int check_firmware_hashes(const image_header *hdr)
} }
// check unused chunks // check unused chunks
for (int i = used_chunks; i < 16; i++) { for (int i = used_chunks; i < 16; i++) {
if (0 != memcmp(hdr->hashes + 32 * i, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32)) return SIG_FAIL; if (!mem_is_empty(hdr->hashes + 32 * i, 32)) return SIG_FAIL;
} }
// all OK // all OK
return SIG_OK; return SIG_OK;

View File

@ -64,4 +64,6 @@ void compute_firmware_fingerprint(const image_header *hdr, uint8_t hash[32]);
int signatures_new_ok(const image_header *hdr, uint8_t store_fingerprint[32]); int signatures_new_ok(const image_header *hdr, uint8_t store_fingerprint[32]);
int check_firmware_hashes(const image_header *hdr); int check_firmware_hashes(const image_header *hdr);
int mem_is_empty(const uint8_t *src, uint32_t len);
#endif #endif

View File

@ -85,8 +85,7 @@ static void check_and_write_chunk(void)
// erase storage // erase storage
erase_storage(); erase_storage();
flash_state = STATE_END; flash_state = STATE_END;
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Error installing ", "firmware.", NULL, "Unplug your TREZOR", "and try again.", NULL); show_halt("Error installing", "firmware.");
shutdown();
return; return;
} }
@ -104,10 +103,9 @@ static void check_and_write_chunk(void)
// check remaining chunks if any // check remaining chunks if any
for (uint32_t i = chunk_idx + 1; i < 16; i++) { for (uint32_t i = chunk_idx + 1; i < 16; i++) {
// hash should be empty if the chunk is unused // hash should be empty if the chunk is unused
if (0 != memcmp(hdr->hashes + i * 32, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32)) { if (!mem_is_empty(hdr->hashes + 32 * i, 32)) {
flash_state = STATE_END; flash_state = STATE_END;
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Error installing ", "firmware.", NULL, "Unplug your TREZOR", "and try again.", NULL); show_halt("Error installing", "firmware.");
shutdown();
return; return;
} }
} }
@ -208,8 +206,7 @@ static void rx_callback(usbd_device *dev, uint8_t ep)
if (buf[9] != 0x0a) { // invalid contents if (buf[9] != 0x0a) { // invalid contents
send_msg_failure(dev); send_msg_failure(dev);
flash_state = STATE_END; flash_state = STATE_END;
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Error installing ", "firmware.", NULL, "Unplug your TREZOR", "and try again.", NULL); show_halt("Error installing", "firmware.");
shutdown();
return; return;
} }
// read payload length // read payload length
@ -218,20 +215,20 @@ static void rx_callback(usbd_device *dev, uint8_t ep)
if (flash_len <= FLASH_FWHEADER_LEN) { // firmware is too small if (flash_len <= FLASH_FWHEADER_LEN) { // firmware is too small
send_msg_failure(dev); send_msg_failure(dev);
flash_state = STATE_END; flash_state = STATE_END;
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Firmware is too small.", NULL, "Get official firmware", "from trezor.io/start", NULL, NULL); show_halt("Firmware is too small.", NULL);
return; return;
} }
if (flash_len > FLASH_FWHEADER_LEN + FLASH_APP_LEN) { // firmware is too big if (flash_len > FLASH_FWHEADER_LEN + FLASH_APP_LEN) { // firmware is too big
send_msg_failure(dev); send_msg_failure(dev);
flash_state = STATE_END; flash_state = STATE_END;
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Firmware is too big.", NULL, "Get official firmware", "from trezor.io/start", NULL, NULL); show_halt("Firmware is too big.", NULL);
return; return;
} }
// check firmware magic // check firmware magic
if (memcmp(p, &FIRMWARE_MAGIC_NEW, 4) != 0) { if (memcmp(p, &FIRMWARE_MAGIC_NEW, 4) != 0) {
send_msg_failure(dev); send_msg_failure(dev);
flash_state = STATE_END; flash_state = STATE_END;
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Wrong firmware header.", NULL, "Get official firmware", "from trezor.io/start", NULL, NULL); show_halt("Wrong firmware header.", NULL);
return; return;
} }
memzero(FW_HEADER, sizeof(FW_HEADER)); memzero(FW_HEADER, sizeof(FW_HEADER));
@ -259,8 +256,7 @@ static void rx_callback(usbd_device *dev, uint8_t ep)
if (buf[0] != '?') { // invalid contents if (buf[0] != '?') { // invalid contents
send_msg_failure(dev); send_msg_failure(dev);
flash_state = STATE_END; flash_state = STATE_END;
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Error installing ", "firmware.", NULL, "Unplug your TREZOR", "and try again.", NULL); show_halt("Error installing", "firmware.");
shutdown();
return; return;
} }
@ -338,8 +334,7 @@ static void rx_callback(usbd_device *dev, uint8_t ep)
sha256_Raw(FLASH_PTR(FLASH_STORAGE_START), FLASH_STORAGE_LEN, hash); sha256_Raw(FLASH_PTR(FLASH_STORAGE_START), FLASH_STORAGE_LEN, hash);
if (memcmp(hash, "\x2d\x86\x4c\x0b\x78\x9a\x43\x21\x4e\xee\x85\x24\xd3\x18\x20\x75\x12\x5e\x5c\xa2\xcd\x52\x7f\x35\x82\xec\x87\xff\xd9\x40\x76\xbc", 32) != 0) { if (memcmp(hash, "\x2d\x86\x4c\x0b\x78\x9a\x43\x21\x4e\xee\x85\x24\xd3\x18\x20\x75\x12\x5e\x5c\xa2\xcd\x52\x7f\x35\x82\xec\x87\xff\xd9\x40\x76\xbc", 32) != 0) {
send_msg_failure(dev); send_msg_failure(dev);
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Error installing ", "firmware.", NULL, "Unplug your TREZOR", "and try again.", NULL); show_halt("Error installing", "firmware.");
shutdown();
return; return;
} }
} }