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
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
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
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
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
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