diff --git a/docs/bootloader.md b/docs/bootloader.md index c186265ac5..67047d36cd 100644 --- a/docs/bootloader.md +++ b/docs/bootloader.md @@ -79,7 +79,11 @@ Total length of bootloader header is always 1024 bytes. | 0x0011 | 1 | vminor | version (minor) | | 0x0012 | 1 | vpatch | version (patch) | | 0x0013 | 1 | vbuild | version (build) | -| 0x0014 | 12 | reserved | not used yet (zeroed) | +| 0x0014 | 1 | fix_vmajor | version of last critical bugfix (major) | +| 0x0015 | 1 | fix_vminor | version of last critical bugfix (minor) | +| 0x0016 | 1 | fix_vpatch | version of last critical bugfix (patch) | +| 0x0017 | 1 | fix_vbuild | version of last critical bugfix (build) | +| 0x0018 | 8 | reserved | not used yet (zeroed) | | 0x0020 | 32 | hash1 | hash of the first code chunk (128 - 1 KiB), this excludes the header | | 0x0040 | 32 | hash2 | hash of the second code chunk (128 KiB), zeroed if unused | | ... | ... | ... | ... | @@ -152,7 +156,11 @@ Total length of firmware header is always 1024 bytes. | 0x0011 | 1 | vminor | version (minor) | | 0x0012 | 1 | vpatch | version (patch) | | 0x0013 | 1 | vbuild | version (build) | -| 0x0014 | 12 | reserved | not used yet (zeroed) | +| 0x0014 | 1 | fix_vmajor | version of last critical bugfix (major) | +| 0x0015 | 1 | fix_vminor | version of last critical bugfix (minor) | +| 0x0016 | 1 | fix_vpatch | version of last critical bugfix (patch) | +| 0x0017 | 1 | fix_vbuild | version of last critical bugfix (build) | +| 0x0018 | 8 | reserved | not used yet (zeroed) | | 0x0020 | 32 | hash1 | hash of the first code chunk (128 - 1 KiB), this excludes the header | | 0x0040 | 32 | hash2 | hash of the second code chunk (128 KiB), zeroed if unused | | ... | ... | ... | ... | diff --git a/embed/bootloader/header.S b/embed/bootloader/header.S index 60a1e121ce..3e3849a670 100644 --- a/embed/bootloader/header.S +++ b/embed/bootloader/header.S @@ -16,7 +16,11 @@ g_header: .byte VERSION_MINOR // vminor .byte VERSION_PATCH // vpatch .byte VERSION_BUILD // vbuild - . = . + 12 // reserved + .byte FIX_VERSION_MAJOR // fix_vmajor + .byte FIX_VERSION_MINOR // fix_vminor + .byte FIX_VERSION_PATCH // fix_vpatch + .byte FIX_VERSION_BUILD // fix_vbuild + . = . + 8 // reserved . = . + 512 // hash1 ... hash16 . = . + 415 // reserved .byte 0 // sigmask diff --git a/embed/bootloader/version.h b/embed/bootloader/version.h index c30364eada..2279c0cc06 100644 --- a/embed/bootloader/version.h +++ b/embed/bootloader/version.h @@ -3,4 +3,9 @@ #define VERSION_PATCH 0 #define VERSION_BUILD 0 +#define FIX_VERSION_MAJOR 0 +#define FIX_VERSION_MINOR 1 +#define FIX_VERSION_PATCH 0 +#define FIX_VERSION_BUILD 0 + #define VERSION_MONOTONIC 1 diff --git a/embed/firmware/header.S b/embed/firmware/header.S index 5f30398692..18a2bdaa4f 100644 --- a/embed/firmware/header.S +++ b/embed/firmware/header.S @@ -16,7 +16,11 @@ g_header: .byte VERSION_MINOR // vminor .byte VERSION_PATCH // vpatch .byte VERSION_BUILD // vbuild - . = . + 12 // reserved + .byte FIX_VERSION_MAJOR // fix_vmajor + .byte FIX_VERSION_MINOR // fix_vminor + .byte FIX_VERSION_PATCH // fix_vpatch + .byte FIX_VERSION_BUILD // fix_vbuild + . = . + 8 // reserved . = . + 512 // hash1 ... hash16 . = . + 415 // reserved .byte 0 // sigmask diff --git a/embed/firmware/version.h b/embed/firmware/version.h index a62341fe92..f5eeee876a 100644 --- a/embed/firmware/version.h +++ b/embed/firmware/version.h @@ -2,3 +2,8 @@ #define VERSION_MINOR 1 #define VERSION_PATCH 0 #define VERSION_BUILD 0 + +#define FIX_VERSION_MAJOR 0 +#define FIX_VERSION_MINOR 1 +#define FIX_VERSION_PATCH 0 +#define FIX_VERSION_BUILD 0 diff --git a/embed/prodtest/header.S b/embed/prodtest/header.S index 5f30398692..18a2bdaa4f 100644 --- a/embed/prodtest/header.S +++ b/embed/prodtest/header.S @@ -16,7 +16,11 @@ g_header: .byte VERSION_MINOR // vminor .byte VERSION_PATCH // vpatch .byte VERSION_BUILD // vbuild - . = . + 12 // reserved + .byte FIX_VERSION_MAJOR // fix_vmajor + .byte FIX_VERSION_MINOR // fix_vminor + .byte FIX_VERSION_PATCH // fix_vpatch + .byte FIX_VERSION_BUILD // fix_vbuild + . = . + 8 // reserved . = . + 512 // hash1 ... hash16 . = . + 415 // reserved .byte 0 // sigmask diff --git a/embed/prodtest/version.h b/embed/prodtest/version.h index a62341fe92..f5eeee876a 100644 --- a/embed/prodtest/version.h +++ b/embed/prodtest/version.h @@ -2,3 +2,8 @@ #define VERSION_MINOR 1 #define VERSION_PATCH 0 #define VERSION_BUILD 0 + +#define FIX_VERSION_MAJOR 0 +#define FIX_VERSION_MINOR 1 +#define FIX_VERSION_PATCH 0 +#define FIX_VERSION_BUILD 0 diff --git a/embed/reflash/header.S b/embed/reflash/header.S index 5f30398692..18a2bdaa4f 100644 --- a/embed/reflash/header.S +++ b/embed/reflash/header.S @@ -16,7 +16,11 @@ g_header: .byte VERSION_MINOR // vminor .byte VERSION_PATCH // vpatch .byte VERSION_BUILD // vbuild - . = . + 12 // reserved + .byte FIX_VERSION_MAJOR // fix_vmajor + .byte FIX_VERSION_MINOR // fix_vminor + .byte FIX_VERSION_PATCH // fix_vpatch + .byte FIX_VERSION_BUILD // fix_vbuild + . = . + 8 // reserved . = . + 512 // hash1 ... hash16 . = . + 415 // reserved .byte 0 // sigmask diff --git a/embed/reflash/version.h b/embed/reflash/version.h index a62341fe92..f5eeee876a 100644 --- a/embed/reflash/version.h +++ b/embed/reflash/version.h @@ -2,3 +2,8 @@ #define VERSION_MINOR 1 #define VERSION_PATCH 0 #define VERSION_BUILD 0 + +#define FIX_VERSION_MAJOR 0 +#define FIX_VERSION_MINOR 1 +#define FIX_VERSION_PATCH 0 +#define FIX_VERSION_BUILD 0 diff --git a/embed/trezorhal/image.c b/embed/trezorhal/image.c index 97824f352b..c689bda7dc 100644 --- a/embed/trezorhal/image.c +++ b/embed/trezorhal/image.c @@ -49,6 +49,7 @@ secbool load_image_header(const uint8_t * const data, const uint32_t magic, cons if ((hdr->hdrlen + hdr->codelen) % 512 != 0) return secfalse; memcpy(&hdr->version, data + 16, 4); + memcpy(&hdr->fix_version, data + 20, 4); memcpy(hdr->hashes, data + 32, 512); diff --git a/embed/trezorhal/image.h b/embed/trezorhal/image.h index be583d55a0..8f95b212a2 100644 --- a/embed/trezorhal/image.h +++ b/embed/trezorhal/image.h @@ -25,7 +25,8 @@ typedef struct { uint32_t expiry; uint32_t codelen; uint32_t version; - // uint8_t reserved[12]; + uint32_t fix_version; + // uint8_t reserved[8]; uint8_t hashes[512]; // uint8_t reserved[415]; uint8_t sigmask; diff --git a/tools/binctl b/tools/binctl index 6bd6780e95..6a56a3cf41 100755 --- a/tools/binctl +++ b/tools/binctl @@ -26,7 +26,7 @@ IMAGE_CHUNK_SIZE = 128 * 1024 class BinImage(object): def __init__(self, data, magic, max_size): - header = struct.unpack('<4sIIIBBBB12s512s415sB64s', data[:IMAGE_HEADER_SIZE]) + header = struct.unpack('<4sIIIBBBBBBBB8s512s415sB64s', data[:IMAGE_HEADER_SIZE]) self.magic, \ self.hdrlen, \ self.expiry, \ @@ -35,6 +35,10 @@ class BinImage(object): self.vminor, \ self.vpatch, \ self.vbuild, \ + self.fix_vmajor, \ + self.fix_vminor, \ + self.fix_vpatch, \ + self.fix_vbuild, \ self.reserved1, \ self.hashes, \ self.reserved2, \ @@ -46,7 +50,7 @@ class BinImage(object): assert total_len % 512 == 0 assert total_len >= 4 * 1024 assert total_len <= max_size - assert self.reserved1 == 12 * b'\x00' + assert self.reserved1 == 8 * b'\x00' assert self.reserved2 == 415 * b'\x00' self.code = data[self.hdrlen:] assert len(self.code) == self.codelen @@ -66,6 +70,7 @@ class BinImage(object): print(' * expiry :', self.expiry) print(' * codelen :', self.codelen) print(' * version : %d.%d.%d.%d' % (self.vmajor, self.vminor, self.vpatch, self.vbuild)) + print(' * fixver : %d.%d.%d.%d' % (self.fix_vmajor, self.fix_vminor, self.fix_vpatch, self.fix_vbuild)) print(' * hashes: %s' % ('OK' if self.check_hashes() else 'INCORRECT')) for i in range(16): print(' - %02d : %s' % (i, binascii.hexlify(self.hashes[i * 32:i * 32 + 32]).decode())) @@ -101,9 +106,10 @@ class BinImage(object): self.hashes = self.compute_hashes() def serialize_header(self, sig=True): - header = struct.pack('<4sIIIBBBB12s512s415s', + header = struct.pack('<4sIIIBBBBBBBB8s512s415s', self.magic, self.hdrlen, self.expiry, self.codelen, self.vmajor, self.vminor, self.vpatch, self.vbuild, + self.fix_vmajor, self.fix_vminor, self.fix_vpatch, self.fix_vbuild, self.reserved1, self.hashes, self.reserved2) if sig: header += struct.pack('