Exemplo n.º 1
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
zf  = zipfile.ZipFile(args.zipfile[0], mode='w',compression=zipfile.ZIP_DEFLATED)
    
if args.application != None:
    bin, dat, key = GenerateBinAndDat(args, "application")
    zf.writestr("application.bin", bin)
    zf.writestr("application.dat", dat)
        
if args.bootloader != None:
    bin, dat, key = GenerateBinAndDat(args, "bootloader")
    zf.writestr("bootloader.bin", bin)
    zf.writestr("bootloader.dat", dat)
        
if args.softdevice != None:
    bin, dat, key = GenerateBinAndDat(args, "softdevice")
    zf.writestr("softdevice.bin", bin)
    zf.writestr("softdevice.dat", dat)

zf.close()

if args.key_output != None:
    key_address = int(args.key_address,16)
    if (key_address == None):
        key_address = 0x0003F800

    key_bin = StringIO.StringIO()
    key_bin.write(key)
    fout = open(args.key_output.replace("hex","bin"), "wb")
    fout.write(key)
    fout.close()
    bin2hex(args.key_output.replace("hex","bin"), args.key_output, key_address)
Exemplo n.º 3
0
 def app_to_hex(self):
     info("Creating ihex from application")
     input_file = os.path.join(self.tab_folder, "cortex-m4.tbf")
     output_file = os.path.join(self.tab_folder, "cortex-m4.hex")
     bin2hex(input_file, output_file, 0x40000)
Exemplo n.º 4
0
 def padding_to_hex(self):
     info("Creating ihex from padding")
     input_file = os.path.join(self.tab_folder, "padding.bin")
     output_file = os.path.join(self.tab_folder, "padding.hex")
     bin2hex(input_file, output_file, 0x30000)
Exemplo n.º 5
0
    def force_stream_binary(stream):
        """Force binary mode for stream on Windows."""
        if os.name == 'nt':
            f_fileno = getattr(stream, 'fileno', None)
            if f_fileno:
                fileno = f_fileno()
                if fileno >= 0:
                    import msvcrt
                    msvcrt.setmode(fileno, os.O_BINARY)

    fin = args[0]
    if fin == '-':
        # read from stdin
        fin = sys.stdin
        force_stream_binary(fin)
    elif 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_stream_binary(fout)

    from intelhex import bin2hex
    sys.exit(bin2hex(fin, fout, offset))
Exemplo n.º 6
0
        sys.exit(2)

    def force_stream_binary(stream):
        """Force binary mode for stream on Windows."""
        if os.name == 'nt':
            f_fileno = getattr(stream, 'fileno', None)
            if f_fileno:
                fileno = f_fileno()
                if fileno >= 0:
                    import msvcrt
                    msvcrt.setmode(fileno, os.O_BINARY)

    fin = args[0]
    if fin == '-':
        # read from stdin
        fin = sys.stdin
        force_stream_binary(fin)
    elif 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_stream_binary(fout)

    sys.exit(bin2hex(fin, fout, offset))
Exemplo n.º 7
0
if not os.path.exists(binfile):
    print("Can't find bin file %s" % binfile)
    sys.exit(1)

if not os.path.exists(bootloaderfile):
    print("Can't find bootloader file %s" % bootloaderfile)
    sys.exit(1)

blimage = bytes(open(bootloaderfile, "rb").read())
blimage += bytes(struct.pack('B', 255) * (reserve_kb * 1024 - len(blimage)))

if reserve_kb > 0 and len(blimage) != reserve_kb * 1024:
    print("Bad blimage size %u (want %u)" % (len(blimage), reserve_kb * 1024))
    sys.exit(1)

appimage = bytes(open(binfile, "rb").read())

with_bl = blimage + appimage

tmpfile = hexfile + ".tmp"

open(tmpfile, "wb").write(appimage)

intelhex.bin2hex(tmpfile, hexfile, offset=(0x08000000 + reserve_kb * 1024))

if reserve_kb > 0:
    open(tmpfile, "wb").write(with_bl)
    intelhex.bin2hex(tmpfile, hex_with_bl, offset=0x08000000)

os.unlink(tmpfile)
Exemplo n.º 8
0
def convertBinToHex(inputBin, outputHex, offset=0):
    try:
        intelhex.bin2hex(inputBin, outputHex, offset)
    except:
        print('Error: Conversion failed!')
Exemplo n.º 9
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.º 10
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.º 11
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.º 12
0
   print("Can't find bin file %s" % binfile)
   sys.exit(1)

if not os.path.exists(bootloaderfile):
    print("Can't find bootloader file %s" % bootloaderfile)
    sys.exit(1)

blimage = bytes(open(bootloaderfile, "rb").read())
blimage += bytes(struct.pack('B',255) * (reserve_kb * 1024 - len(blimage)))

if reserve_kb > 0 and len(blimage) != reserve_kb * 1024:
   print("Bad blimage size %u" % len(blimage))
   sys.exit(1)

appimage = bytes(open(binfile,"rb").read())

with_bl = blimage + appimage

tmpfile = hexfile + ".tmp"

open(tmpfile, "wb").write(appimage)

intelhex.bin2hex(tmpfile, hexfile, offset=(0x08000000 + reserve_kb*1024))

if reserve_kb > 0:
   open(tmpfile, "wb").write(with_bl)
   intelhex.bin2hex(tmpfile, hex_with_bl, offset=0x08000000)
   
os.unlink(tmpfile)

if args.application != None:
    bin, dat, key = GenerateBinAndDat(args, "application")
    zf.writestr("application.bin", bin)
    zf.writestr("application.dat", dat)

if args.bootloader != None:
    bin, dat, key = GenerateBinAndDat(args, "bootloader")
    zf.writestr("bootloader.bin", bin)
    zf.writestr("bootloader.dat", dat)

if args.softdevice != None:
    bin, dat, key = GenerateBinAndDat(args, "softdevice")
    zf.writestr("softdevice.bin", bin)
    zf.writestr("softdevice.dat", dat)

zf.close()

if args.key_output != None:
    key_address = int(args.key_address, 16)
    if (key_address == None):
        key_address = 0x0003F800

    key_bin = StringIO.StringIO()
    key_bin.write(key)
    fout = open(args.key_output.replace("hex", "bin"), "wb")
    fout.write(key)
    fout.close()
    bin2hex(args.key_output.replace("hex", "bin"), args.key_output,
            key_address)
Exemplo n.º 14
0
    parser.add_argument('input_file', help="Input ROM file")
    parser.add_argument('output_file', help="Output Verilog filename")
    parser.add_argument('--to-hardware', help="Input file is a yaAGC-style bin that must be converted to hardware format", action="store_true")
    parser.add_argument('--hex', help="Also generate an Intel .hex file", action="store_true")
    args = parser.parse_args()
    
    words = array.array('H')
    with open(args.input_file, 'rb') as f:
        words.fromfile(f, int(os.path.getsize(args.input_file)/2))

    words.byteswap()
    if args.to_hardware:
        temp = words[0:0o4000]
        words[0:0o4000] = words[0o4000:0o10000]
        words[0o4000:0o10000] = temp

        # Add in parity in bit position 15
        for i in range(len(words)):
            words[i] = (words[i] & 0o100000) | (((bin(words[i]).count('1') + 1) % 2) << 14) | ((words[i] & 77776) >> 1)

    with open(args.output_file, 'w') as of:
        for i,word in enumerate(words):
            of.write("    %-5u: data = 16'o%06o;\n" % (i, word))

    if args.hex:
        from intelhex import bin2hex
        output_hex = os.path.splitext(args.output_file)[0] + '.hex'
        words.byteswap()
        hw_file = BytesIO(words.tostring())
        bin2hex(hw_file, output_hex, 0)
Exemplo n.º 15
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.º 16
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()