mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 23:48:12 +00:00
add vendor trust to vendorheader
This commit is contained in:
parent
1d9b907342
commit
78f57d083c
4
Makefile
4
Makefile
@ -149,11 +149,11 @@ gdb_firmware: $(FIRMWARE_BUILD_DIR)/firmware.elf ## start remote gdb session to
|
|||||||
## misc commands:
|
## misc commands:
|
||||||
|
|
||||||
vendorheader: ## construct default vendor header
|
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
|
./tools/binctl embed/firmware/vendorheader.bin -s 1:2 4444444444444444444444444444444444444444444444444444444444444444:4545454545454545454545454545454545454545454545454545454545454545
|
||||||
|
|
||||||
vendorheader_sl: ## construct SatoshiLabs vendor header
|
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
|
./tools/binctl embed/firmware/vendorheader_sl.bin -s 1:2 trezor:trezor
|
||||||
|
|
||||||
binctl: ## print info about binary files
|
binctl: ## print info about binary files
|
||||||
|
@ -82,14 +82,16 @@ of 512 bytes.
|
|||||||
| 0x000D | 1 | vminor | version (minor) |
|
| 0x000D | 1 | vminor | version (minor) |
|
||||||
| 0x000E | 1 | vsig_m | number of signatures needed to run the firmware from this vendor |
|
| 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 |
|
| 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 |
|
| ? | 32 | vpubn | vendor pubkey n |
|
||||||
| ? | 1 | vstr_len | vendor string length |
|
| ? | 1 | vstr_len | vendor string length |
|
||||||
| ? | ? | vstr | vendor string |
|
| ? | ? | vstr | vendor string |
|
||||||
| ? | ? | vstrpad | padding to a multiple of 4 bytes |
|
| ? | ? | vstrpad | padding to a multiple of 4 bytes |
|
||||||
| ? | ? | vimg | vendor image (in [TOIf format](toif.md)) |
|
| ? | ? | 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) |
|
| ? | 1 | sigmask | SatoshiLabs signature indexes (bitmap) |
|
||||||
| ? | 64 | sig | SatoshiLabs aggregated signature |
|
| ? | 64 | sig | SatoshiLabs aggregated signature |
|
||||||
|
|
||||||
|
@ -92,7 +92,11 @@ void check_and_jump(void)
|
|||||||
display_printf("valid firmware signature\n");
|
display_printf("valid firmware signature\n");
|
||||||
|
|
||||||
display_vendor(vhdr.vimg, (const char *)vhdr.vstr, vhdr.vstr_len, hdr.version);
|
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);
|
jump_to(FIRMWARE_START + vhdr.hdrlen + HEADER_SIZE);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -71,3 +71,8 @@ void jump_to(uint32_t start)
|
|||||||
__asm__ volatile("msr msp, %0"::"g" (*(volatile uint32_t *)start));
|
__asm__ volatile("msr msp, %0"::"g" (*(volatile uint32_t *)start));
|
||||||
(*(void (**)())(start + 4))();
|
(*(void (**)())(start + 4))();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hal_delay(uint32_t ms)
|
||||||
|
{
|
||||||
|
HAL_Delay(ms);
|
||||||
|
}
|
||||||
|
@ -16,4 +16,6 @@ void __attribute__((noreturn)) nlr_jump_fail(void *val);
|
|||||||
|
|
||||||
void jump_to(uint32_t address);
|
void jump_to(uint32_t address);
|
||||||
|
|
||||||
|
void hal_delay(uint32_t ms);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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_m, data + 14, 1);
|
||||||
memcpy(&vhdr->vsig_n, data + 15, 1);
|
memcpy(&vhdr->vsig_n, data + 15, 1);
|
||||||
|
memcpy(&vhdr->vtrust, data + 16, 1);
|
||||||
|
|
||||||
if (vhdr->vsig_n > MAX_VENDOR_PUBLIC_KEYS) {
|
if (vhdr->vsig_n > MAX_VENDOR_PUBLIC_KEYS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < vhdr->vsig_n; i++) {
|
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++) {
|
for (int i = vhdr->vsig_n; i < MAX_VENDOR_PUBLIC_KEYS; i++) {
|
||||||
vhdr->vpub[i] = 0;
|
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
|
// align to 4 bytes
|
||||||
vhdr->vimg += (-(uintptr_t)vhdr->vimg) & 3;
|
vhdr->vimg += (-(uintptr_t)vhdr->vimg) & 3;
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@ typedef struct {
|
|||||||
uint16_t version;
|
uint16_t version;
|
||||||
uint8_t vsig_m;
|
uint8_t vsig_m;
|
||||||
uint8_t vsig_n;
|
uint8_t vsig_n;
|
||||||
|
uint8_t vtrust;
|
||||||
|
// uint8_t reserved[16];
|
||||||
const uint8_t *vpub[MAX_VENDOR_PUBLIC_KEYS];
|
const uint8_t *vpub[MAX_VENDOR_PUBLIC_KEYS];
|
||||||
uint8_t vstr_len;
|
uint8_t vstr_len;
|
||||||
const uint8_t *vstr;
|
const uint8_t *vstr;
|
||||||
|
15
tools/binctl
15
tools/binctl
@ -172,18 +172,19 @@ class BootloaderImage(BinImage):
|
|||||||
class VendorHeader(object):
|
class VendorHeader(object):
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
header = struct.unpack('<4sIIBBBB', data[:16])
|
header = struct.unpack('<4sIIBBBBB', data[:17])
|
||||||
self.magic, \
|
self.magic, \
|
||||||
self.hdrlen, \
|
self.hdrlen, \
|
||||||
self.expiry, \
|
self.expiry, \
|
||||||
self.vmajor, \
|
self.vmajor, \
|
||||||
self.vminor, \
|
self.vminor, \
|
||||||
self.vsig_m, \
|
self.vsig_m, \
|
||||||
self.vsig_n = header
|
self.vsig_n, \
|
||||||
|
self.vtrust = header
|
||||||
assert self.magic == b'TRZV'
|
assert self.magic == b'TRZV'
|
||||||
assert self.vsig_m > 0 and self.vsig_m <= self.vsig_n
|
assert self.vsig_m > 0 and self.vsig_m <= self.vsig_n
|
||||||
assert self.vsig_n > 0 and self.vsig_n <= 8
|
assert self.vsig_n > 0 and self.vsig_n <= 8
|
||||||
p = 16
|
p = 32
|
||||||
self.vpub = []
|
self.vpub = []
|
||||||
for _ in range(self.vsig_n):
|
for _ in range(self.vsig_n):
|
||||||
self.vpub.append(data[p:p + 32])
|
self.vpub.append(data[p:p + 32])
|
||||||
@ -200,7 +201,7 @@ class VendorHeader(object):
|
|||||||
self.sigmask = data[p]
|
self.sigmask = data[p]
|
||||||
p += 1
|
p += 1
|
||||||
self.sig = data[p:p + 64]
|
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) + \
|
32 * len(self.vpub) + \
|
||||||
1 + self.vstr_len + vstr_pad + \
|
1 + self.vstr_len + vstr_pad + \
|
||||||
self.vimg_len + \
|
self.vimg_len + \
|
||||||
@ -213,6 +214,7 @@ class VendorHeader(object):
|
|||||||
print(' * expiry :', self.expiry)
|
print(' * expiry :', self.expiry)
|
||||||
print(' * version : %d.%d' % (self.vmajor, self.vminor))
|
print(' * version : %d.%d' % (self.vmajor, self.vminor))
|
||||||
print(' * scheme : %d out of %d' % (self.vsig_m, self.vsig_n))
|
print(' * scheme : %d out of %d' % (self.vsig_m, self.vsig_n))
|
||||||
|
print(' * trust :', self.vtrust)
|
||||||
for i in range(self.vsig_n):
|
for i in range(self.vsig_n):
|
||||||
print(' * vpub #%d :' % (i + 1), binascii.hexlify(self.vpub[i]).decode('ascii'))
|
print(' * vpub #%d :' % (i + 1), binascii.hexlify(self.vpub[i]).decode('ascii'))
|
||||||
print(' * vstr :', self.vstr.decode('ascii'))
|
print(' * vstr :', self.vstr.decode('ascii'))
|
||||||
@ -221,10 +223,11 @@ class VendorHeader(object):
|
|||||||
print(' * sig :', binascii.hexlify(self.sig).decode('ascii'))
|
print(' * sig :', binascii.hexlify(self.sig).decode('ascii'))
|
||||||
|
|
||||||
def serialize_header(self, sig=True):
|
def serialize_header(self, sig=True):
|
||||||
header = struct.pack('<4sIIBBBB',
|
header = struct.pack('<4sIIBBBBB',
|
||||||
self.magic, self.hdrlen, self.expiry,
|
self.magic, self.hdrlen, self.expiry,
|
||||||
self.vmajor, self.vminor,
|
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):
|
for i in range(self.vsig_n):
|
||||||
header += self.vpub[i]
|
header += self.vpub[i]
|
||||||
header += struct.pack('<B', self.vstr_len) + self.vstr
|
header += struct.pack('<B', self.vstr_len) + self.vstr
|
||||||
|
@ -21,22 +21,24 @@ def encode_pubkey(pubkey):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
if len(sys.argv) < 7:
|
if len(sys.argv) < 7:
|
||||||
print('Usage build_vendorheader "pubkey1hex:pubkey2hex:..." m version vendorname vendorimage.toif vendorheader.bin')
|
print('Usage build_vendorheader "pubkey1hex:pubkey2hex:..." m version vendortrust vendorname vendorimage.toif vendorheader.bin')
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
keys = [encode_pubkey(x) for x in sys.argv[1].split(':')]
|
keys = [encode_pubkey(x) for x in sys.argv[1].split(':')]
|
||||||
m = int(sys.argv[2])
|
m = int(sys.argv[2])
|
||||||
(vmajor, vminor) = [int(x) for x in sys.argv[3].split('.')]
|
(vmajor, vminor) = [int(x) for x in sys.argv[3].split('.')]
|
||||||
vname = sys.argv[4]
|
vtrust = int(sys.argv[4])
|
||||||
ifn = sys.argv[5]
|
vname = sys.argv[5]
|
||||||
ofn = sys.argv[6]
|
ifn = sys.argv[6]
|
||||||
|
ofn = sys.argv[7]
|
||||||
if not ifn.endswith('.toif'):
|
if not ifn.endswith('.toif'):
|
||||||
print('Must provide TOIF file')
|
print('Must provide TOIF file')
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
expiry = 0
|
expiry = 0
|
||||||
vheader = b'TRZV' + \
|
vheader = b'TRZV' + \
|
||||||
struct.pack('<IIBBBB', 0, expiry, vmajor, vminor, m, len(keys))
|
struct.pack('<IIBBBBB', 0, expiry, vmajor, vminor, m, len(keys), vtrust)
|
||||||
|
vheader += 15 * b'\0'
|
||||||
for k in keys:
|
for k in keys:
|
||||||
vheader += k
|
vheader += k
|
||||||
vheader += encode_vendor(vname) + open(ifn, 'rb').read()
|
vheader += encode_vendor(vname) + open(ifn, 'rb').read()
|
||||||
|
Loading…
Reference in New Issue
Block a user