#!/usr/bin/env python3 import argparse import hashlib import struct import ecdsa from ecdsa import BadSignatureError SLOTS = 3 pubkeys_dev = { 1: "042c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991ae31a9c671a36543f46cea8fce6984608aa316aa0472a7eed08847440218cb2f", 2: "04edabbd16b41c8371b92ef2f04c1185b4f03b6dcd52ba9b78d9d7c89c8f2211452c88a66eb8ac3c19a1cc3a3fc6d72506f6fce2025f738d8b55f29f22125eb0a4", 3: "04665f660a5052be7a95546a02179058d93d3e08a779734914594346075bb0afd45113948d72cf3dc8f2b70ee02dc1695d051bb0c6da2a914a69045e3277682d3b", } privkeys_dev = { 1: "0x4444444444444444444444444444444444444444444444444444444444444444", 2: "0x4545454545454545454545454545454545454545454545454545454545454545", 3: "0xbfc4bca9c9c228a16639d3503d999a733a439210b64cebe757a4fd03ca46a5c8", } FWHEADER_SIZE = 1024 SIGNATURES_START = 6 * 4 + 8 + 512 INDEXES_START = SIGNATURES_START + 3 * 64 INDEXES_START_OLD = len("TRZR") + struct.calcsize(" size: raise ValueError("Chunk too big already") if len(data) == size: return data return data + b"\xFF" * (size - len(data)) # see memory.h for details def prepare_hashes(data): # process chunks start = 0 end = (64 - 1) * 1024 hashes = [] for i in range(16): sector = data[start:end] if len(sector) > 0: chunk = pad_to_size(sector, end - start) hashes.append(hashlib.sha256(chunk).digest()) else: hashes.append(b"\x00" * 32) start = end end += 64 * 1024 return hashes def check_hashes(data): expected_hashes = data[0x20 : 0x20 + 16 * 32] hashes = b"" for h in prepare_hashes(data[FWHEADER_SIZE:]): hashes += h if expected_hashes == hashes: print("HASHES OK") else: print("HASHES NOT OK") def update_hashes_in_header(data): # Store hashes in the firmware header data = bytearray(data) o = 0 for h in prepare_hashes(data[FWHEADER_SIZE:]): data[0x20 + o : 0x20 + o + 32] = h o += 32 return bytes(data) def get_header(data, zero_signatures=False): if not zero_signatures: return data[:FWHEADER_SIZE] else: data = bytearray(data[:FWHEADER_SIZE]) data[SIGNATURES_START : SIGNATURES_START + 3 * 64 + 3] = b"\x00" * (3 * 64 + 3) return bytes(data) def check_size(data): size = struct.unpack("