mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-12 10:39:00 +00:00
61 lines
1.8 KiB
Python
61 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 LEGACY_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] == LEGACY_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()
|