trezorhal: increase image header size from 512 to 1024 bytes

This commit is contained in:
Pavol Rusnak 2017-10-26 02:09:06 +02:00
parent 0c6ee14ee1
commit 3c974095aa
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
6 changed files with 38 additions and 33 deletions

View File

@ -67,7 +67,7 @@ TREZOR Core (second stage) bootloader consists of 2 parts:
### Bootloader Header
Total length of bootloader header is always 512 bytes.
Total length of bootloader header is always 1024 bytes.
| offset | length | name | description |
|-------:|-------:|------|-------------|
@ -79,9 +79,9 @@ Total length of bootloader header is always 512 bytes.
| 0x0011 | 1 | vminor | version (minor) |
| 0x0012 | 1 | vpatch | version (patch) |
| 0x0013 | 1 | vbuild | version (build) |
| 0x0014 | 427 | reserved | not used yet (zeroed) |
| 0x01BF | 1 | sigmask | SatoshiLabs signature indexes (bitmap) |
| 0x01C0 | 64 | sig | SatoshiLabs aggregated signature |
| 0x0014 | 939 | reserved | not used yet (zeroed) |
| 0x03BF | 1 | sigmask | SatoshiLabs signature indexes (bitmap) |
| 0x03C0 | 64 | sig | SatoshiLabs aggregated signature |
## Firmware Format
@ -122,7 +122,7 @@ of 512 bytes.
### Firmware Header
Total length of firmware header is always 512 bytes.
Total length of firmware header is always 1024 bytes.
| offset | length | name | description |
|-------:|-------:|------|-------------|
@ -134,9 +134,10 @@ Total length of firmware header is always 512 bytes.
| 0x0011 | 1 | vminor | version (minor) |
| 0x0012 | 1 | vpatch | version (patch) |
| 0x0013 | 1 | vbuild | version (build) |
| 0x0014 | 427 | reserved | not used yet (zeroed) |
| 0x01BF | 1 | sigmask | vendor signature indexes (bitmap) |
| 0x01C0 | 64 | sig | vendor aggregated signature |
| 0x0014 | 939 | reserved | not used yet (zeroed) |
| 0x03BF | 1 | sigmask | vendor signature indexes (bitmap) |
| 0x03C0 | 64 | sig | vendor aggregated signature |
## Various ideas

View File

@ -16,7 +16,7 @@ g_header:
.byte VERSION_MINOR // vminor
.byte VERSION_PATCH // vpatch
.byte VERSION_BUILD // vbuild
. = . + 427 // reserved
. = . + 939 // reserved
.byte 0 // sigmask
. = . + 64 // sig
g_header_end:

View File

@ -16,7 +16,7 @@ g_header:
.byte VERSION_MINOR // vminor
.byte VERSION_PATCH // vpatch
.byte VERSION_BUILD // vbuild
. = . + 427 // reserved
. = . + 939 // reserved
.byte 0 // sigmask
. = . + 64 // sig
g_header_end:

View File

@ -49,11 +49,11 @@ bool image_parse_header(const uint8_t * const data, const uint32_t magic, const
memcpy(&hdr->version, data + 16, 4);
// uint8_t reserved[427];
// uint8_t reserved[939];
memcpy(&hdr->sigmask, data + 0x01BF, 1);
memcpy(&hdr->sigmask, data + IMAGE_HEADER_SIZE - IMAGE_SIG_SIZE, 1);
memcpy(hdr->sig, data + 0x01C0, 64);
memcpy(hdr->sig, data + IMAGE_HEADER_SIZE - IMAGE_SIG_SIZE + 1, IMAGE_SIG_SIZE - 1);
return true;
}
@ -63,8 +63,8 @@ bool image_check_signature(const uint8_t *data, const image_header *hdr, uint8_t
uint8_t hash[BLAKE2S_DIGEST_LENGTH];
BLAKE2S_CTX ctx;
blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH);
blake2s_Update(&ctx, data, IMAGE_HEADER_SIZE - 65);
for (int i = 0; i < 65; i++) {
blake2s_Update(&ctx, data, IMAGE_HEADER_SIZE - IMAGE_SIG_SIZE);
for (int i = 0; i < IMAGE_SIG_SIZE; i++) {
blake2s_Update(&ctx, (const uint8_t *)"\x00", 1);
}
blake2s_Update(&ctx, data + IMAGE_HEADER_SIZE, hdr->codelen);
@ -112,11 +112,11 @@ bool vendor_parse_header(const uint8_t * const data, vendor_header * const vhdr)
// align to 4 bytes
vhdr->vimg += (-(uintptr_t)vhdr->vimg) & 3;
// uint8_t reserved[427];
// reserved for padding
memcpy(&vhdr->sigmask, data + vhdr->hdrlen - 65, 1);
memcpy(&vhdr->sigmask, data + vhdr->hdrlen - IMAGE_SIG_SIZE, 1);
memcpy(vhdr->sig, data + vhdr->hdrlen - 64, 64);
memcpy(vhdr->sig, data + vhdr->hdrlen - IMAGE_SIG_SIZE + 1, IMAGE_SIG_SIZE - 1);
return true;
}
@ -126,8 +126,8 @@ bool vendor_check_signature(const uint8_t *data, const vendor_header *vhdr, uint
uint8_t hash[BLAKE2S_DIGEST_LENGTH];
BLAKE2S_CTX ctx;
blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH);
blake2s_Update(&ctx, data, vhdr->hdrlen - 65);
for (int i = 0; i < 65; i++) {
blake2s_Update(&ctx, data, vhdr->hdrlen - IMAGE_SIG_SIZE);
for (int i = 0; i < IMAGE_SIG_SIZE; i++) {
blake2s_Update(&ctx, (const uint8_t *)"\x00", 1);
}
blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH);

View File

@ -7,7 +7,8 @@
#define BOARDLOADER_START 0x08000000
#define BOOTLOADER_START 0x08020000
#define FIRMWARE_START 0x08040000
#define IMAGE_HEADER_SIZE 0x200
#define IMAGE_HEADER_SIZE 0x400
#define IMAGE_SIG_SIZE 65
typedef struct {
uint32_t magic;
@ -15,7 +16,7 @@ typedef struct {
uint32_t expiry;
uint32_t codelen;
uint32_t version;
// uint8_t reserved[427];
// uint8_t reserved[939];
uint8_t sigmask;
uint8_t sig[64];
} image_header;
@ -30,7 +31,7 @@ typedef struct {
uint8_t vsig_m;
uint8_t vsig_n;
uint8_t vtrust;
// uint8_t reserved[16];
// uint8_t reserved[15];
const uint8_t *vpub[MAX_VENDOR_PUBLIC_KEYS];
uint8_t vstr_len;
const uint8_t *vstr;

View File

@ -18,11 +18,14 @@ def format_sigmask(sigmask):
# bootloader/firmware headers specification: https://github.com/trezor/trezor-core/blob/master/docs/bootloader.md
IMAGE_HEADER_SIZE = 0x400
IMAGE_SIG_SIZE = 65
class BinImage(object):
def __init__(self, data, magic, max_size):
header = struct.unpack('<4sIIIBBBB427sB64s', data[:512])
header = struct.unpack('<4sIIIBBBB939sB64s', data[:IMAGE_HEADER_SIZE])
self.magic, \
self.hdrlen, \
self.expiry, \
@ -35,12 +38,12 @@ class BinImage(object):
self.sigmask, \
self.sig = header
assert self.magic == magic
assert self.hdrlen == 512
assert self.hdrlen == IMAGE_HEADER_SIZE
total_len = self.hdrlen + self.codelen
assert total_len % 512 == 0
assert total_len >= 4 * 1024
assert total_len <= max_size
assert self.reserved == 427 * b'\x00'
assert self.reserved == 939 * b'\x00'
self.code = data[self.hdrlen:]
assert len(self.code) == self.codelen
@ -64,14 +67,14 @@ class BinImage(object):
print()
def serialize_header(self, sig=True):
header = struct.pack('<4sIIIBBBB427s',
header = struct.pack('<4sIIIBBBB939s',
self.magic, self.hdrlen, self.expiry, self.codelen,
self.vmajor, self.vminor, self.vpatch, self.vbuild,
self.reserved)
if sig:
header += struct.pack('<B64s', self.sigmask, self.sig)
else:
header += 65 * b'\x00'
header += IMAGE_SIG_SIZE * b'\x00'
assert len(header) == self.hdrlen
return header
@ -134,7 +137,7 @@ class VendorHeader(object):
p += self.vstr_len
vstr_pad = -p & 3
p += vstr_pad
self.vimg_len = len(data) - 65 - p
self.vimg_len = len(data) - IMAGE_SIG_SIZE - p
self.vimg = data[p:p + self.vimg_len]
p += self.vimg_len
self.sigmask = data[p]
@ -144,7 +147,7 @@ class VendorHeader(object):
32 * len(self.vpub) + \
1 + self.vstr_len + vstr_pad + \
self.vimg_len + \
1 + 64
IMAGE_SIG_SIZE
def print(self):
print('TREZOR Vendor Header')
@ -176,7 +179,7 @@ class VendorHeader(object):
if sig:
header += struct.pack('<B64s', self.sigmask, self.sig)
else:
header += 65 * b'\x00'
header += IMAGE_SIG_SIZE * b'\x00'
assert len(header) == self.hdrlen
return header
@ -212,7 +215,7 @@ def binopen(filename):
pk = [vheader.vpub[i] for i in range(8) if firmware.sigmask & (1 << i)]
global_pk = ed25519cosi.combine_keys(pk)
subdata_nosig = bytearray(subdata)
subdata_nosig[512 - 65:512] = 65 * b'\x00'
subdata_nosig[IMAGE_HEADER_SIZE - IMAGE_SIG_SIZE:IMAGE_HEADER_SIZE] = IMAGE_SIG_SIZE * b'\x00'
digest = pyblake2.blake2s(subdata_nosig).digest()
try:
ed25519raw.checkvalid(firmware.sig, digest, global_pk)
@ -220,7 +223,7 @@ def binopen(filename):
except:
print('Firmware signature INCORRECT')
else:
print('No firmware signature')
print('No firmware signature')
return firmware
if magic == b'TRZF':
return FirmwareImage(data, 0)