Пример #1
0
def search_projects_for_chip_type(devkit_root, workspace_file):
    """
    Look for what memory type options are available
    """
    ws_projects = Workspace(workspace_file).parse()
    # Go through the projects in the x2w file and find dev_cfg_filesystem
    for project in ws_projects.values():
        # Only going to work on project 'dev_cfg_filesystem'
        if project.default_configuration.properties.get(
                'TYPE') == 'device_config':
            # Try and get the chip type from the project
            return search_project_for_chip_type(devkit_root, project,
                                                workspace_file)

    return None
Пример #2
0
 def _search_projects_for_flash_config_file(self):
     """
     Look for a flash configuration file in the default configuration of the
     app/p1 project file.
     """
     ws_projects = Workspace(self._workspace_file).parse()
     # Go through the projects in the x2w file
     for project in ws_projects.values():
         # Try and get the flash configuration file from the project
         flash_config_file = self._search_project_for_flash_config_file(project.filename)
         if flash_config_file:
             # The flash configuration file has been found so return it
             return flash_config_file
     # The flash configuration file has not been found in the projects
     return None
Пример #3
0
def search_projects_for_chip_type(devkit_root, workspace_file):
    """
    Look for a chip type in the default configuration of the
    app/p1 project file.
    """
    ws_projects = Workspace(workspace_file).parse()
    # Go through the projects in the x2w file
    for project in ws_projects.values():
        # Try and get the chip type from the project
        chip_type = \
            search_project_for_chip_type(devkit_root, project.filename, workspace_file)
        if chip_type:
            # The chip type has been found so return it
            return chip_type
    # The chip type has not been found in the projects
    return None
Пример #4
0
def get_crypto_key(script_args):
    """
    Search all projects in the workspace to find where the crypto key is and extract it.
    :param script_args:
    :return: the crypto key needed to encrypt the PS storage
    """
    crypto_key = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    # Get the project paths from the workspace because we need to be able
    # to find information from other projects
    # Get the list of the workspace proj_path
    ws_projects = Workspace(script_args.workspace_file).parse()

    # Go through each project, find the filesystem and then look for *.htf files under different filesystems
    # and scan them to find the encryption key "PsAesKey"
    for proj in ws_projects.values():
        config = proj.get_properties('filesystem')
        filesystem_type = config.get('TYPE')
        if filesystem_type in ("firmware_config", "curator_config",
                               "device_config", "user_ps"):
            project_files = proj.files
            htf_files = [
                f for f in project_files
                if os.path.splitext(f.lower())[1] == '.htf'
            ]
            for file in htf_files:
                with open(file, 'r') as htf_file:
                    file_content = htf_file.read().splitlines()
                    for i in range(len(file_content)):
                        # Do not consider the key or anything else which is commented out
                        file_content[i] = re.sub("#.*$", "", file_content[i])
                        if "PsAesKey" in file_content[i]:
                            # PsAesKey = [ 00 2f 00 80 00 00 00 00 00 00 00 00 00 00 00 10]
                            # after splitting ['PsAesKey ', ' [ 00 2f 00 80 00 00 00 00 00 00 00 00 00 00 00 10]']
                            crypto_key = file_content[i].split("=")[-1:]

                            # removing  "[ ]" and extra spaces
                            crypto_key = crypto_key[0].replace(
                                "[", "").replace("]", "").replace(" ", "")

                            # creating 16 elements, each octet long this is what P0 expects
                            # e.g. [0, 47, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16]
                            crypto_key = [
                                int(crypto_key[i:i + 2], 16)
                                for i in range(0, len(crypto_key), 2)
                            ]

    return crypto_key
def collect_all_workspace_projects(single_image, workspace_file, inputpath):
    """
    Collect all workspace projects and combine them into a single image.
    Build and collect the input xuv files from all the projects in the workspace
    """
    workspace = Workspace(workspace_file).parse()

    for project in workspace.values():
        if not single_image.process_project(project.filename, inputpath):
            # An error has occured
            print("Failed to process %s" % project)
            sys.stdout.flush()
            return False

    sys.stdout.flush()

    return True
def search_projects_for_chip_type(devkit_root, workspace_file):
    """
    Look for what memory type options are available
    """
    ws_projects = Workspace(workspace_file).parse()
    # Go through the projects in the x2w file and find dev_cfg_filesystem
    for project in ws_projects.values():
        # Only going to work on project 'dev_cfg_filesystem'
        if "dev_cfg_filesystem" == project.name:
            # Try and get the chip type from the project
            memory_options_list = \
                search_project_for_chip_type(devkit_root, project.filename, workspace_file)
            if memory_options_list:
                # The chip type has been found so return it
                return memory_options_list
    # The chip type has not been found in the projects
    return None
Пример #7
0
    def collect_all_workspace_projects(self, workspace, inputpath, build_output_folder=None):
        """
        Collect all workspace projects and combine them into a single image.
        """
        # Build and collect the input xuv files from all the projects in the workspace
        ws_projects = Workspace(workspace).parse()
        for project in ws_projects.values():
            proceed, _ = self.process_project(project.filename, inputpath)

            if not proceed:
                # An error has occured
                print("Failed to process %s" % project.filename)
                sys.stdout.flush()
                return False

        sys.stdout.flush()

        return True
Пример #8
0
def main(args):
    UISTATE_LOCATION_SELECTION  = 0
    UISTATE_RESPONSE_SELECTION  = 1
    UISTATE_PROCEED             = 2
    UISTATE_EXIT                = -1
    uistate = UISTATE_LOCATION_SELECTION

    parsed_args = parse_args(args)

    # Display whatever arguments have been given
    print("devkit root: %s" % (parsed_args.devkit_root))
    print("workspace: %s" % (parsed_args.workspace))
    if parsed_args.nowstring is not None:
        print("nowstring: %s" % (parsed_args.nowstring))
    if parsed_args.response is not None:
        print("response: %s" % (parsed_args.response))
    if parsed_args.folder_for_rsa_files is not None:
        print("folder_for_rsa_files: %s" % (parsed_args.folder_for_rsa_files))
    sys.stdout.flush()

    if (parsed_args.nowstring is not None):
        # The user has provided their own folder name
        nowstring = parsed_args.nowstring
    else:
        nowstring = datetime.strftime(datetime.now(), '%Y%m%d%H%M%S')

    if not parsed_args.folder_for_rsa_files:
        # The -f option has not been given so use the default location
        # Present the UI to the user to confirm or change that location
        outpath = os.path.join(os.path.dirname(parsed_args.workspace), "dfu")
    else:
        # The -f option has been given so use that location
        outpath = os.path.abspath(parsed_args.folder_for_rsa_files)
        uistate = UISTATE_RESPONSE_SELECTION

    returnValue = 3
    if parsed_args.response is not None:
        # The user has provided a response on the command line
        # to avoid having to present a UI, for test automation
        response = str.lower(parsed_args.response)
        if response == "use":
            returnValue = 1
        elif response == "replace":
            returnValue = 2
        else:
            print("Invalid -r option {}".format(parsed_args.response))
            print('Valid options are "Use" or "Replace"')
            sys.stdout.flush()
            return False

        if uistate == UISTATE_RESPONSE_SELECTION:
            uistate = UISTATE_PROCEED

    sys.stdout.flush()

    tlh = None
    if uistate == UISTATE_LOCATION_SELECTION or uistate == UISTATE_RESPONSE_SELECTION:
        tlh = TCL_LIBRARY_handler(parsed_args.devkit_root)
        top = Tkinter.Tk()

    private_pem_file = os.path.join(outpath, "private.pem")
    rsa_pss_constants_c_file = os.path.join(outpath, "rsa_pss_constants.c")

    while uistate != UISTATE_EXIT and uistate != UISTATE_PROCEED:
        if uistate is UISTATE_LOCATION_SELECTION:
            if not os.path.isdir(outpath):
                try:
                    os.makedirs(outpath)
                    print("Created folder %s" % outpath)
                    sys.stdout.flush()
                    returnValue = 3
                except (OSError, IOError) as exception:
                    print("Unable to create path {}; error {}. Exit!\n".format(outpath,
                                                                        exception.errno))
                    sys.stdout.flush()
                    return False
            newpath = askdirectory(top, outpath)
            if newpath == "":
                # The directory selection has been cancelled
                # Cancel is exit
                print("Cancelled\n")
                sys.stdout.flush()
                return False
                
            if not os.path.isdir(newpath):
                try:
                    os.makedirs(newpath)
                    print("Created folder %s" % newpath)
                    sys.stdout.flush()
                    returnValue = 3
                except (OSError, IOError) as exception:
                    print("Unable to create path {}; error {}. Exit!\n".format(newpath, exception.errno))
                    sys.stdout.flush()
                    return False

            outpath = newpath
            sys.stdout.flush()
            private_pem_file = os.path.join(outpath, "private.pem")
            rsa_pss_constants_c_file = os.path.join(outpath, "rsa_pss_constants.c")

            if (parsed_args.response is None):
                uistate = UISTATE_RESPONSE_SELECTION
            else:
                uistate = UISTATE_PROCEED

        elif uistate is UISTATE_RESPONSE_SELECTION:
            if os.path.isfile(private_pem_file) and os.path.isfile(rsa_pss_constants_c_file):
                # There are existing files to use or replace.
                # The above is the minimum set.
                # Ask the user what to do via a dialog
                bb = show_button_box(top, outpath)
                returnValue = 0
                while returnValue == 0:
                    returnValue = bb.returnValue()
                if returnValue == -1:
                    # Cancelling
                    if parsed_args.folder_for_rsa_files == None:
                        # Back to location selection UI
                        uistate = UISTATE_LOCATION_SELECTION
                    else:
                        # Folder given so no location  selectio UI
                        # Cancel is exit
                        print("Cancelled\n")
                        sys.stdout.flush()
                        return False
                else:
                    uistate = UISTATE_PROCEED
            else:
                returnValue = 3
                uistate = UISTATE_PROCEED

    if tlh is not None:
        tlh.close()

    if not os.path.isdir(outpath):
        try:
            os.makedirs(outpath)
            print("Created folder %s" % outpath)
            returnValue = 3
        except (OSError, IOError) as exception:
            print("Unable to create path {}; error {}. Exit!\n".format(outpath, exception.errno))
            return False

    # Set up the file specs for the files to of interest for archive/create
    filelist = []
    private_pem_file = os.path.join(outpath, "private.pem")
    filelist.append(private_pem_file)
    public_pem_file = os.path.join(outpath, "public.pem")
    filelist.append(public_pem_file)
    dfu_private_key_file = os.path.join(outpath, "dfu-private.key")
    filelist.append(dfu_private_key_file)
    dfu_public_key_file = os.path.join(outpath, "dfu-public.key")
    filelist.append(dfu_public_key_file)
    rsa_pss_constants_c_file = os.path.join(outpath, "rsa_pss_constants.c")
    filelist.append(rsa_pss_constants_c_file)

    # At this point the returnValue should be:
    # 1 to use (known to already exist),
    # 2 to replace (known to already exist), or
    # 3 to create

    if returnValue >= 2:
        # If we are to replace or create we need SecurityCmd.exe
        scexe = os.path.join(parsed_args.devkit_root, "tools", "bin", "SecurityCmd.exe")
        if not os.path.isfile(scexe):
            print("{} does not exist\n".format(scexe))
            print("Exiting!\n")
            sys.stdout.flush()
            return False

    if returnValue == 2:
        # Going to replace so archive what we already have
        zip_filename = nowstring + ".zip"
        zip_filespec = os.path.join(outpath, zip_filename)
        # Create the archive for writing "deflated" (compressed) files to
        try:
            with zipfile.ZipFile(zip_filespec, mode="w", compression=zipfile.ZIP_DEFLATED) as zip:
                for listfile in filelist:
                    if os.path.isfile(listfile):
                        print("Adding {} to archive {}".format(listfile, zip_filespec))
                        zip.write(listfile, os.path.basename(listfile))
        except (OSError, IOError) as exception:
            print("Error with zip file {}; error {}, {}\n".format(zip_filespec, exception.errno, os.strerror(exception.errno)))
            print("Exiting!\n")
            sys.stdout.flush()
            return False

        try:
            # Having archived all the files without an error, delete them
            for listfile in filelist:
                # Ensure the file is not read-only before trying to delete it
                os.chmod(listfile, stat.S_IWRITE)
                os.remove(listfile)
                print("Deleted {}".format(listfile))
        except (OSError, IOError) as exception:
            print("Error deleting file; error {}, {}\n".format(exception.errno, os.strerror(exception.errno)))
            restore_archive(nowstring, outpath, filelist)
            print("Exiting!\n")
            sys.stdout.flush()
            return False

        sys.stdout.flush()
        # Having archived and deleted the original files, now as for create
        returnValue = 3

    if returnValue == 3:
        # Create the required files
        cmd_line = [scexe, "-product", "hyd", "creatersakey", "2048", "F4", private_pem_file, public_pem_file]
        print("Invoking '%s'" % " ".join(cmd_line))
        sys.stdout.flush()
        result = subprocess.call(cmd_line)
        if result != 0:
            print("'%s' failed" % " ".join(cmd_line))
            restore_archive(nowstring, outpath, filelist)
            print("Exiting!\n")
            sys.stdout.flush()
            return False
        if not os.path.isfile(private_pem_file):
            print("Failed to create '%s'" % private_pem_file)
            restore_archive(nowstring, outpath, filelist)
            print("Exiting!\n")
            sys.stdout.flush()
            return False
        if not os.path.isfile(public_pem_file):
            print("Failed to create '%s'" % public_pem_file)
            restore_archive(nowstring, outpath, filelist)
            print("Exiting!\n")
            sys.stdout.flush()
            return False

        print("'%s' created" % private_pem_file)
        print("'%s' created" % public_pem_file)

        cmd_line = [scexe, "-product", "hyd", "pem2dfukey", "prv", private_pem_file, dfu_private_key_file]
        print("Invoking '%s'" % " ".join(cmd_line))
        sys.stdout.flush()
        result = subprocess.call(cmd_line)

        # We don't care whether that failed or not as the dfu_private_key_file
        # is not used for any other processing

        if os.path.isfile(dfu_private_key_file):
            print("'%s' created" % dfu_private_key_file)

        cmd_line = [scexe, "-product", "hyd", "pem2dfukey", "pub", public_pem_file, dfu_public_key_file]
        print("Invoking '%s'" % " ".join(cmd_line))
        sys.stdout.flush()
        result = subprocess.call(cmd_line)
        if result != 0:
            print("'%s' failed" % " ".join(cmd_line))
            restore_archive(nowstring, outpath, filelist)
            print("Exiting!\n")
            sys.stdout.flush()
            return False
        if not os.path.isfile(dfu_public_key_file):
            print("Failed to create '%s'" % dfu_public_key_file)
            restore_archive(nowstring, outpath, filelist)
            print("Exiting!\n")
            sys.stdout.flush()
            return False

        print("'%s' created" % dfu_public_key_file)

        cmd_args = ["-i", dfu_public_key_file]
        cmd = "'gen_rsa_pss_constants {}'".format(" ".join(cmd_args))
        print("Invoking {}".format(cmd))

        if not gen_rsa_pss_constants.main(cmd_args):
            print("'{}' failed".format(cmd))
            restore_archive(nowstring, outpath, filelist)
            print("Exiting!\n")
            sys.stdout.flush()
            return False
        if not os.path.isfile(rsa_pss_constants_c_file):
            print("Failed to create '%s'" % rsa_pss_constants_c_file)
            restore_archive(nowstring, outpath, filelist)
            print("Exiting!\n")
            sys.stdout.flush()
            return False

        print("'%s' created" % rsa_pss_constants_c_file)

    # All the required files are now in place
    # Find the rsa_pss_constants.c in the workspace and replace it
    ws_projects = Workspace(parsed_args.workspace).parse()
    for project in ws_projects.values():
        result = process_project(project, rsa_pss_constants_c_file, nowstring)
        if result < 0:
            # An error has occured
            restore_archive(nowstring, outpath, filelist)
            sys.stdout.flush()
            return False
        elif result > 0:
            print("\nPlease rebuild library project {} and your application".format(project.filename))
            sys.stdout.flush()
            break

    if result == 0:
        print("\nUnable to find {} in any of the projects".format(
            rsa_pss_constants_c_file))
        sys.stdout.flush()
        return False

    sys.stdout.flush()
    return True