mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-17 21:22:10 +00:00
63 lines
1.8 KiB
Python
63 lines
1.8 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
import typing as t
|
||
|
from hashlib import sha256
|
||
|
from pathlib import Path
|
||
|
|
||
|
import click
|
||
|
import ecdsa
|
||
|
|
||
|
from trezorlib.firmware.legacy import LegacyV2Firmware
|
||
|
from trezorlib.firmware.models import TREZOR_ONE_V3_DEV
|
||
|
|
||
|
SECRET_KEYS = [
|
||
|
ecdsa.SigningKey.from_string(bytes.fromhex(sk), curve=ecdsa.SECP256k1)
|
||
|
for sk in (
|
||
|
"ca8de06e1e93d101136fa6fbc41432c52b6530299dfe32808030ee8e679702f1",
|
||
|
"dde47dd393f7d76f9b522bfa9760bc4543d2c3654491393774f54e066461fccb",
|
||
|
"14ba98c5c5cb8f1b214c661f4046ec2288c34fe2e73e02f149ec3dd8dad07ae2",
|
||
|
)
|
||
|
]
|
||
|
|
||
|
PUBLIC_KEYS: list[ecdsa.VerifyingKey] = [sk.get_verifying_key() for sk in SECRET_KEYS]
|
||
|
|
||
|
# Should be these public keys
|
||
|
assert [
|
||
|
pk.to_string("compressed") for pk in PUBLIC_KEYS
|
||
|
] == TREZOR_ONE_V3_DEV.firmware_keys
|
||
|
|
||
|
|
||
|
def signmessage(digest: bytes, key: ecdsa.SigningKey) -> bytes:
|
||
|
"""Sign via SignMessage"""
|
||
|
btc_digest = b"\x18Bitcoin Signed Message:\n\x20" + digest
|
||
|
final_digest = sha256(sha256(btc_digest).digest()).digest()
|
||
|
return key.sign_digest_deterministic(final_digest, hashfunc=sha256)
|
||
|
|
||
|
|
||
|
@click.command()
|
||
|
@click.argument("firmware", type=click.File("rb"))
|
||
|
@click.option("-i", "--index", "indices", type=int, multiple=True)
|
||
|
def cli(firmware: click.utils.LazyFile, indices: t.Sequence[int]) -> None:
|
||
|
fw = LegacyV2Firmware.parse(firmware.read())
|
||
|
if not indices:
|
||
|
indices = [1, 2]
|
||
|
|
||
|
if len(indices) > 3:
|
||
|
raise click.ClickException("Too many indices")
|
||
|
|
||
|
digest = fw.digest()
|
||
|
for i, idx in enumerate(indices):
|
||
|
sk = SECRET_KEYS[idx - 1]
|
||
|
sig = signmessage(digest, sk)
|
||
|
|
||
|
fw.header.v1_key_indexes[i] = idx
|
||
|
fw.header.v1_signatures[i] = sig
|
||
|
|
||
|
new_fw = Path(firmware.name).with_suffix(".signed.bin")
|
||
|
new_fw.write_bytes(fw.build())
|
||
|
click.echo(f"Wrote signed firmware to {new_fw}")
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
cli()
|