add vendor trust to vendorheader

pull/25/head
Pavol Rusnak 7 years ago
parent 1d9b907342
commit 78f57d083c
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -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

@ -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 |

@ -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 {

@ -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);
}

@ -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

@ -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;

@ -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;

@ -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('<B', self.vstr_len) + self.vstr

@ -21,22 +21,24 @@ def encode_pubkey(pubkey):
def main():
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
keys = [encode_pubkey(x) for x in sys.argv[1].split(':')]
m = int(sys.argv[2])
(vmajor, vminor) = [int(x) for x in sys.argv[3].split('.')]
vname = sys.argv[4]
ifn = sys.argv[5]
ofn = sys.argv[6]
vtrust = int(sys.argv[4])
vname = sys.argv[5]
ifn = sys.argv[6]
ofn = sys.argv[7]
if not ifn.endswith('.toif'):
print('Must provide TOIF file')
return 2
expiry = 0
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:
vheader += k
vheader += encode_vendor(vname) + open(ifn, 'rb').read()

Loading…
Cancel
Save