1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-18 21:48:13 +00:00
trezor-firmware/core/tools/keyctl

64 lines
1.7 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env python3
import binascii
import struct
import click
import pyblake2
from trezorlib import cosi
2018-07-31 09:35:09 +00:00
indexmap = {"bootloader": 0, "vendorheader": 1, "firmware": 2}
def header_digest(index, filename):
2018-07-31 09:35:09 +00:00
data = open(filename, "rb").read()
z = bytes(65 * [0x00])
2018-07-31 09:35:09 +00:00
if index == "bootloader":
header = data[:0x03BF] + z
2018-07-31 09:35:09 +00:00
elif index == "vendorheader":
header = data[:-65] + z
2018-07-31 09:35:09 +00:00
elif index == "firmware":
vhdrlen = struct.unpack("<I", data[4:8])[0]
header = data[vhdrlen : vhdrlen + 0x03BF] + z
2018-01-29 08:10:19 +00:00
else:
raise ValueError('Unknown index "%s"' % index)
return pyblake2.blake2s(header).digest()
@click.group()
def cli():
pass
2018-07-31 09:35:09 +00:00
@cli.command(help="")
@click.argument("index", type=click.Choice(indexmap.keys()))
@click.argument("filename")
@click.argument("seckeys", nargs=-1)
def sign(index, filename, seckeys):
# compute header digest
digest = header_digest(index, filename)
# collect commits
pks, nonces, Rs = [], [], []
for ctr, seckey in enumerate(seckeys):
sk = binascii.unhexlify(seckey)
pk = cosi.pubkey_from_privkey(sk)
r, R = cosi.get_nonce(sk, digest, ctr)
pks.append(pk)
nonces.append(r)
Rs.append(R)
# compute global commit
global_pk = cosi.combine_keys(pks)
global_R = cosi.combine_keys(Rs)
# collect signatures
sigs = []
for seckey, nonce in zip(seckeys, nonces):
sk = binascii.unhexlify(seckey)
sig = cosi.sign_with_privkey(digest, sk, global_pk, nonce, global_R)
sigs.append(sig)
# compute global signature
sig = cosi.combine_sig(global_R, sigs)
cosi.verify_combined(sig, digest, global_pk)
print(binascii.hexlify(sig).decode())
2018-07-31 09:35:09 +00:00
if __name__ == "__main__":
cli()