def __init__(self, dev_type, dev_rev, app_ver, sd_ver, key_file, image_file):
     self.DeviceType         = dev_type
     self.DeviceRevision     = dev_rev
     self.ApplicationVersion = app_ver
     self.SoftDeviceVersions = sd_ver
     self.HMAC               = ""
     self.init_pkt           = ""
     
     # Generate bin file
     bin_file = StringIO.StringIO()
     hex2bin(image_file, bin_file)
     
     fkey      = open(key_file, "r")
     self.key  = fkey.read().strip()
     self.msg  = bin_file.getvalue()
     
     if len(self.key) < 32:
         print "ERROR: Expected key length 32, but got key length " + str(len(self.key))
         exit(1)
     
     self.HMAC      = self.GenerateHMAC(self.key, self.msg, image_file.replace("hex","bin"))
     self.init_pkt += self.GenerateInitPkt()
     self.init_pkt += self.HMAC
     
     fkey.close()
Exemplo n.º 2
0
 def uploadHex (self, file):
     buffer = BytesIO ()
     intelhex.hex2bin (file, buffer)
     bin = buffer.getvalue ()
     self.uploadFlash (0, bin)
     if self.downloadFlash (0, len (bin)) != bin:
         raise IOError (_('Verification failed'))
Exemplo n.º 3
0
    def program_device(firmware_path, port):
        filename, file_extension = os.path.splitext(firmware_path)
        if file_extension == '.hex':
            hex2bin(firmware_path, filename + '.binary')
            firmware_path = filename + '.binary'

        ser = serial.Serial(port=port,
                            baudrate=115200,
                            parity=serial.PARITY_NONE,
                            stopbits=serial.STOPBITS_ONE,
                            timeout=0.1)
        ser.write(b"system bootloader\r\n")
        ser.close()
        time.sleep(0.1)

        loader = Stm32Loader()
        loader.configuration['data_file'] = firmware_path
        loader.configuration['port'] = port
        loader.configuration['erase'] = True
        loader.configuration['write'] = True
        loader.configuration['verify'] = True
        loader.configuration['go_address'] = 0x08000000
        loader.configuration['baud'] = 115200

        loader.connect()
        loader.read_device_details()

        time.sleep(0.1)
        loader.perform_commands()
        loader.reset()
Exemplo n.º 4
0
def hex_to_bin():
    # hex文件转成bin文件
    hex_file_name, bin_file_name = get_hex_file_name()
    hex_file_path = os.path.join(file_path, hex_file_name)
    bin_file_path = os.path.join(file_path, bin_file_name)
    hex2bin(hex_file_path, bin_file_path, start, end, size, pad)
    return bin_file_path
    def __init__(self, dev_type, dev_rev, app_ver, sd_ver, key_file,
                 image_file):
        self.DeviceType = dev_type
        self.DeviceRevision = dev_rev
        self.ApplicationVersion = app_ver
        self.SoftDeviceVersions = sd_ver
        self.HMAC = ""
        self.init_pkt = ""

        # Generate bin file
        bin_file = StringIO.StringIO()
        hex2bin(image_file, bin_file)

        fkey = open(key_file, "r")
        self.key = fkey.read().strip()
        self.msg = bin_file.getvalue()

        if len(self.key) < 32:
            print "ERROR: Expected key length 32, but got key length " + str(
                len(self.key))
            exit(1)

        self.HMAC = self.GenerateHMAC(self.key, self.msg,
                                      image_file.replace("hex", "bin"))
        self.init_pkt += self.GenerateInitPkt()
        self.init_pkt += self.HMAC

        fkey.close()
Exemplo n.º 6
0
 def upload_hex (self, file):
     print ('Uploading firmware...')
     buffer = BytesIO ()
     intelhex.hex2bin (file, buffer)
     bin = buffer.getvalue ()
     self.upload_flash (0, bin)
     print ('Verifying...')
     if self.download_flash (0, len (bin)) != bin:
         raise IOError ('Verification failed')
     print ('Done.')
Exemplo n.º 7
0
 def upload_hex(self, file):
     print('Uploading firmware...')
     buffer = BytesIO()
     intelhex.hex2bin(file, buffer)
     bin = buffer.getvalue()
     self.upload_flash(0, bin)
     print('Verifying...')
     if self.download_flash(0, len(bin)) != bin:
         raise IOError('Verification failed')
     print('Done.')
Exemplo n.º 8
0
    def sign_image(self, hex_file, image_id):
        """
        Signs hex file with the key specified in the policy file.
        Converts binary file of the signed image.
        Creates copy of unsigned hex file.
        Encrypts UPGRADE image if the policy file contains encryption key
        :param hex_file: The hex file to sign.
        :param image_id: The ID of the firmware in policy file.
        :return: Path to the signed files. One file per slot.
        """
        result = []
        slot = self.parser.get_slot(image_id)
        for image in slot['resources']:
            # Sign BOOT image and encrypt+sign UPGRADE image
            if 'encrypt' in slot and slot['encrypt'] and image[
                    'type'] == ImageType.UPGRADE.name:
                hex_out = self.encrypt_image(slot, image['type'],
                                             unsigned_boot_hex)
            else:
                if image['type'] == ImageType.UPGRADE.name:
                    if 'upgrade' not in slot or not slot['upgrade']:
                        continue  # skip generating hex file for UPGRADE slot if it is disabled

                # Preserve hex file for cm4 image
                if slot['id'] == self.memory_map.NSPE_IMAGE_ID:
                    out_cm4_hex = '{0}_{2}{1}'.format(
                        *os.path.splitext(hex_file) + ('cm4', ))
                    copy2(hex_file, out_cm4_hex)

                # Sign image
                if image['type'] == ImageType.BOOT.name:
                    unsigned_boot_hex = '{0}_{2}{1}'.format(
                        *os.path.splitext(hex_file) + ('unsigned', ))
                    copy2(hex_file, unsigned_boot_hex)
                    hex_out = self.sign_single_hex(slot, image['type'],
                                                   hex_file, hex_file)

                # Produce hex file for slot1
                if image['type'] == ImageType.UPGRADE.name:
                    output_name = '{0}_{2}{1}'.format(
                        *os.path.splitext(hex_file) + ('upgrade', ))
                    hex_out = self.sign_single_hex(slot, image['type'],
                                                   unsigned_boot_hex,
                                                   output_name)
                    bin_out = '{0}.bin'.format(os.path.splitext(hex_out)[0])
                    hex2bin(hex_out, bin_out)
                    bin2hex(bin_out, output_name, offset=int(image['address']))
                    os.remove(bin_out)
                    logger.info(f'Image UPGRADE: {hex_out}\n')

                # Replace input hex file with the
            result.append(hex_out)
        os.remove(unsigned_boot_hex)
        result = tuple(result) if len(result) > 0 else None
        return result
Exemplo n.º 9
0
    def test_binary_verify(self, device):
        """Creates a binary image from the hex image and tries to flash the
        device.

        Checks two test cases:
        1) fails when trying to verify binary image with
            'bin' bool set to False;
        2) passes when trying to verify binary image with
            'bin' bool set to True;
        """
        # Ensure image is a hex file
        assert device['image'].endswith(".hex")
        hex_path = device['image']
        bin_path = hex_path[:-3] + "bin"

        # Convert .hex image to .bin
        intelhex.hex2bin(hex_path, bin_path)

        # Basic Binary Test
        result = tiflash.flash(bin_path,
                               binary=True,
                               serno=device['serno'],
                               connection=device['connection'],
                               devicetype=device['devicetype'])

        if result is False:
            pytest.skip("Flashing of image needs to work in order for this"
                        "test to run")

        result = tiflash.verify(bin_path,
                                binary=True,
                                serno=device['serno'],
                                connection=device['connection'],
                                devicetype=device['devicetype'])
        assert result is True

        # Verifying binary without specifying binary=True
        with pytest.raises(tiflash.TIFlashError):
            result = tiflash.verify(bin_path,
                                    binary=True,
                                    serno=device['serno'],
                                    connection=device['connection'],
                                    devicetype=device['devicetype'])

        # Verifying hex image with specifying binary image = True
        with pytest.raises(tiflash.TIFlashError):
            result = tiflash.verify(hex_path,
                                    binary=True,
                                    serno=device['serno'],
                                    connection=device['connection'],
                                    devicetype=device['devicetype'])
Exemplo n.º 10
0
    def test_binary_verify(self, device):
        """Creates a binary image from the hex image and tries to flash the
        device.

        Checks two test cases:
        1) fails when trying to flash binary image with
            'bin' bool set to False;
        2) passes when trying to flash binary image with
            'bin' bool set to True;
        """
        # Ensure image is a hex file
        assert device['image'].endswith(".hex")
        hex_path = device['image']
        bin_path = hex_path[:-3] + "bin"

        # Convert .hex image to .bin
        intelhex.hex2bin(hex_path, bin_path)

        # Basic Binary Flash
        cmd = get_cmd_with_device_params(device)

        cmd.extend(["flash", "\"%s\"" % bin_path, "--bin"])
        cmd_str = " ".join(cmd)

        subprocess.check_call(cmd_str, shell=True)

        # Basic Binary Verify
        cmd = get_cmd_with_device_params(device)

        cmd.extend(["verify", "\"%s\"" % bin_path, "--bin"])
        cmd_str = " ".join(cmd)

        subprocess.check_call(cmd_str, shell=True)

        # Verifying binary without specifying binary=True
        cmd = get_cmd_with_device_params(device)

        cmd.extend(["verify", "\"%s\"" % bin_path])
        cmd_str = " ".join(cmd)

        subprocess.check_call(cmd_str, shell=True)

        # Verify hex image with specifying binary image = True
        with pytest.raises(subprocess.CalledProcessError):
            cmd = get_cmd_with_device_params(device)

            cmd.extend(["verify", "\"%s\"" % hex_path, "--bin"])
            cmd_str = " ".join(cmd)

            subprocess.check_call(cmd_str, shell=True)
Exemplo n.º 11
0
def getStackImgRange(projdir, stackHexFileName, boundary_address, outputPath):
    stack_boundary, flash_limit = getStackRange(boundary_address)

    # Generate binary file
    if stackHexFileName.endswith('.hex'):
        outfileStackPath = os.path.abspath(stackHexFileName[:-4] + ".bin")
    else:
        raise Exception("Stack hex not valid")

    intelhex.hex2bin(stackHexFileName, outfileStackPath, start=stack_boundary,
                     end=flash_limit)

    # Get the image range
    imgRange = imgBinUtil.getImgRange([outfileStackPath, imgStartOffset,
                                      imgEndOffset, imgLenOffset])

    return imgRange
Exemplo n.º 12
0
def createTgtBinfile(projType, projdir, binaryFileType, appHexFileName,
                     tgtBdFileName, outputPath):
    # Find boundary
    if projType == 'ccs':
        boundary_address = getBoundary_CCS(projdir)
    else:
        boundary_address = getTgtBoundary(tgtBdFileName)


    stack_boundary, flash_limit = getStackRange(boundary_address)

    flash_path = os.path.join(projdir, appHexFileName)
    outfileTargetPath = os.path.abspath(outputPath + ".bin")

    intelhex.hex2bin(flash_path, outfileTargetPath, start=stack_boundary,
                     end=flash_limit)

    imgBinUtil.updateImageLen([outfileTargetPath, imgStartOffset, imgEndOffset,
                               imgLenOffset])
    computeCRC32.computeCRC32([outfileTargetPath, '12', '8'])
Exemplo n.º 13
0
 def send_file(self):
     """
         Отправка файла в COM порт. 
     """
     try:  #Проверка на скорость передачи
         self.boud = self.listWidget_2.currentItem().text()
     except:
         buttonReply = QtWidgets.QMessageBox.warning(
             self, 'Ошибка', "Выберите скорость предачи.",
             QtWidgets.QMessageBox.Ok)
     try:  #Проверка на выбранный порт
         self.com_port = self.listWidget.currentItem().text()
     except:
         buttonReply = QtWidgets.QMessageBox.warning(
             self, 'Ошибка', "Выберите COM порт.", QtWidgets.QMessageBox.Ok)
     if not self.path_file:  #Проверка на выбранный файл
         buttonReply = QtWidgets.QMessageBox.warning(
             self, 'Ошибка', "Выберите файл для прошивки.",
             QtWidgets.QMessageBox.Ok)
     else:
         if self.path_file.endswith('.hex'):  #Если файл hex
             in_file = self.path_file
             out_file = '{0}.bin'.format(self.path_file.split('.')[0])
             hex2bin(in_file, out_file)  #Конвертирование
         else:
             out_file = self.path_file
         ser = serial.Serial()  #Создаем экземпляр подключения к порту
         ser.baudrate = int(self.boud)  #Задаем скорость передачи
         ser.port = self.com_port  #Задаем порт для подключения
         if not ser.is_open:
             ser.open()  # Если не открыт порт, то открываем.
         with open(out_file, "rb") as f:
             byte = f.read(16)
             while byte != b'':  # Окончание бинарного файла
                 byte = f.read(16)
                 ser.write(byte)
         ser.close()  #Закрываем порт
         buttonReply = QtWidgets.QMessageBox.question(
             self, 'Успешно', "Отправка данных успешно завершена",
             QtWidgets.QMessageBox.Ok)  #Выводим сообщение об отправке
Exemplo n.º 14
0
def convert_file_format(filename,
                        firmware_version='0100',
                        firmware_type='APP',
                        module_number='',
                        start=None,
                        end=None,
                        size=None):
    """convert hexadecimal format to binary format"""
    (fname, ext) = os.path.splitext(filename)
    bin_file = fname + "_" + firmware_type + ".bin"
    with open(filename,
              'rb' if ext == '.bin' else 'rt') as fin, open(bin_file,
                                                            'wb') as fout:
        if firmware_type.upper().startswith('DSP'):
            if ext == '.txt':
                convert_dsp_file_format(fin, fout)
            elif ext == '.bin':
                convert_binary_dsp_file(fin, fout)
        else:
            hex2bin(fin, fout, start, end, size, pad=0xFF)

    append_vendor_info(bin_file, firmware_version, firmware_type, start,
                       module_number)
Exemplo n.º 15
0
        if len(args) > 2:
            raise getopt.GetoptError('Too many arguments')

    except getopt.GetoptError, msg:
        txt = 'ERROR: '+str(msg)  # that's required to get not-so-dumb result from 2to3 tool
        print(txt)
        print(usage)
        sys.exit(2)

    fin = args[0]
    if not os.path.isfile(fin):
        txt = "ERROR: File not found: %s" % fin  # that's required to get not-so-dumb result from 2to3 tool
        print(txt)
        sys.exit(1)

    if len(args) == 2:
        fout = args[1]
    else:
        # write to stdout
        fout = sys.stdout
        # force binary mode for stdout on Windows
        if os.name == 'nt':
            f_fileno = getattr(sys.stdout, 'fileno', None)
            if f_fileno:
                fileno = f_fileno()
                if fileno >= 0:
                    import msvcrt
                    msvcrt.setmode(fileno, os.O_BINARY)

    sys.exit(hex2bin(fin, fout, start, end, size, pad))
Exemplo n.º 16
0
import intelhex
import sys
import os
import struct
"""
	Convert intel hex output from Atmel Studio to binary payloads for ROP.py
"""

args = sys.argv[1:]
if len(args) == 2:
    fin = args[0]
    fout = args[1]

    intelhex.hex2bin(fin, fout, None, None, None, None)

res = ''
with open(fout, 'r') as f:
    first = f.read(1)
    second = f.read(1)
    while second != '':
        res += second + first
        first = f.read(1)
        second = f.read(1)

with open(fout, 'w') as fw:
    fw.write(res)
Exemplo n.º 17
0
def createAppStackBinfile(projType,
                          projdir,
                          binaryFileType,
                          appHexFileName,
                          bdFileName,
                          outputPath,
                          stackHexFileName=None):
    # Find boundary, if there is one
    if (bdFileName is not None):
        if projType == 'ccs':
            boundary_address = getBoundary_CCS(bdFileName)
        else:
            boundary_address = getBoundary(bdFileName)

    if (binaryFileType == 3 or binaryFileType
            == 7):  #Merged App + Stack or app + stack library
        app_path = os.path.join(projdir, appHexFileName)
        outfileAppPath = os.path.join(projdir, outputPath)
        outfileAppPath = os.path.abspath(outfileAppPath + ".bin")

        # Generate application binary
        intelhex.hex2bin(app_path, outfileAppPath)

        # Get the image range
        if (binaryFileType == 7):
            imgStartOffset = 52  #0x34

        imgRngParams = [
            outfileAppPath, imgStartOffset, imgEndOffset, imgLenOffset
        ]
        imgStAddr, imgEndAddr = imgBinUtil.getImgRange(imgRngParams)
        #pad end if it is not word aligned
        imgLen = imgEndAddr - imgStAddr + 1
        if (imgLen & 3):
            imgEndAddr = imgEndAddr - (imgLen & 3) + 4

        # Run the hex2bin to get correct length binary image
        intelhex.hex2bin(app_path,
                         outfileAppPath,
                         start=imgStAddr,
                         end=imgEndAddr)

        # Update imageLength field
        imgBinUtil.updateImageLen(
            [outfileAppPath, imgStartOffset, imgEndOffset, imgLenOffset])

        if (binaryFileType == 3):
            # Update image segment's length field
            imgBinUtil.updateImageSegLen([
                outfileAppPath, imgStartOffset, imgEndOffset,
                (fixedHdrLen + boundrySegLen + 4), fixedHdrLen + boundrySegLen
            ])
            # Update file type field
            imgBinUtil.fileTypeTag([outfileAppPath, "3", "18"])
        else:
            # Update image segment's length field
            imgBinUtil.updateImageSegLen([
                outfileAppPath, imgStartOffset, imgEndOffset,
                (fixedHdrLen + 4), fixedHdrLen
            ])
            # Update file type field
            imgBinUtil.fileTypeTag([outfileAppPath, "7", "18"])

        # Update crc32 field
        computeCRC32.computeCRC32([outfileAppPath, "12", "8"])

    elif (binaryFileType == 2):  # Stack only
        stack_boundary, flash_limit = getStackRange(boundary_address)

        stack_path = os.path.join(projdir, appHexFileName)
        outfileStackPath = os.path.abspath(stack_path + ".bin")

        # Generate binary file
        outfileStackPath = os.path.join(projdir, outputPath)
        outfileStackPath = outfileStackPath + ".bin"
        intelhex.hex2bin(stack_path,
                         outfileStackPath,
                         start=stack_boundary,
                         end=flash_limit)

        # Get the image range
        args = [outfileStackPath, imgStartOffset, imgEndOffset, imgLenOffset]
        imgStAddr, imgEndAddr = imgBinUtil.getImgRange(args)
        #pad end if it is not word aligned
        imgLen = imgEndAddr - imgStAddr + 1
        if (imgLen & 3):
            imgEndAddr = imgEndAddr - (imgLen & 3) + 4

        # Rerun hex2bin to get correct length of binary image
        intelhex.hex2bin(stack_path,
                         outfileStackPath,
                         start=imgStAddr,
                         end=imgEndAddr)

        imgBinUtil.updateImageLen(
            [outfileStackPath, imgStartOffset, imgEndOffset, imgLenOffset])
        imgBinUtil.updateImageSegLen([
            outfileStackPath, imgStartOffset, imgEndOffset,
            payloadSegLenOffset, fixedHdrLen + boundrySegLen
        ])
        computeCRC32.computeCRC32([outfileStackPath, "12", "8"])

    elif (binaryFileType == 1):
        # Get app image range
        appImgStartAddr, app_boundary = getAppRange(boundary_address)

        # To get the actual stack range, need to build stack binary and then
        # read the image header to find the actual address
        stack_boundary, flash_limit = getStackImgRange(projdir,
                                                       stackHexFileName,
                                                       boundary_address,
                                                       outputPath)

        app_path = os.path.join(projdir, appHexFileName)
        stack_path = os.path.join(projdir, stackHexFileName)

        outfileAppPath = os.path.join(projdir, outputPath) + ".bin"

        # Generate application binary
        intelhex.hex2bin(app_path,
                         outfileAppPath,
                         start=appImgStartAddr,
                         end=app_boundary)

        # Get the image range
        imgRngParams = [
            outfileAppPath, imgStartOffset, imgEndOffset, imgLenOffset
        ]
        imgStAddr, imgEndAddr = imgBinUtil.getImgRange(imgRngParams)

        #pad end if it is not word aligned
        imgLen = imgEndAddr - imgStAddr + 1
        if (imgLen & 3):
            imgEndAddr = imgEndAddr - (imgLen & 3) + 4

        # Rerun the hex2bin to get correct length binary image
        intelhex.hex2bin(app_path,
                         outfileAppPath,
                         start=imgStAddr,
                         end=imgEndAddr)

        # Update file type field
        imgBinUtil.fileTypeTag([outfileAppPath, "1", "18"])

        print "outfileAppPath: " + str(
            outfileAppPath) + "imgStartOffset: " + str(
                imgStartOffset) + "imgEndOffset" + str(
                    imgEndOffset) + "imgLenOffset" + str(imgLenOffset)
        # Update imageLength field
        imgBinUtil.updateImageLen(
            [outfileAppPath, imgStartOffset, imgEndOffset, imgLenOffset])

        # Update image segment's length field
        imgBinUtil.updateImageSegLen([
            outfileAppPath, imgStartOffset, imgEndOffset, payloadSegLenOffset,
            fixedHdrLen + boundrySegLen
        ])

        # Update crc32 field
        computeCRC32.computeCRC32([outfileAppPath, "12", "8"])

        # Generate merged binary
        flashRange = str(hex(appImgStartAddr)) + ':' + str(hex(flash_limit))

        mergedBinLen = getMergeBinLen(flashRange)

        # Create IntelHex objects for each hex
        appHex = intelhex.IntelHex(app_path)
        stackHex = intelhex.IntelHex(stack_path)

        # Define boundaries for each hex
        appHex = appHex[appImgStartAddr:app_boundary + 1]
        stackHex = stackHex[stack_boundary:flash_limit + 1]

        # Merge hex's
        inputHexFiles = [appHex, stackHex]
        mergedHex = intelhex.IntelHex()
        for hexFile in inputHexFiles:
            try:
                mergedHex.merge(hexFile, overlap="replace")
            except:
                print("Fatal Error: FAILED merge due to overlap when merging")
                sys.exit(1)

        # Define boundaries for merged hex
        mergedHex = mergedHex[appImgStartAddr:flash_limit + 1]

        # Write hex to file
        # mergeHexFilePath = os.path.abspath(outputPath + "_merged.hex")
        # print "mergeHexFilePath:::: " + mergeHexFilePath
        mergeHexFilePath = os.path.join(projdir, outputPath) + "_merged.hex"
        mergedHex.write_hex_file(mergeHexFilePath)

        # Convert hex to bin
        outFileMergedPath = os.path.join(projdir, outputPath) + "_merged.bin"

        intelhex.hex2bin(mergeHexFilePath,
                         outFileMergedPath,
                         start=appImgStartAddr,
                         end=flash_limit)
        imgBinUtil.fileTypeTag([outFileMergedPath, "3", "18"])

        # Update imageLength field
        imgBinUtil.updateMergedImageLen(
            [outFileMergedPath, mergedBinLen, imgLenOffset])
        args = [
            outFileMergedPath, mergedBinLen, imgEndOffset, payloadSegLenOffset
        ]
        imgBinUtil.updateMergedImageSegLen(args)

        mergedImgEndAddr = getMergeBinEndAddr(flashRange)

        imgBinUtil.updateMergedImageEndAddr(
            [outFileMergedPath, mergedImgEndAddr, imgEndOffset])

        # Add crc32 bytes
        computeCRC32.computeCRC32([outFileMergedPath, "12", "8"])
Exemplo n.º 18
0
def sign_image(toolchain, binf):
    """
    Adds signature to a binary file being built,
    prepares some intermediate binary artifacts.
    :param toolchain: Toolchain object of current build session
    :param binf: Binary file created for target
    """
    from pathlib import PurePath

    target_sig_data = None
    # reserve name for separate NSPE image
    out_cm4_hex = binf[:-4] + "_cm4.hex"

    # preserve original hex file from mbed-os build
    mbed_hex = binf[:-4] + "_unsigned.hex"
    copy2(binf, mbed_hex)

    # find target name and type before processing
    for part in PurePath(binf).parts:
        if "CY" in part:
            target_sig_data = process_target(toolchain=toolchain, target=part)

    if target_sig_data is None:
        toolchain.notify.debug("[PSOC6.sign_image] ERROR: Target not found!")
        raise AddSignatureError(
            "PSOC6.sign_image finished execution with errors! Signature is not added."
        )

    for slot in target_sig_data:
        # first check if image for slot under processing should be encrypted
        if slot["slot_data"].get("encrypt") is True:
            # call encrypt_img to perform encryption
            args = [
                sys.executable,
                str(slot["sdk_path"] / "encrypted_image_runner.py"),
                "--sdk-path",
                str(slot["sdk_path"]), "--hex-file",
                os.getcwd() + '/' + mbed_hex, "--key-priv",
                str(slot["sdk_path"] / slot["key_file"]), "--key-pub",
                str(slot["sdk_path"] / slot["dev_pub_key"]), "--key-aes",
                str(slot["sdk_path"] / slot["aes_key"]), "--ver",
                str(slot["img_data"]["VERSION"]), "--img-id",
                str(slot["id"]), "--rlb-count",
                str(slot["img_data"]["ROLLBACK_COUNTER"]), "--slot-size",
                str(hex(slot["slot_data"]["size"])), "--img-offset",
                str(slot["slot_data"]["address"])
            ]
            if slot["slot_data"]["type"] != "BOOT":
                args.append("--pad")
            process = subprocess.Popen(args,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)

            # catch standard process pipes outputs
            stderr = process.communicate()[1]
            stdout = process.communicate()[0]
            rc = process.wait()
            toolchain.notify.info(stdout.decode("utf-8"))

            if rc != 0:
                toolchain.notify.debug(
                    "[PSOC6.sign_image] ERROR: Encryption script ended with error!"
                )
                toolchain.notify.debug(
                    "[PSOC6.sign_image] Message from encryption script: " +
                    stderr.decode("utf-8"))
                raise AddSignatureError(
                    "PSOC6.sign_image finished execution with errors! Signature is not added."
                )
            else:
                toolchain.notify.info(
                    "[PSOC6.sign_image] SUCCESS: Image for slot " +
                    slot["slot_data"]["type"] +
                    " is signed and encrypted with no errors!")
        # all non ecrypted images take this path
        else:
            if slot["slot_data"]["type"] == "UPGRADE":
                out_hex_name = binf[:-4] + "_upgrade.hex"
            else:
                out_hex_name = binf

            out_bin_name = out_hex_name[:-4] + "_signed.bin"

            # call imgtool for signature
            args = [
                sys.executable,
                str(slot["sdk_path"] / "imgtool/imgtool.py"), "sign", "--key",
                str(slot["sdk_path"] / slot["key_file"]), "--header-size",
                str(hex(MCUBOOT_HEADER_SIZE)), "--pad-header", "--align", "8",
                "--version",
                str(slot["img_data"]["VERSION"]), "--image-id",
                str(slot["id"]), "--rollback_counter",
                str(slot["img_data"]["ROLLBACK_COUNTER"]), "--slot-size",
                str(hex(slot["slot_data"]["size"])), "--overwrite-only",
                mbed_hex, out_hex_name
            ]
            if slot["slot_data"]["type"] != "BOOT":
                args.append("--pad")
            process = subprocess.Popen(args,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)

            # catch stderr outputs
            stderr = process.communicate()[1]
            rc = process.wait()

            if rc != 0:
                toolchain.notify.debug(
                    "[PSOC6.sign_image] ERROR: Signature is not added!")
                toolchain.notify.debug(
                    "[PSOC6.sign_image] Message from imgtool: " +
                    stderr.decode("utf-8"))
                raise AddSignatureError(
                    "PSOC6.sign_image finished execution with errors! Signature is not added."
                )
            else:
                toolchain.notify.info(
                    "[PSOC6.sign_image] SUCCESS: Image for slot " +
                    slot["slot_data"]["type"] + " is signed with no errors!")
            # preserve signed binary file
            hex2bin(out_hex_name, out_bin_name)

            # preserve separate hex for cm4
            # 16 is image ID for NSPE image
            if slot["id"] == NSPE_IMAGE_ID:
                copy2(out_hex_name, out_cm4_hex)

            # produce hex file for slot1
            if slot["slot_data"]["type"] == "UPGRADE":
                bin2hex(out_bin_name,
                        out_hex_name,
                        offset=int(slot["slot_data"]["address"]))
                toolchain.notify.info("Image UPGRADE: " + out_hex_name + "\n")
Exemplo n.º 19
0
def main(sdk_path, hex_file, key_priv, key_pub, key_aes, version, img_id,
         rlb_count, slot_size, pad, img_offset):
    """
    Function consequentially performs operations with provided hex file
    and produces an encrypted and signed hex file for UPGRADE
    """

    check_file_exist(key_priv)
    check_file_exist(key_pub)
    check_file_exist(key_aes)
    check_file_exist(hex_file)

    in_f = '{0}_{2}.bin'.format(*os.path.splitext(hex_file) + ('i', ))
    out_f = '{0}_{2}.bin'.format(*os.path.splitext(hex_file) + ('o', ))

    hex_file_final = get_final_hex_name(hex_file)
    print("Image UPGRADE:" + hex_file_final)

    hex2bin(hex_file, in_f)

    # call imgtool for signature
    process = subprocess.Popen([
        sys.executable,
        os.path.join(sdk_path, "../imgtool/imgtool.py"), "sign", "--key",
        key_priv, "--header-size",
        str(hex(HEADER_SIZE)), "--pad-header", "--align", "8", "--version",
        version, "--image-id", img_id, "--rollback_counter", rlb_count,
        "--slot-size", slot_size, "--overwrite-only", in_f, out_f
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    manage_output(process, in_f, out_f)

    # call aesHeader for crypto header generation
    process = subprocess.Popen([
        sys.executable,
        os.path.join(sdk_path, "../imgtool/create_aesHeader.py"), "-k",
        key_priv, "-p", key_pub, "--key_to_encrypt", key_aes, AES_HEADER
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)

    # catch stderr outputs
    process.communicate()
    process.wait()
    check_file_exist(AES_HEADER)

    # aes_cipher.py script file should be in the same folder as imgtool.py
    # encrypt signed image
    process = subprocess.Popen([
        sys.executable,
        os.path.join(sdk_path, "../imgtool/aes_cipher.py"), "-k", key_aes,
        out_f, in_f
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    manage_output(process, out_f, in_f)

    # second part - obtain signed image from encrypted file - with padding - for staging area
    # call imgtool for signature
    process = subprocess.Popen([
        sys.executable,
        os.path.join(sdk_path, "../imgtool/imgtool.py"), "sign", "--key",
        key_priv, "--header-size",
        str(hex(HEADER_SIZE)), "--pad-header", "--align", "8", "--version",
        version, "--image-id", img_id, "--rollback_counter", rlb_count,
        "--slot-size", slot_size, "--overwrite-only", "--pad", "-a",
        AES_HEADER, in_f, out_f
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    manage_output(process, in_f, out_f)

    bin2hex(out_f, hex_file_final, int(img_offset))
    os.remove(out_f)
    os.remove(AES_HEADER)
Exemplo n.º 20
0
    def on_mergeButton_clicked(self):
        #error
        tmpFirstHex = self.firstlineEdit.text()
        tmpSecondHex = self.secondlineEdit.text()
        if (tmpFirstHex == '' or tmpSecondHex == ''):
            #print('error')
            errInput = QtGui.QMessageBox.warning(self, '提示', "请选择两个hex文件,注意顺序",
                                                 QtGui.QMessageBox.Ok,
                                                 QtGui.QMessageBox.Ok)
            if errInput == QtGui.QMessageBox.Yes:
                return

            #自定义对话框
            #customMsgBox=QtGui.QMessageBox(self)
            #customMsgBox.setWindowTitle("提示")
            #customMsgBox.addButton("确定", QtGui.QMessageBox.ActionRole)
            #customMsgBox.addButton(self.tr("解锁"), QtGui.QMessageBox.ActionRole)
            #customMsgBox.addButton("cancel",QtGui.QMessageBox.ActionRole)

            #customMsgBox.setText("请选择两个hex文件,注意顺序!")
            #customMsgBox.exec_()
        else:
            #firstHex = os.path.basename(self.firstlineEdit.text())
            #secondHex = os.path.basename(self.secondlineEdit.text())
            curFirstPath = os.path.abspath(self.firstlineEdit.text())
            curSecondPath = os.path.abspath(self.secondlineEdit.text())

            #get file name
            #tmp_name = os.path.basename(firstHex)
            binfile1 = curFirstPath[0:-4] + '.bin'
            #tmp_name = os.path.basename(secondHex)
            binfile2 = curSecondPath[0:-4] + '~' + '.bin'

            binfile_name = curSecondPath[0:-4] + '.bin'
            if (os.path.isfile(binfile_name)):
                os.remove(binfile_name)

            #hex to bin
            self.statustextBrowser.setText("Hex to Bin and Merge Bin file....")
            self.statustextBrowser.append("Hex File To Bin File...")
            self.statustextBrowser.append("*****************************")
            #self.statustextBrowser.append(firstHex)
            #self.statustextBrowser.append(secondHex)
            self.statustextBrowser.append(curFirstPath)
            self.statustextBrowser.append(curSecondPath)
            self.statustextBrowser.append(binfile1)
            self.statustextBrowser.append(binfile2)

            self.statustextBrowser.append("*****************************")
            #self.statustextBrowser.append("")

            intelhex.hex2bin(curFirstPath, binfile1, None, None, None, 00)
            intelhex.hex2bin(curSecondPath, binfile2, None, None, None, 00)

            self.statustextBrowser.append("Hex File To Bin File completly")

            #merge two files
            self.statustextBrowser.append(binfile1)
            self.statustextBrowser.append(binfile2)

            bin_boot_len = os.path.getsize(binfile1)
            bin_app_len = os.path.getsize(binfile2)
            self.statustextBrowser.append("First Bin File size is %d" %
                                          (bin_boot_len))
            self.statustextBrowser.append("Second Bin File size is %d" %
                                          (bin_app_len))

            bin_boot_file = open(binfile1, 'rb')
            bin_app_file = open(binfile2, 'rb')
            bin_file = open(binfile_name, 'ab')

            for h in bin_boot_file.readlines():
                #print(h)
                bin_file.write(h)

            bin_file.seek(2)
            bin_app_file.seek(bin_boot_len, 0)
            for h in bin_app_file.readlines():
                #print(h)
                bin_file.write(h)

            bin_boot_file.close()
            bin_app_file.close()
            bin_file.close()

            bin_file_len = os.path.getsize(binfile_name)
            self.statustextBrowser.append("Bin File size is %d " %
                                          bin_file_len)
            self.statustextBrowser.append("")
Exemplo n.º 21
0
    def sign_image(self,
                   hex_file,
                   image_id,
                   image_type,
                   encrypt_key=None,
                   erased_val=None,
                   boot_record='default'):
        """
        Signs hex file with the key specified in the policy file.
        Converts binary file of the signed image.
        Creates copy of unsigned hex file.
        Encrypts UPGRADE image if the policy file contains encryption key
        :param hex_file: The hex file to sign.
        :param image_id: The ID of the firmware in policy file.
        :param image_type: The image type.
        :param encrypt_key: path to public key file for the image encryption
        :param erased_val: The value that is read back from erased flash
        :param boot_record: Create CBOR encoded boot record TLV.
               The sw_type represents the role of the software component
               (e.g. CoFM for coprocessor firmware). [max. 12 characters]
        :return: Path to the signed files. One file per slot.
        """
        result = []
        slot = self.parser.get_slot(image_id)

        if erased_val:
            self.erased_val = erased_val
            ih_padding = int(erased_val, 0)
            logger.warning(f'Custom value {erased_val} will be used as an '
                           f'erased value for all regions and memory types. '
                           f'Typical correct values for internal and '
                           f'external Flash memory are 0x00 and 0xFF '
                           f'respectively.')
        else:
            default_erased_val = self._default_erased_value(image_type, slot)
            ih_padding = int(default_erased_val, 0)

        if slot is None:
            logger.error(
                f'Image with ID {image_id} not found in \'{self.policy_file}\''
            )
            return None
        unsigned_hex = '{0}_{2}{1}'.format(*os.path.splitext(hex_file) +
                                           ('unsigned', ))
        copy2(hex_file, unsigned_hex)

        boot_ih = IntelHex()
        boot_ih.padding = ih_padding
        boot_ih.loadfile(hex_file, 'hex')
        base_addr = boot_ih.minaddr()
        boot_bin = f'{hex_file}.bin'
        hex2bin(boot_ih, boot_bin)

        encrypted_boot = False
        first_image_result = None  # indicates first image signing success
        for image in slot['resources']:
            if image_type:
                if image['type'] != image_type.upper():
                    continue  # skip generating hex file if sign type defined and not same as current image type
            if image['type'] == ImageType.UPGRADE.name:
                if 'upgrade' not in slot or not slot['upgrade']:
                    continue  # skip generating hex file for UPGRADE slot if it is disabled

            encryption = self.parser.encryption_enabled(slot['id'])
            if encryption:
                if encrypt_key is None:
                    encrypt_key = self.parser.encrypt_key(slot['id'])
                    if encrypt_key is None:
                        raise ValueError('Encryption key not specified')
                    else:
                        if not os.path.isfile(encrypt_key):
                            raise FileNotFoundError(
                                f'Encryption key \'{encrypt_key}\' not found')
            else:
                encrypt_key = None

            if image['type'] == ImageType.BOOT.name:
                if first_image_result is False:
                    continue

                hex_out = self.sign_single_hex(slot,
                                               image['type'],
                                               boot_bin,
                                               hex_file,
                                               start_addr=base_addr,
                                               boot_record=boot_record,
                                               encrypt_key=encrypt_key)
                encrypted_boot = encrypt_key is not None
                first_image_result = hex_out is not None
                os.remove(boot_bin)
            else:
                if first_image_result is False:
                    continue

                output_name = '{0}_{2}{1}'.format(*os.path.splitext(hex_file) +
                                                  ('upgrade', ))

                hex_out = self.sign_single_hex(slot,
                                               image['type'],
                                               unsigned_hex,
                                               output_name,
                                               encrypt_key,
                                               boot_record=boot_record)
                first_image_result = hex_out is not None
                if hex_out:
                    bin_out = '{0}.bin'.format(os.path.splitext(hex_out)[0])

                    if not erased_val:
                        default_erased_val = self._default_erased_value(
                            image_type, slot)
                        ih_padding = int(default_erased_val, 0)

                    upgrade_ih = IntelHex()
                    upgrade_ih.padding = ih_padding
                    upgrade_ih.loadfile(hex_out, 'hex')

                    hex2bin(upgrade_ih, bin_out)
                    bin2hex(bin_out, output_name, offset=int(image['address']))
                    os.remove(bin_out)
            if hex_out:
                result.append(hex_out)

        if encrypted_boot:
            self.replace_image_body(hex_file, unsigned_hex, ih_padding)

        if image_type:
            if ImageType.UPGRADE.name == image_type.upper():
                os.remove(hex_file)
        result = tuple(result) if len(result) > 0 else None

        return result
Exemplo n.º 22
0
    def program(self):
        if not os.path.isfile(
                os.path.join(self.flora_path,
                             DEVKIT_FIRMWARE_PATH + '.binary')):
            hex2bin(
                os.path.join(self.flora_path, DEVKIT_FIRMWARE_PATH + '.hex'),
                os.path.join(self.flora_path,
                             DEVKIT_FIRMWARE_PATH + '.binary'))

        if not os.path.isfile(
                os.path.join(self.flora_path,
                             COMBOARD_FIRMWARE_PATH + '.binary')):
            hex2bin(
                os.path.join(self.flora_path, COMBOARD_FIRMWARE_PATH + '.hex'),
                os.path.join(self.flora_path,
                             COMBOARD_FIRMWARE_PATH + '.binary'))

        self.loader = Stm32Loader()
        self.loader.configuration['data_file'] = DEVKIT_FIRMWARE_PATH
        self.loader.configuration['port'] = self.bootloader.port.device
        self.loader.configuration['erase'] = True
        self.loader.configuration['write'] = True
        self.loader.configuration['verify'] = True
        self.loader.configuration['go_address'] = 0x08000000
        self.loader.configuration['baud'] = 115200

        # self.loader.connect()
        # Connecting manually, as a reset like in self.loader.connect() would not work on DevKit or ComBoard

        self.loader.bootloader = Stm32Bootloader()
        self.loader.bootloader.open(
            self.loader.configuration['port'],
            self.loader.configuration['baud'],
            self.loader.configuration['parity'],
        )

        try:
            self.loader.bootloader.reset_from_system_memory()
        except Exception:
            print("Can't init. Ensure that BOOT0 is enabled and reset device")
            self.loader.bootloader.reset_from_flash()
            return

        try:
            device_id = self.loader.bootloader.get_id()
            self.loader.read_device_details()

            if device_id == 0x415:
                print("{} is DevKit.".format(self.bootloader.port.device))
                self.loader.configuration['data_file'] = os.path.join(
                    self.flora_path, DEVKIT_FIRMWARE_PATH + '.binary')
            elif device_id == 0x435:
                print("{} is ComBoard.".format(self.bootloader.port.device))
                self.loader.configuration['data_file'] = os.path.join(
                    self.flora_path, COMBOARD_FIRMWARE_PATH + '.binary')

            self.loader.perform_commands()

            if device_id == 0x435:
                self.loader.reset()
        finally:
            pass
Exemplo n.º 23
0
def main(sdk_path, hex_file, key_priv, key_pub, key_aes, version, img_id,
         rlb_count, slot_size, pad, img_offset):
    """
    Function consequentially performs operations with provided hex file
    and produces an encrypted and signed hex file for UPGRADE
    """

    check_file_exist(key_priv)
    check_file_exist(key_pub)
    check_file_exist(key_aes)
    check_file_exist(hex_file)

    in_f = hex_file[:-4] + "_i.bin"
    out_f = hex_file[:-4] + "_o.bin"

    hex_file_final = get_final_hex_name(hex_file)
    print("Image UPGRADE:" + hex_file_final)

    # ih = IntelHex(hex_file)
    # img_start_addr = ih.start_addr['EIP']

    hex2bin(hex_file, in_f)  #bin_file)

    # $PYTHON $IMGTOOL sign --key $KEY --header-size $HEADER_SIZE --pad-header --align 8 --version $VERSION --image-id $ID --rollback_counter $ROLLBACK_COUNTER --slot-size $SLOT_SIZE --overwrite-only $binFileName $signedFileName is_file_created $signedFileName

    # call imgtool for signature
    process = subprocess.Popen([
        sys.executable, sdk_path + "/imgtool/imgtool.py", "sign", "--key",
        key_priv, "--header-size",
        str(hex(HEADER_SIZE)), "--pad-header", "--align", "8", "--version",
        version, "--image-id", img_id, "--rollback_counter", rlb_count,
        "--slot-size", slot_size, "--overwrite-only", in_f, out_f
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    manage_output(process, in_f, out_f)

    # AES
    # $PYTHON $(dirname "${IMGTOOL}")"/create_aesHeader.py" -k $KEY -p $KEY_DEV --key_to_encrypt "$KEY_AES" $AES_HEADER
    # call aesHeader for crypto header generation
    process = subprocess.Popen([
        sys.executable, sdk_path + "/imgtool/create_aesHeader.py", "-k",
        key_priv, "-p", key_pub, "--key_to_encrypt", key_aes, AES_HEADER
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)

    # catch stderr outputs
    stderr = process.communicate()
    rc = process.wait()
    check_file_exist(AES_HEADER)

    # aes_cipher.py script file should be in the same folder as imgtool.py
    # $PYTHON $(dirname "${IMGTOOL}")"/aes_cipher.py" -k $KEY_AES $signedFileName $aes_encryptedFileName
    # is_file_created $aes_encryptedFileName
    # encrypt signed image
    process = subprocess.Popen([
        sys.executable, sdk_path + "/imgtool/aes_cipher.py", "-k", key_aes,
        out_f, in_f
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    manage_output(process, out_f, in_f)

    # second part - obtain signed image from encrypted file - with padding - for staging area
    # $PYTHON $IMGTOOL sign --key $KEY --header-size $HEADER_SIZE --pad-header --align 8 --version $VERSION --image-id $ID --rollback_counter $ROLLBACK_COUNTER --slot-size $SLOT_SIZE --overwrite-only $PAD -a $AES_HEADER $aes_encryptedFileName $signedEncFileName
    # is_file_created $signedEncFileName

    # call imgtool for signature
    process = subprocess.Popen(
        [
            sys.executable, sdk_path + "/imgtool/imgtool.py", "sign", "--key",
            key_priv, "--header-size",
            str(hex(HEADER_SIZE)), "--pad-header", "--align", "8", "--version",
            version, "--image-id", img_id, "--rollback_counter", rlb_count,
            "--slot-size", slot_size, "--overwrite-only", "--pad", "-a",
            AES_HEADER, in_f, out_f
        ],
        #bin_sig_enc,
        #bin_sig_enc_sig],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
    manage_output(process, in_f, out_f)

    bin2hex(out_f, hex_file_final, int(img_offset))
    os.remove(out_f)

    os.remove(AES_HEADER)
Exemplo n.º 24
0
        if not args:
            raise getopt.GetoptError('Hex file is not specified')

        if len(args) > 2:
            raise getopt.GetoptError('Too many arguments')

    except getopt.GetoptError:
        msg = sys.exc_info()[1]  # current exception
        txt = 'ERROR: ' + str(
            msg)  # that's required to get not-so-dumb result from 2to3 tool
        print(txt)
        print(usage)
        sys.exit(2)

    fin = args[0]
    if not os.path.isfile(fin):
        txt = "ERROR: File not found: %s" % fin  # that's required to get not-so-dumb result from 2to3 tool
        print(txt)
        sys.exit(1)

    if len(args) == 2:
        fout = args[1]
    else:
        # write to stdout
        from intelhex import compat
        fout = compat.get_binary_stdout()

    from intelhex import hex2bin
    sys.exit(hex2bin(fin, fout, start, end, size, pad))
Exemplo n.º 25
0
def inject_ids(new_school_id, new_hub_id, output_file_path="", clean=False):

    if len(new_school_id) != len(SCHOOL_ID):
        print("New school id length (%d) must match the old (%d)" %
              (len(new_school_id), len(SCHOOL_ID)))
        return -1

    if len(new_hub_id) != len(HUB_ID):
        print("New hub id length (%d) must match the old (%d)" %
              (len(new_hub_id), len(HUB_ID)))
        return -1

    if clean:
        print("Removing old hub file.")
        os.remove(package_directory + "/hexes/hub-not-combined.hex")

    if not os.path.isfile(package_directory + "/hexes/hub-not-combined.hex"):
        try:
            print("Copying latest hub file from: %s" % BUILD_FOLDER_PATH)
            copyfile(BUILD_FOLDER_PATH,
                     package_directory + "/hexes/hub-not-combined.hex")
        except Exception as e:
            print("hub-combined-hex not available")

    with tempfile.NamedTemporaryFile() as hub_not_combined_modified_hex_file, \
            tempfile.NamedTemporaryFile() as hub_not_combined_modified_bin_file, \
                tempfile.NamedTemporaryFile() as temp_out_file:

        # first convert the uncombined hex file into bin
        hex_as_bin = hex2bin(package_directory + "/hexes/hub-not-combined.hex",
                             hub_not_combined_modified_bin_file.name)

        # replace the old ids with the new.
        print("Replacing ids.")
        bin_data = hub_not_combined_modified_bin_file.readlines()
        hub_not_combined_modified_bin_file.seek(0)

        school_id_changed = False
        hub_id_changed = False

        for l in bin_data:
            try:
                new_l = re.sub(bytes(SCHOOL_ID, 'utf-8'),
                               bytes(new_school_id, 'utf-8'), l)
            except:
                new_l = re.sub(SCHOOL_ID, new_school_id, l)

            if new_l != l:
                school_id_changed = True

            try:
                final_l = re.sub(bytes(HUB_ID, 'utf-8'),
                                 bytes(new_hub_id, 'utf-8'), new_l)
            except:
                final_l = re.sub(HUB_ID, new_hub_id, new_l)

            if final_l != new_l:
                hub_id_changed = True

            hub_not_combined_modified_bin_file.write(final_l)

        hub_not_combined_modified_bin_file.flush()

        if not school_id_changed:
            print("School id not found in bin!")
            exit(1)

        if not hub_id_changed:
            print("Hub id not found in bin!")
            exit(1)

        # then to hex
        bin2hex(hub_not_combined_modified_bin_file.name,
                hub_not_combined_modified_hex_file.name, 0x18000)
        replaced_hex = IntelHex(hub_not_combined_modified_hex_file.name)
        bootloader_hex = IntelHex(package_directory + "/hexes/BOOTLOADER.hex")
        softdevice_hex = IntelHex(package_directory + "/hexes/SOFTDEVICE.hex")

        replaced_hex.merge(bootloader_hex)
        replaced_hex.merge(softdevice_hex)

        # finally creating the final binary.
        if len(output_file_path):
            print("Creating final file: %s" % (output_file_path))
            with open(output_file_path, 'w') as f:
                replaced_hex.write_hex_file(f.name)
                f.close()
                return 0
        else:
            sio = StringIO()
            bio = BytesIO()
            try:
                #python 3
                replaced_hex.write_hex_file(sio)
                return sio.getvalue()
            except:
                #python 2
                replaced_hex.write_hex_file(bio)
                return bio.getvalue()