From 7ddfdf69d6eba6c6c576d6cb1e09b93407974ae3 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Thu, 26 Oct 2017 19:09:53 +0200 Subject: [PATCH] trezorhal: support for non-continous areas in check_image_contents --- embed/boardloader/main.c | 5 ++++- embed/bootloader/main.c | 17 ++++++++++++++++- embed/trezorhal/flash.c | 6 ++---- embed/trezorhal/flash.h | 4 ++++ embed/trezorhal/image.c | 14 ++++++++++---- embed/trezorhal/image.h | 2 +- 6 files changed, 37 insertions(+), 11 deletions(-) diff --git a/embed/boardloader/main.c b/embed/boardloader/main.c index f6980e520a..e6cbe90494 100644 --- a/embed/boardloader/main.c +++ b/embed/boardloader/main.c @@ -182,8 +182,11 @@ int main(void) load_image_header((const uint8_t *)BOOTLOADER_START, BOOTLOADER_IMAGE_MAGIC, BOOTLOADER_IMAGE_MAXSIZE, BOARDLOADER_KEY_M, BOARDLOADER_KEY_N, BOARDLOADER_KEYS, &hdr), "invalid bootloader header"); + uint8_t sectors[] = { + FLASH_SECTOR_BOOTLOADER, + }; ensure( - check_image_contents(&hdr, (const uint8_t *)BOOTLOADER_START, IMAGE_HEADER_SIZE, 1), + check_image_contents(&hdr, IMAGE_HEADER_SIZE, sectors, 1), "invalid bootloader hash"); jump_to(BOOTLOADER_START + IMAGE_HEADER_SIZE); diff --git a/embed/bootloader/main.c b/embed/bootloader/main.c index b316a182d6..95741e1d16 100644 --- a/embed/bootloader/main.c +++ b/embed/bootloader/main.c @@ -327,8 +327,23 @@ int main(void) load_image_header((const uint8_t *)(FIRMWARE_START + vhdr.hdrlen), FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE, vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr), "invalid firmware header"); + uint8_t sectors[] = { + FLASH_SECTOR_FIRMWARE_START, + 7, + 8, + 9, + 10, + FLASH_SECTOR_FIRMWARE_END, + FLASH_SECTOR_FIRMWARE_EXTRA_START, + 18, + 19, + 20, + 21, + 22, + FLASH_SECTOR_FIRMWARE_EXTRA_END, + }; ensure( - check_image_contents(&hdr, (const uint8_t *)FIRMWARE_START, IMAGE_HEADER_SIZE + vhdr.hdrlen, 6), + check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, sectors, 13), "invalid firmware hash"); display_vendor(vhdr.vimg, (const char *)vhdr.vstr, vhdr.vstr_len, hdr.version); diff --git a/embed/trezorhal/flash.c b/embed/trezorhal/flash.c index 8316a1ca9c..d59ce77d2d 100644 --- a/embed/trezorhal/flash.c +++ b/embed/trezorhal/flash.c @@ -5,9 +5,7 @@ // see docs/memory.md for more information -#define SECTOR_COUNT 24 - -static const uint32_t SECTOR_TABLE[SECTOR_COUNT + 1] = { +const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1] = { [ 0] = 0x08000000, // - 0x08003FFF | 16 KiB [ 1] = 0x08004000, // - 0x08007FFF | 16 KiB [ 2] = 0x08008000, // - 0x0800BFFF | 16 KiB @@ -68,7 +66,7 @@ bool flash_erase_sectors(const uint8_t *sectors, int len, void (*progress)(int p return false; } // check whether the sector was really deleted (contains only 0xFF) - uint32_t addr_start = SECTOR_TABLE[sectors[i]], addr_end = SECTOR_TABLE[sectors[i] + 1]; + uint32_t addr_start = FLASH_SECTOR_TABLE[sectors[i]], addr_end = FLASH_SECTOR_TABLE[sectors[i] + 1]; for (uint32_t addr = addr_start; addr < addr_end; addr += 4) { if (*((const uint32_t *)addr) != 0xFFFFFFFF) { return false; diff --git a/embed/trezorhal/flash.h b/embed/trezorhal/flash.h index 14a5b93460..6b97bef0b8 100644 --- a/embed/trezorhal/flash.h +++ b/embed/trezorhal/flash.h @@ -38,6 +38,10 @@ // 22 #define FLASH_SECTOR_FIRMWARE_EXTRA_END 23 +#define FLASH_SECTOR_COUNT 24 + +extern const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1]; + void flash_set_option_bytes(void); bool flash_unlock(void); diff --git a/embed/trezorhal/image.c b/embed/trezorhal/image.c index 04201908ce..7e310ab121 100644 --- a/embed/trezorhal/image.c +++ b/embed/trezorhal/image.c @@ -4,6 +4,7 @@ #include "ed25519-donna/ed25519.h" #include "common.h" +#include "flash.h" #include "image.h" static bool compute_pubkey(uint8_t sig_m, uint8_t sig_n, const uint8_t * const *pub, uint8_t sigmask, ed25519_public_key res) @@ -138,19 +139,24 @@ static bool check_hash(const uint8_t * const hash, const uint8_t * const data, i #define MIN(a,b) ((a) < (b) ? (a) : (b)) -bool check_image_contents(const image_header * const hdr, const uint8_t * const data, uint32_t firstskip, int maxblocks) +bool check_image_contents(const image_header * const hdr, uint32_t firstskip, const uint8_t *sectors, int blocks) { + if (!sectors || blocks < 1) { + return false; + } + const void *data = (const void *)(FLASH_SECTOR_TABLE[sectors[0]] + firstskip); int remaining = hdr->codelen; - if (!check_hash(hdr->hashes, data + firstskip, MIN(remaining, IMAGE_CHUNK_SIZE - firstskip))) { + if (!check_hash(hdr->hashes, data, MIN(remaining, IMAGE_CHUNK_SIZE - firstskip))) { return false; } int block = 1; remaining -= IMAGE_CHUNK_SIZE - firstskip; while (remaining > 0) { - if (block >= maxblocks) { + if (block >= blocks) { return false; } - if (!check_hash(hdr->hashes + block * 32, data + block * IMAGE_CHUNK_SIZE, MIN(remaining, IMAGE_CHUNK_SIZE))) { + data = (const void *)FLASH_SECTOR_TABLE[sectors[block]]; + if (!check_hash(hdr->hashes + block * 32, data, MIN(remaining, IMAGE_CHUNK_SIZE))) { return false; } block++; diff --git a/embed/trezorhal/image.h b/embed/trezorhal/image.h index 3cd57f0937..ca9da002d9 100644 --- a/embed/trezorhal/image.h +++ b/embed/trezorhal/image.h @@ -48,6 +48,6 @@ bool load_image_header(const uint8_t * const data, const uint32_t magic, const u bool load_vendor_header(const uint8_t * const data, uint8_t key_m, uint8_t key_n, const uint8_t * const *keys, vendor_header * const vhdr); -bool check_image_contents(const image_header * const hdr, const uint8_t * const data, uint32_t firstskip, int maxblocks); +bool check_image_contents(const image_header * const hdr, uint32_t firstskip, const uint8_t *sectors, int blocks); #endif