mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-13 08:50:56 +00:00
feat(core): support checking generated vendor headers as part of make gen_check
[no changelog]
This commit is contained in:
parent
ec06cc5c40
commit
df84d96244
10
Makefile
10
Makefile
@ -130,6 +130,12 @@ ci_docs: ## generate CI documentation
|
||||
ci_docs_check: ## check that generated CI documentation is up to date
|
||||
./tools/generate_ci_docs.py --check
|
||||
|
||||
gen: mocks icons templates protobuf ci_docs ## regenerate auto-generated files from sources
|
||||
vendorheader: ## generate vendor header
|
||||
./core/embed/vendorheader/generate.sh --quiet
|
||||
|
||||
gen_check: mocks_check icons_check templates_check protobuf_check ci_docs_check ## check validity of auto-generated files
|
||||
vendorheader_check: ## check that vendor header is up to date
|
||||
./core/embed/vendorheader/generate.sh --quiet --check
|
||||
|
||||
gen: mocks icons templates protobuf ci_docs vendorheader ## regenerate auto-generated files from sources
|
||||
|
||||
gen_check: mocks_check icons_check templates_check protobuf_check ci_docs_check vendorheader_check ## check validity of auto-generated files
|
||||
|
@ -1,10 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
BUILDVH=$(realpath ../../tools/build_vendorheader)
|
||||
BINCTL=$(realpath ../../tools/headertool.py)
|
||||
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" == "--check" ]; then
|
||||
CHECK="--check"
|
||||
fi
|
||||
if [ "$arg" == "--quiet" ]; then
|
||||
QUIET="--quiet"
|
||||
fi
|
||||
done
|
||||
|
||||
MODELS=(T2T1 T2B1 D001)
|
||||
|
||||
for MODEL in ${MODELS[@]}; do
|
||||
@ -12,13 +23,24 @@ for MODEL in ${MODELS[@]}; do
|
||||
# construct all vendor headers
|
||||
for fn in *.json; do
|
||||
name=$(echo $fn | sed 's/vendor_\(.*\)\.json/\1/')
|
||||
$BUILDVH vendor_${name}.json vendor_${name}.toif vendorheader_${name}_unsigned.bin
|
||||
$BUILDVH $QUIET $CHECK vendor_${name}.json vendor_${name}.toif vendorheader_${name}_unsigned.bin
|
||||
done
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
trap "rm -rf $TMPDIR" EXIT
|
||||
# sign dev and QA vendor header
|
||||
for name in unsafe qa_DO_NOT_SIGN; do
|
||||
cp -a vendorheader_${name}_unsigned.bin vendorheader_${name}_signed_dev.bin
|
||||
$BINCTL -D vendorheader_${name}_signed_dev.bin
|
||||
SRC_NAME="vendorheader_${name}_unsigned.bin"
|
||||
DEST_NAME="vendorheader_${name}_signed_dev.bin"
|
||||
if [ ! -f "$SRC_NAME" ]; then
|
||||
continue
|
||||
fi
|
||||
cp -a vendorheader_${name}_unsigned.bin "$TMPDIR/$DEST_NAME"
|
||||
$BINCTL $QUIET -D "$TMPDIR/$DEST_NAME"
|
||||
if [ -n "$CHECK" ]; then
|
||||
diff "$DEST_NAME" "$TMPDIR/$DEST_NAME"
|
||||
fi
|
||||
cp -a "$TMPDIR/$DEST_NAME" "$DEST_NAME"
|
||||
done
|
||||
cd ..
|
||||
done
|
||||
|
@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import click
|
||||
|
||||
@ -20,8 +21,15 @@ def minimum_header_len(spec):
|
||||
@click.command()
|
||||
@click.argument("specfile", type=click.File("r"))
|
||||
@click.argument("image", type=click.File("rb"))
|
||||
@click.argument("outfile", type=click.File("wb"))
|
||||
def build_vendorheader(specfile, image, outfile):
|
||||
@click.argument("outfile", type=click.Path(dir_okay=False, writable=True, path_type=Path))
|
||||
@click.option("-c", "--check", is_flag=True, help="Check but do not write header.")
|
||||
@click.option("-q", "--quiet", is_flag=True, help="Do not print anything.")
|
||||
def build_vendorheader(specfile, image, outfile, check: bool, quiet: bool):
|
||||
if quiet:
|
||||
echo = lambda *args, **kwargs: None
|
||||
else:
|
||||
echo = click.echo
|
||||
|
||||
spec = json.load(specfile)
|
||||
spec["pubkeys"] = [bytes.fromhex(k) for k in spec["pubkeys"]]
|
||||
spec["image"] = toif.ToifStruct.parse(image.read())
|
||||
@ -41,16 +49,26 @@ def build_vendorheader(specfile, image, outfile):
|
||||
f"Minimum allowable value is {min_length}."
|
||||
)
|
||||
elif spec["header_len"] == min_length:
|
||||
click.echo(f"{specfile.name}: Header has correct length.")
|
||||
echo(f"{specfile.name}: Header has correct length.")
|
||||
else:
|
||||
click.echo(
|
||||
echo(
|
||||
f"{specfile.name}: Extending header ({min_length} bytes) to {spec['header_len']} bytes."
|
||||
)
|
||||
|
||||
if spec["header_len"] % 512 != 0:
|
||||
raise click.ClickException("Invalid header_len: must be a multiple of 512")
|
||||
|
||||
outfile.write(firmware.VendorHeader.SUBCON.build(spec))
|
||||
vh_bytes = firmware.VendorHeader.SUBCON.build(spec)
|
||||
if check:
|
||||
if not outfile.exists():
|
||||
raise click.ClickException(f"Header file {outfile.name} does not exist.")
|
||||
outfile_bytes = outfile.read_bytes()
|
||||
if outfile_bytes != vh_bytes:
|
||||
raise click.ClickException(
|
||||
f"Header file {outfile.name} differs from expected header."
|
||||
)
|
||||
else:
|
||||
outfile.write_bytes(firmware.VendorHeader.SUBCON.build(spec))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -100,6 +100,7 @@ def do_replace_vendorheader(fw, vh_file) -> None:
|
||||
is_flag=True,
|
||||
help="Only output header digest for signing and exit.",
|
||||
)
|
||||
@click.option("-q", "--quiet", is_flag=True, help="Do not print anything.")
|
||||
@click.argument("firmware_file", type=click.File("rb+"))
|
||||
def cli(
|
||||
firmware_file,
|
||||
@ -111,6 +112,7 @@ def cli(
|
||||
insert_signature,
|
||||
replace_vendor_header,
|
||||
print_digest,
|
||||
quiet,
|
||||
):
|
||||
"""Manage firmware headers.
|
||||
|
||||
@ -160,6 +162,11 @@ def cli(
|
||||
click.echo(digest.hex())
|
||||
return
|
||||
|
||||
if quiet:
|
||||
echo = lambda *args, **kwargs: None
|
||||
else:
|
||||
echo = click.echo
|
||||
|
||||
if replace_vendor_header:
|
||||
do_replace_vendorheader(fw, replace_vendor_header)
|
||||
|
||||
@ -174,11 +181,11 @@ def cli(
|
||||
signature = None
|
||||
|
||||
if privkeys:
|
||||
click.echo("Signing with local private keys...", err=True)
|
||||
echo("Signing with local private keys...", err=True)
|
||||
signature = sign_with_privkeys(digest, privkeys)
|
||||
|
||||
if insert_signature:
|
||||
click.echo("Inserting external signature...", err=True)
|
||||
echo("Inserting external signature...", err=True)
|
||||
sigmask_str, signature = insert_signature
|
||||
signature = bytes.fromhex(signature)
|
||||
sigmask = 0
|
||||
@ -193,14 +200,14 @@ def cli(
|
||||
if signature or rehash:
|
||||
do_rehash(fw)
|
||||
|
||||
click.echo(f"Detected image type: {fw.NAME}")
|
||||
click.echo(fw.format(verbose))
|
||||
echo(f"Detected image type: {fw.NAME}")
|
||||
echo(fw.format(verbose))
|
||||
|
||||
updated_data = fw.build()
|
||||
if updated_data == firmware_data:
|
||||
click.echo("No changes made", err=True)
|
||||
echo("No changes made", err=True)
|
||||
elif dry_run:
|
||||
click.echo("Not saving changes", err=True)
|
||||
echo("Not saving changes", err=True)
|
||||
else:
|
||||
firmware_file.seek(0)
|
||||
firmware_file.truncate(0)
|
||||
|
Loading…
Reference in New Issue
Block a user