From 89cc35b195aba4f9707efce21475fe28bb916237 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Thu, 26 Oct 2017 18:53:20 +0200 Subject: [PATCH] trezorhal: fix hash offset in check_image_contents --- embed/boardloader/main.c | 2 +- embed/bootloader/main.c | 2 +- embed/trezorhal/image.c | 6 +++--- embed/trezorhal/image.h | 2 +- tools/binctl | 8 ++++++-- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/embed/boardloader/main.c b/embed/boardloader/main.c index ae7abc35..f6980e52 100644 --- a/embed/boardloader/main.c +++ b/embed/boardloader/main.c @@ -183,7 +183,7 @@ int main(void) "invalid bootloader header"); ensure( - check_image_contents(&hdr, (const uint8_t *)BOOTLOADER_START, 1), + check_image_contents(&hdr, (const uint8_t *)BOOTLOADER_START, IMAGE_HEADER_SIZE, 1), "invalid bootloader hash"); jump_to(BOOTLOADER_START + IMAGE_HEADER_SIZE); diff --git a/embed/bootloader/main.c b/embed/bootloader/main.c index dc1d83d1..b316a182 100644 --- a/embed/bootloader/main.c +++ b/embed/bootloader/main.c @@ -328,7 +328,7 @@ int main(void) "invalid firmware header"); ensure( - check_image_contents(&hdr, (const uint8_t *)(FIRMWARE_START + vhdr.hdrlen), 6), + check_image_contents(&hdr, (const uint8_t *)FIRMWARE_START, IMAGE_HEADER_SIZE + vhdr.hdrlen, 6), "invalid firmware hash"); display_vendor(vhdr.vimg, (const char *)vhdr.vstr, vhdr.vstr_len, hdr.version); diff --git a/embed/trezorhal/image.c b/embed/trezorhal/image.c index f5721098..04201908 100644 --- a/embed/trezorhal/image.c +++ b/embed/trezorhal/image.c @@ -138,14 +138,14 @@ 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, int maxblocks) +bool check_image_contents(const image_header * const hdr, const uint8_t * const data, uint32_t firstskip, int maxblocks) { int remaining = hdr->codelen; - if (!check_hash(hdr->hashes, data + IMAGE_HEADER_SIZE, MIN(remaining, IMAGE_CHUNK_SIZE - IMAGE_HEADER_SIZE))) { + if (!check_hash(hdr->hashes, data + firstskip, MIN(remaining, IMAGE_CHUNK_SIZE - firstskip))) { return false; } int block = 1; - remaining -= IMAGE_CHUNK_SIZE - IMAGE_HEADER_SIZE; + remaining -= IMAGE_CHUNK_SIZE - firstskip; while (remaining > 0) { if (block >= maxblocks) { return false; diff --git a/embed/trezorhal/image.h b/embed/trezorhal/image.h index 01029b56..3cd57f09 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, int maxblocks); +bool check_image_contents(const image_header * const hdr, const uint8_t * const data, uint32_t firstskip, int maxblocks); #endif diff --git a/tools/binctl b/tools/binctl index b9ebcddf..452f34e6 100755 --- a/tools/binctl +++ b/tools/binctl @@ -74,12 +74,16 @@ class BinImage(object): print() def compute_hashes(self): + if self.magic == b'TRZF': + hdrlen = self.vhdrlen + self.hdrlen + else: + hdrlen = self.hdrlen hashes = b'' for i in range(16): if i == 0: - d = self.code[:IMAGE_CHUNK_SIZE - IMAGE_HEADER_SIZE] + d = self.code[:IMAGE_CHUNK_SIZE - hdrlen] else: - s = IMAGE_CHUNK_SIZE - IMAGE_HEADER_SIZE + (i - 1) * IMAGE_CHUNK_SIZE + s = IMAGE_CHUNK_SIZE - hdrlen + (i - 1) * IMAGE_CHUNK_SIZE d = self.code[s:s + IMAGE_CHUNK_SIZE] if len(d) > 0: h = pyblake2.blake2s(d).digest()