#!/usr/bin/env python from __future__ import print_function import argparse import hashlib import struct import binascii import ecdsa try: raw_input except: raw_input = input SLOTS = 3 pubkeys = { 1: '04d571b7f148c5e4232c3814f777d8faeaf1a84216c78d569b71041ffc768a5b2d810fc3bb134dd026b57e65005275aedef43e155f48fc11a32ec790a93312bd58', 2: '0463279c0c0866e50c05c799d32bd6bab0188b6de06536d1109d2ed9ce76cb335c490e55aee10cc901215132e853097d5432eda06b792073bd7740c94ce4516cb1', 3: '0443aedbb6f7e71c563f8ed2ef64ec9981482519e7ef4f4aa98b27854e8c49126d4956d300ab45fdc34cd26bc8710de0a31dbdf6de7435fd0b492be70ac75fde58', 4: '04877c39fd7c62237e038235e9c075dab261630f78eeb8edb92487159fffedfdf6046c6f8b881fa407c4a4ce6c28de0b19c1f4e29f1fcbc5a58ffd1432a3e0938a', 5: '047384c51ae81add0a523adbb186c91b906ffb64c2c765802bf26dbd13bdf12c319e80c2213a136c8ee03d7874fd22b70d68e7dee469decfbbb510ee9a460cda45', } INDEXES_START = len('TRZR') + struct.calcsize(' SLOTS: raise Exception("Invalid slot") if is_pem: print("Paste ECDSA private key in PEM format and press Enter:") print("(blank private key removes the signature on given index)") pem_key = '' while True: key = raw_input() pem_key += key + "\n" if key == '': break if pem_key.strip() == '': # Blank key,let's remove existing signature from slot return modify(data, slot, 0, '\x00' * 64) key = ecdsa.SigningKey.from_pem(pem_key) else: print("Paste SECEXP (in hex) and press Enter:") print("(blank private key removes the signature on given index)") secexp = raw_input() if secexp.strip() == '': # Blank key,let's remove existing signature from slot return modify(data, slot, 0, '\x00' * 64) key = ecdsa.SigningKey.from_secret_exponent(secexp = int(secexp, 16), curve=ecdsa.curves.SECP256k1, hashfunc=hashlib.sha256) to_sign = prepare(data)[256:] # without meta # Locate proper index of current signing key pubkey = b'04' + binascii.hexlify(key.get_verifying_key().to_string()) index = None for i, pk in pubkeys.items(): if pk == pubkey: index = i break if index == None: raise Exception("Unable to find private key index. Unknown private key?") signature = key.sign_deterministic(to_sign, hashfunc=hashlib.sha256) return modify(data, slot, index, signature) def main(args): if args.generate: key = ecdsa.SigningKey.generate( curve=ecdsa.curves.SECP256k1, hashfunc=hashlib.sha256) print("PRIVATE KEY (SECEXP):") print(binascii.hexlify(key.to_string())) print() print("PRIVATE KEY (PEM):") print(key.to_pem()) print("PUBLIC KEY:") print('04' + binascii.hexlify(key.get_verifying_key().to_string())) return if not args.path: raise Exception("-f/--file is required") data = open(args.path, 'rb').read() assert len(data) % 4 == 0 if data[:4] != b'TRZR': print("Metadata has been added...") data = prepare(data) if data[:4] != b'TRZR': raise Exception("Firmware header expected") print("Firmware size %d bytes" % len(data)) check_signatures(data) if args.sign: data = sign(data, args.pem) check_signatures(data) fp = open(args.path, 'wb') fp.write(data) fp.close() if __name__ == '__main__': args = parse_args() main(args)