Пример #1
0
def main():
    '''Main program'''

    # Determine program name, for error messages.
    pgmname = os.path.split(sys.argv[0])[-1]

    # Determine help text width.
    try:
        help_width = int(os.environ['COLUMNS'])
    except (KeyError, ValueError):
        help_width = 80
    help_width -= 2

    parser = argparse.ArgumentParser(
        prog = pgmname,
        formatter_class = argparse.RawDescriptionHelpFormatter,
        description = textwrap.fill(
        "A tool to prepare EFR32 stack hex file for v4.0 to v5.0 upgrade."))

    parser.add_argument("infilespec",
        metavar = "INFILESPEC", help = "stack hex file")
    parser.add_argument("--output", "-o",
        metavar = "OUTFILESPEC",
        help = "output file")

    try:
        args = parser.parse_args()

        memory = hextool.Memory()

        hextool.load_intel_hex(memory, filename = args.infilespec)

        # Move first page off stack just before the v3 bootloader data.
        first_page = memory[memory.min_address:memory.min_address + PAGE_SIZE]
        memory.cursor = FIRST_PAGE_ADDRESS
        memory += first_page
        del memory[memory.min_address:memory.min_address + PAGE_SIZE]

        if args.output is not None:
            # Save output file.
            hextool.save_intel_hex(memory, filename=args.output)
        else:
            hextool.save_intel_hex(memory, filename=args.infilespec)

    except (ValueError, IOError, OSError) as exc:
        sys.stdout.write("%s: %s\n" % (pgmname, exc))

    return 0
Пример #2
0
    def __init__(self, file_spec = None, data = None,
                 version = (0, 0, 0, 0)):
        if file_spec == None and data == None:
            raise ValueError("no data given")
        elif file_spec != None and data != None:
            raise ValueError("file_spec and data are mutually exclusive")

        # Set default values.
        self.area_id = 0x00000000
        self.version = version
        self.compressed = False
        self.encrypted = False

        if data:
            # Data given, make a copy of it.
            self.data = bytearray(data)
            self.raw_data = bytearray(data)
        else:
            # File specification given, parse it.
            version, self.area_id, filename = self.parse_file_spec(file_spec)
            self.version = self.parse_version(version)

            # Read data from file.
            memory = hextool.Memory()
            hextool.load_intel_hex(memory, filename = filename)

            if memory.num_ranges == 0:
                # No data found in file.
                raise ValueError("file contains no data: '%s'" % filename)
            elif (memory.max_address -
                  memory.min_address > self.MAX_NUM_BYTES_PER_FILE):
                raise ValueError("file too big: '%s'" % filename)

            # Convert Memory object to a flat bytearray.
            self.data = memory[memory.min_address:memory.max_address]
            self.raw_data = memory[memory.min_address:memory.max_address]

        # Create a file header for uncompressed, unencrypted data.
        self.header = self.make_file_header(self.area_id, len(self.data),
                                            *self.version)
Пример #3
0
def main():
    '''Main program'''

    # Determine program name, for error messages.
    pgmname = os.path.split(sys.argv[0])[-1]

    # Create a parser for parsing the command line and printing error messages.
    parser = create_argument_parser(pgmname)

    try:
        # Parse command line arguments.
        args = parse_arguments(parser)

        # Parse configuration file.
        config = BootloaderConfig.from_ini_files(args.configfile, args.symbols)

        # Check that config is valid
        # ValueError exception will be raised in case of invalid config
        config.check_config()

        # Check the key chosen is declared
        try:
            chosenkey = config.keys[args.keyname]
        except KeyError:
            raise ValueError("key not found: '%s'" % args.keyname)

    except (ValueError, IOError, OSError, configparser.Error) as exc:
        sys.stdout.write("%s: %s\n" % (pgmname, exc))
        return 1

    if False:
        # DEBUG: Show config.
        for key in config.keys.items():
            print(key)

    # Create a Memory object for storing the bootloader.
    bootloader = hextool.Memory()

    if args.bootloader:
        # Read bootloader.
        hextool.load_intel_hex(bootloader, filename=args.bootloader)

    in_files = []  # List of InFile objects
    # (header, area_id, version, data)
    scratchpad_data = []  # List of scratchpad data blocks
    ver_major, ver_minor, ver_maint, ver_devel = (0, 0, 0, 0)

    if AES_TEST:
        # Run AES test. See aes_test1() in utils/aes.c for details.
        in_files.append(InFile(data=test_data))
        scratchpad_data.append(test_icb)
    elif CMAC_TEST:
        # Run CMAC / OMAC1 test. See aes_omac1_test1()
        # in utils/aes.c for details.
        scratchpad_data.append(test_data)
    else:
        # Read input files.
        try:
            for file_spec in args.infilespec:
                # Create an InFile object.
                in_file = InFile(file_spec=file_spec,
                                 version=(0, 0, 0, args.otapseq))

                # Compress data in-place.
                in_file.compress()

                in_files.append(in_file)
        except (ValueError, IOError, OSError) as exc:
            sys.stdout.write("%s: %s\n" % (pgmname, exc))
            return 1

        # Create secure header, which is also the initial counter block (ICB).
        secure_header = get_random_bytes(16)
        scratchpad_data.append(secure_header)

    if not CMAC_TEST:
        try:
            # Create an AES Counter (CTR) mode cipher using secure
            # header as the 16-byte initial counter block (ICB).
            cipher = create_cipher(secure_header, chosenkey.encryption)

            # Encrypt each input file.
            for in_file in in_files:
                # Encrypt data in-place.
                in_file.encrypt(cipher)

                # Add file header to scratchpad data.
                scratchpad_data.append(in_file.header)

                # Add compressed, encrypted file data to scratchpad data.
                scratchpad_data.append(in_file.data)
        except ValueError as exc:
            sys.stdout.write("%s: %s\n" % (pgmname, exc))
            return 1

    # Calculate and add CMAC / OMAC1 tag.
    try:
        cmac = calculate_cmac(scratchpad_data, chosenkey.authentication)
        scratchpad_data.insert(0, cmac)
    except ValueError as exc:
        sys.stdout.write("%s: %s\n" % (pgmname, exc))
        return 1

    if not AES_TEST and not CMAC_TEST:
        # Create a scratchpad header.
        try:
            scratchpad_header = make_scratchpad_header(args.otapseq,
                                                       scratchpad_data)
        except ValueError as exc:
            sys.stdout.write("%s: %s\n" % (pgmname, exc))
            return 1
    else:
        scratchpad_header = bytes()

    # Write output file and optionally the programming image file.
    try:
        with open(args.outfile, "wb") as f:
            # A combi scratchpad file starts with a 16-byte tag.
            f.write(SCRATCHPAD_V1_TAG)

            # Combi scratchpad files have the scratchpad header in front of
            # the scratchpad contents. The firmware rearranges the data in
            # Flash memory while storing the scratchpad.
            f.write(scratchpad_header)

            # Write scratchpad contents.
            for data in scratchpad_data:
                f.write(data)

        if args.genprog == None:
            return 0

        # Combine bootloader, memory area specification, keys and scratchpad.
        file_without_scr = args.genprog.rsplit('.',1)[0] + \
                           "_without_scratchpad.hex"

        if config.is_scratchpad_internal():
            # Generate a programming image (bootloader + scratchpad file)
            # and save it as Intel HEX.
            memory = gen_prog_image(config, bootloader, scratchpad_header,
                                    scratchpad_data)
            hextool.save_intel_hex(memory, filename=args.genprog)

            # Also generate a programming image without scratchpad
            # (bl+stack+app) for debug purposes and save it as Intel HEX.
            memory = gen_prog_image_without_scratchpad(config, bootloader,
                                                       scratchpad_data,
                                                       in_files)
            hextool.save_intel_hex(memory, filename=file_without_scr)

        else:  # config.is_scratchpad_internal():
            # Generate a programming image without scratchpad (bl+stack+app).
            # and save it as Intel HEX.
            memory = gen_prog_image_without_scratchpad(config, bootloader,
                                                       scratchpad_data,
                                                       in_files)
            hextool.save_intel_hex(memory, filename=file_without_scr)

    except (ValueError, IOError, OSError) as exc:
        sys.stdout.write("%s: %s\n" % (pgmname, exc))
        return 1

    return 0
Пример #4
0
 def __init__(self, config, bootloader):
     self.config = config
     bl_without_config = hextool.Memory()
     hextool.load_intel_hex(bl_without_config, filename=bootloader)
     self.bootloader = self.gen_bootloader(bl_without_config)
     self.infiles = []  # List of data blocks
Пример #5
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# hextoarray32.py - A tool to convert an hex file to an array of 32-bit numbers

import sys
import os
import struct
import hextool

LINE_INDENT = "    "
LINE_LENGTH = 72

# Open hex file and convert it to byte array
memory = hextool.Memory()
hextool.load_intel_hex(memory, filename=sys.argv[1])
# For EFR32 delete range in special registers [0xfe04000-0xfe04200]
del memory[0xfe04000:0xfe04200]
data = memory[memory.min_address:memory.max_address]

# Open outfile and write uint32 array
with open(sys.argv[2], "w") as f:
    line = LINE_INDENT

    for pos in range(0, len(data), 4):
        if pos != 0:
            line += ", "

        if len(line) >= LINE_LENGTH:
            f.write(line)
            f.write("\n")