#!/usr/bin/env python3 """ insert_signatures.py A script to append two TLV entries (signatures) into the unprotected TLV area of a Zephyr image in either raw binary or Intel HEX format, updating the existing TLV-info header length. Usage: python insert_signatures.py input.[bin|hex] [-o output.[bin|hex]] - `signature0` and `signature1` must be 64-byte values (128 hex digits). """ import argparse import struct import sys import os from intelhex import IntelHex def parse_args(): parser = argparse.ArgumentParser( description="Append signature TLVs to an existing unprotected TLV area in a Zephyr image.") # Input file to modify parser.add_argument('input_file', help='Input file (.bin for raw binary or .hex for Intel HEX format)') # Signature values (hex strings) must represent exactly 64 bytes each parser.add_argument( 'signature0', help='Signature 0 as hex string (exactly 128 hex digits, e.g. 0xAA...AA or AA...AA)') parser.add_argument( 'signature1', help='Signature 1 as hex string (exactly 128 hex digits, e.g. 0xAA...AA or AA...AA)') # Optional output file path parser.add_argument( '-o', '--output', help='Output file (defaults to input_inserted.[bin|hex])') args = parser.parse_args() # Validate input file extension ext = os.path.splitext(args.input_file)[1].lower() if ext not in ['.bin', '.hex']: sys.exit("Error: Input file must have .bin or .hex extension") return args def make_tlv_entry(tag, hexstr, enforce_len=None): """ Build a TLV entry with: - 2-byte little-endian type - 2-byte little-endian length - payload bytes If `enforce_len` is set, the payload length must match exactly. """ # Strip optional 0x/0X prefix h = hexstr[2:] if hexstr.lower().startswith('0x') else hexstr # Ensure even number of hex digits if len(h) % 2: h = '0' + h # Convert to bytes val_bytes = bytes.fromhex(h) # Validate fixed length if required if enforce_len is not None and len(val_bytes) != enforce_len: sys.exit( f"Error: TLV for tag 0x{tag:04X} must be exactly {enforce_len} bytes, " f"but got {len(val_bytes)} bytes.") # Pack type and length, then payload return struct.pack('