diff --git a/core/embed/vendorheader/vendor_satoshilabs.json b/core/embed/vendorheader/vendor_satoshilabs.json index 7c4c6f4567..0e0d2c7002 100644 --- a/core/embed/vendorheader/vendor_satoshilabs.json +++ b/core/embed/vendorheader/vendor_satoshilabs.json @@ -1,4 +1,5 @@ { + "header_len": 4608, "text": "SatoshiLabs", "expiry": 0, "version": { diff --git a/core/embed/vendorheader/vendor_unsafe.json b/core/embed/vendorheader/vendor_unsafe.json index e7af4710e5..9e2d1620af 100644 --- a/core/embed/vendorheader/vendor_unsafe.json +++ b/core/embed/vendorheader/vendor_unsafe.json @@ -1,4 +1,5 @@ { + "header_len": 2560, "text": "UNSAFE, DO NOT USE!", "expiry": 0, "version": { diff --git a/core/tools/build_vendorheader b/core/tools/build_vendorheader index be085c121e..e9264bf1dd 100755 --- a/core/tools/build_vendorheader +++ b/core/tools/build_vendorheader @@ -6,6 +6,15 @@ import click from trezorlib import firmware +def minimum_header_len(spec): + spec = spec.copy() + spec["header_len"] = 512000 + reparsed = firmware.VendorHeader.parse(firmware.VendorHeader.build(spec)) + data_length = reparsed._end_offset - reparsed._start_offset + # data length + 65 for signatures, rounded up to nearest multiple of 512 + return (data_length + 65 + 511) // 512 * 512 + + @click.command() @click.argument("specfile", type=click.File("r")) @click.argument("image", type=click.File("rb")) @@ -16,6 +25,19 @@ def build_vendorheader(specfile, image, outfile): spec["image"] = firmware.Toif.parse(image.read()) spec["sigmask"] = 0 spec["signature"] = b"\x00" * 64 + + min_length = minimum_header_len(spec) + if "header_len" not in spec: + spec["header_len"] = min_length + elif spec["header_len"] < min_length: + raise click.ClickException( + f"Specified header_len {spec['header_len']} too low. " + f"Minimum allowable value is {min_length}." + ) + + if spec["header_len"] % 512 != 0: + raise click.ClickException("Invalid header_len: must be a multiple of 512") + outfile.write(firmware.VendorHeader.build(spec)) diff --git a/python/src/trezorlib/firmware.py b/python/src/trezorlib/firmware.py index c6947fef75..21e67eab75 100644 --- a/python/src/trezorlib/firmware.py +++ b/python/src/trezorlib/firmware.py @@ -146,7 +146,7 @@ VendorTrust = c.Transformed(c.BitStruct( VendorHeader = c.Struct( "_start_offset" / c.Tell, "magic" / c.Const(b"TRZV"), - "_header_len" / c.Padding(4), + "header_len" / c.Int32ul, "expiry" / c.Int32ul, "version" / c.Struct( "major" / c.Int8ul, @@ -159,17 +159,14 @@ VendorHeader = c.Struct( "pubkeys" / c.Bytes(32)[c.this.sig_n], "text" / c.Aligned(4, c.PascalString(c.Int8ul, "utf-8")), "image" / Toif, - "_data_end_offset" / c.Tell, + "_end_offset" / c.Tell, - c.Padding(-(c.this._data_end_offset + 65) % 512), + "_min_header_len" / c.Check(c.this.header_len > (c.this._end_offset - c.this._start_offset) + 65), + "_header_len_aligned" / c.Check(c.this.header_len % 512 == 0), + + c.Padding(c.this.header_len - c.this._end_offset + c.this._start_offset - 65), "sigmask" / c.Byte, "signature" / c.Bytes(64), - - "_end_offset" / c.Tell, - "header_len" / c.Pointer( - c.this._start_offset + 4, - c.Rebuild(c.Int32ul, c.this._end_offset - c.this._start_offset) - ), )