diff --git a/Makefile b/Makefile index 82097e5c..1e8dc46a 100644 --- a/Makefile +++ b/Makefile @@ -149,11 +149,11 @@ gdb_firmware: $(FIRMWARE_BUILD_DIR)/firmware.elf ## start remote gdb session to ## misc commands: vendorheader: ## construct default vendor header - ./tools/build_vendorheader 'e28a8970753332bd72fef413e6b0b2ef1b4aadda7aa2c141f233712a6876b351:d4eec1869fb1b8a4e817516ad5a931557cb56805c3eb16e8f3a803d647df7869:772c8a442b7db06e166cfbc1ccbcbcde6f3eba76a4e98ef3ffc519502237d6ef' 2 0.0 DEVELOPMENT assets/vendor_devel.toif embed/firmware/vendorheader.bin + ./tools/build_vendorheader e28a8970753332bd72fef413e6b0b2ef1b4aadda7aa2c141f233712a6876b351:d4eec1869fb1b8a4e817516ad5a931557cb56805c3eb16e8f3a803d647df7869:772c8a442b7db06e166cfbc1ccbcbcde6f3eba76a4e98ef3ffc519502237d6ef 2 0.0 10 DEVELOPMENT assets/vendor_devel.toif embed/firmware/vendorheader.bin ./tools/binctl embed/firmware/vendorheader.bin -s 1:2 4444444444444444444444444444444444444444444444444444444444444444:4545454545454545454545454545454545454545454545454545454545454545 vendorheader_sl: ## construct SatoshiLabs vendor header - ./tools/build_vendorheader '47fbdc84d8abef44fe6abde8f87b6ead821b7082ec63b9f7cc33dc53bf6c708d:03fdd9a9c3911652d5effca4540d96ed92d85850a47d256ab0a2d728c0d1a298:2218c25f8ba70c82eba8ed6a321df209c0a7643d014f33bf9317846f62923830' 2 0.0 SatoshiLabs assets/vendor_satoshilabs.toif embed/firmware/vendorheader_sl.bin + ./tools/build_vendorheader 47fbdc84d8abef44fe6abde8f87b6ead821b7082ec63b9f7cc33dc53bf6c708d:03fdd9a9c3911652d5effca4540d96ed92d85850a47d256ab0a2d728c0d1a298:2218c25f8ba70c82eba8ed6a321df209c0a7643d014f33bf9317846f62923830 2 0.0 80 SatoshiLabs assets/vendor_satoshilabs.toif embed/firmware/vendorheader_sl.bin ./tools/binctl embed/firmware/vendorheader_sl.bin -s 1:2 trezor:trezor binctl: ## print info about binary files diff --git a/docs/bootloader.md b/docs/bootloader.md index 953026d3..6c7069ce 100644 --- a/docs/bootloader.md +++ b/docs/bootloader.md @@ -82,14 +82,16 @@ of 512 bytes. | 0x000D | 1 | vminor | version (minor) | | 0x000E | 1 | vsig_m | number of signatures needed to run the firmware from this vendor | | 0x000F | 1 | vsig_n | number of different pubkeys vendor provides for signing | -| 0x0010 | 32 | vpub1 | vendor pubkey 1 | +| 0x0010 | 1 | vtrust | level of vendor trust (0-100) | +| 0x0011 | 15 | reserved | not used yet (zeroed) | +| 0x0020 | 32 | vpub1 | vendor pubkey 1 | | ... | ... | ... | ... | | ? | 32 | vpubn | vendor pubkey n | | ? | 1 | vstr_len | vendor string length | | ? | ? | vstr | vendor string | | ? | ? | vstrpad | padding to a multiple of 4 bytes | | ? | ? | vimg | vendor image (in [TOIf format](toif.md)) | -| ? | ? | reserved | padding to an address that is -65 modulo 512 | +| ? | ? | reserved | padding to an address that is -65 modulo 512 (zeroed) | | ? | 1 | sigmask | SatoshiLabs signature indexes (bitmap) | | ? | 64 | sig | SatoshiLabs aggregated signature | diff --git a/embed/bootloader/main.c b/embed/bootloader/main.c index 89983707..814f7ec9 100644 --- a/embed/bootloader/main.c +++ b/embed/bootloader/main.c @@ -92,7 +92,11 @@ void check_and_jump(void) display_printf("valid firmware signature\n"); display_vendor(vhdr.vimg, (const char *)vhdr.vstr, vhdr.vstr_len, hdr.version); - touch_click(); + if (vhdr.vtrust < 50) { + touch_click(); + } else { + hal_delay(1000); + } jump_to(FIRMWARE_START + vhdr.hdrlen + HEADER_SIZE); } else { diff --git a/embed/trezorhal/common.c b/embed/trezorhal/common.c index 2983505b..ea21c076 100644 --- a/embed/trezorhal/common.c +++ b/embed/trezorhal/common.c @@ -71,3 +71,8 @@ void jump_to(uint32_t start) __asm__ volatile("msr msp, %0"::"g" (*(volatile uint32_t *)start)); (*(void (**)())(start + 4))(); } + +void hal_delay(uint32_t ms) +{ + HAL_Delay(ms); +} diff --git a/embed/trezorhal/common.h b/embed/trezorhal/common.h index c6888942..d51a2992 100644 --- a/embed/trezorhal/common.h +++ b/embed/trezorhal/common.h @@ -16,4 +16,6 @@ void __attribute__((noreturn)) nlr_jump_fail(void *val); void jump_to(uint32_t address); +void hal_delay(uint32_t ms); + #endif diff --git a/embed/trezorhal/image.c b/embed/trezorhal/image.c index d60342a5..5c3fda22 100644 --- a/embed/trezorhal/image.c +++ b/embed/trezorhal/image.c @@ -98,23 +98,24 @@ bool vendor_parse_header(const uint8_t *data, vendor_header *vhdr) memcpy(&vhdr->vsig_m, data + 14, 1); memcpy(&vhdr->vsig_n, data + 15, 1); + memcpy(&vhdr->vtrust, data + 16, 1); if (vhdr->vsig_n > MAX_VENDOR_PUBLIC_KEYS) { return false; } for (int i = 0; i < vhdr->vsig_n; i++) { - vhdr->vpub[i] = data + 16 + i * 32; + vhdr->vpub[i] = data + 32 + i * 32; } for (int i = vhdr->vsig_n; i < MAX_VENDOR_PUBLIC_KEYS; i++) { vhdr->vpub[i] = 0; } - memcpy(&vhdr->vstr_len, data + 16 + vhdr->vsig_n * 32, 1); + memcpy(&vhdr->vstr_len, data + 32 + vhdr->vsig_n * 32, 1); - vhdr->vstr = data + 16 + vhdr->vsig_n * 32 + 1; + vhdr->vstr = data + 32 + vhdr->vsig_n * 32 + 1; - vhdr->vimg = data + 16 + vhdr->vsig_n * 32 + 1 + vhdr->vstr_len; + vhdr->vimg = data + 32 + vhdr->vsig_n * 32 + 1 + vhdr->vstr_len; // align to 4 bytes vhdr->vimg += (-(uintptr_t)vhdr->vimg) & 3; diff --git a/embed/trezorhal/image.h b/embed/trezorhal/image.h index 470b4769..69d159ec 100644 --- a/embed/trezorhal/image.h +++ b/embed/trezorhal/image.h @@ -24,6 +24,8 @@ typedef struct { uint16_t version; uint8_t vsig_m; uint8_t vsig_n; + uint8_t vtrust; + // uint8_t reserved[16]; const uint8_t *vpub[MAX_VENDOR_PUBLIC_KEYS]; uint8_t vstr_len; const uint8_t *vstr; diff --git a/tools/binctl b/tools/binctl index aeb9a720..6bf1997b 100755 --- a/tools/binctl +++ b/tools/binctl @@ -172,18 +172,19 @@ class BootloaderImage(BinImage): class VendorHeader(object): def __init__(self, data): - header = struct.unpack('<4sIIBBBB', data[:16]) + header = struct.unpack('<4sIIBBBBB', data[:17]) self.magic, \ self.hdrlen, \ self.expiry, \ self.vmajor, \ self.vminor, \ self.vsig_m, \ - self.vsig_n = header + self.vsig_n, \ + self.vtrust = header assert self.magic == b'TRZV' assert self.vsig_m > 0 and self.vsig_m <= self.vsig_n assert self.vsig_n > 0 and self.vsig_n <= 8 - p = 16 + p = 32 self.vpub = [] for _ in range(self.vsig_n): self.vpub.append(data[p:p + 32]) @@ -200,7 +201,7 @@ class VendorHeader(object): self.sigmask = data[p] p += 1 self.sig = data[p:p + 64] - assert len(data) == 4 + 4 + 4 + 1 + 1 + 1 + 1 + \ + assert len(data) == 4 + 4 + 4 + 1 + 1 + 1 + 1 + 1 + 15 + \ 32 * len(self.vpub) + \ 1 + self.vstr_len + vstr_pad + \ self.vimg_len + \ @@ -213,6 +214,7 @@ class VendorHeader(object): print(' * expiry :', self.expiry) print(' * version : %d.%d' % (self.vmajor, self.vminor)) print(' * scheme : %d out of %d' % (self.vsig_m, self.vsig_n)) + print(' * trust :', self.vtrust) for i in range(self.vsig_n): print(' * vpub #%d :' % (i + 1), binascii.hexlify(self.vpub[i]).decode('ascii')) print(' * vstr :', self.vstr.decode('ascii')) @@ -221,10 +223,11 @@ class VendorHeader(object): print(' * sig :', binascii.hexlify(self.sig).decode('ascii')) def serialize_header(self, sig=True): - header = struct.pack('<4sIIBBBB', + header = struct.pack('<4sIIBBBBB', self.magic, self.hdrlen, self.expiry, self.vmajor, self.vminor, - self.vsig_m, self.vsig_n) + self.vsig_m, self.vsig_n, self.vtrust) + header += 15 * b'\x00' for i in range(self.vsig_n): header += self.vpub[i] header += struct.pack('