def process( self, verify_setup=False, sign_attr=False, integrity_check=False, sign=False, encrypt=False, decrypt=False, val_image=False, val_integrity_check=False, val_sign=False, val_encrypt=False, root_cert_hash=None, progress_cb=PROGRESS_CB_PYPASS, ): """Performs the secure-image related operations specified from the params. :param bool verify_setup: Verify that the configuration of the object is correct and return. This will ignore any other params. :param bool sign_attr: Add signing attributes to hash segment of images. :param bool integrity_check: Add integrity check to the image. :param bool sign: Sign the images. (Re-sign if image is already signed) :param bool encrypt: Encrypt the images. (Re-encrypt if image is already encrypted) :param bool val_image: Validate the integrity of the image against the config file. :param bool val_integrity_check: Validate the integrity check in the image. :param bool val_sign: Validate that the image is signed and validate the integrity of the signing related data. :param bool val_encrypt: Validate that the image is encrypted and validate the integrity of the encryption related data. :param cb progress_cb: Callback method to get a status update during processing. Callback method should have this format: :: def progress_cb(status_string, progress_percent): \""" :param str status_string: the current status. :param int progress_percent: the progress (in percent) \""" ... """ from imageinfo import ImageInfo, StatusInfo from sectools.features.isc.signer.remote import RemoteSignerNote # Ensure that one or more image files is provided for processing if self._stager is None or not self.image_path_list: raise RuntimeError( 'Please specify one or more images for processing') # Ensure the correct set of operations is provided if not (verify_setup or integrity_check or sign or encrypt or decrypt or val_image or val_integrity_check or val_sign or val_encrypt): raise RuntimeError( 'Please specify one or more operations to perform.') # Print the openssl path version = '' path_info = 'is unavailable. Please run "which openssl" and "openssl version" to check openssl version info, and upgrade to required version' try: from sectools.common import crypto version = 'v' + '.'.join( tuple(str(x) for x in crypto.openssl.OPENSSL_VERSION_MIN)) + ' or greater ' path_info = 'is available at: "' + crypto.discovery_factory.get_impl( crypto.modules.MOD_OPENSSL) + '"' except Exception as e: pass logger.info('Openssl ' + version + path_info) if verify_setup: logger.note('The inputs provided (config, cmd args) are valid.') return # Start processing images individual_image_count = len(self.image_info_list) total_image_count = individual_image_count progress = ProgressNotifier(total_image_count, progress_cb, PROGRESS_TOTAL_STAGES) def _process(idx, image, sign_attr, integrity_check, sign, encrypt, decrypt, val_image, val_integrity_check, val_sign, val_encrypt): assert isinstance(image, ImageInfo) logger.info( '------------------------------------------------------') status_string = ('Processing ' + str(idx + 1) + '/' + str(total_image_count) + ': ' + image.image_under_operation) logger.info(status_string + '\n') # Send a progress notification to the toplevel progress.status = status_string progress.cur = idx progress.cur_stage = 0 file_logger_id = None image.authority = self.authority try: # Create the required directory structure for this image image_output_dir = image.dest_image.image_dir try: c_path.create_dir(image_output_dir) except Exception as e: raise RuntimeError('Could not create output directory: ' + image_output_dir + '\n' ' ' + 'Error: ' + str(e)) # Enable/Disable debug image.dest_image.debug_enable = self.debug c_path.create_debug_dir(image.dest_image.debug_dir) # Set the root cert hash image.validation_root_cert_hash = root_cert_hash # Enable file logging to the directory file_logger_id = logger.add_file_logger( c_path.join(image_output_dir, 'SecImage_log.txt'), logger.verbosity) # Create the security policies list for this image security_policy_list = create_security_policy_list(image) # Parsegen object parsegen = None # For secure operations if integrity_check or sign or encrypt or decrypt: parsegen = self._process_secure_operation( image, progress, security_policy_list, sign_attr, integrity_check, sign, encrypt, decrypt) # For validation if val_image or val_integrity_check or val_sign or val_encrypt: # Bypass validation when encrypted key provide is configured as UIE server because decryption will always fail if parsegen is not None and parsegen.is_encrypted( ) and encrypted_key_provider_id_supported( image.general_properties.UIE_key): logger.warning( "Skipping validation because encrypted key provider is configured as UIE server" ) else: parsegen = self._process_validation( image, progress, security_policy_list, val_image, val_integrity_check, val_sign, val_encrypt) # Print the image data if parsegen is not None: logger.info('\n' + str(parsegen)) # Set overall processing to true if not ((val_image and image.status.validate_parsegen.state == StatusInfo.ERROR) or (val_integrity_check and image.status.validate_integrity_check.state == StatusInfo.ERROR) or (val_sign and image.status.validate_sign.state == StatusInfo.ERROR) or (val_encrypt and image.status.validate_encrypt.state == StatusInfo.ERROR)): image.status.overall.state = StatusInfo.SUCCESS except RemoteSignerNote as e: logger.info('NOTE: ' + str(e), color=logger.YELLOW) except Exception: logger.error(traceback.format_exc()) logger.error(sys.exc_info()[1]) finally: if file_logger_id is not None: logger.removeFileLogger(file_logger_id) logger.info( '------------------------------------------------------\n') for idx, image in enumerate(self.image_info_list): _process(idx, image, sign_attr, integrity_check, sign, encrypt, decrypt, val_image, val_integrity_check, val_sign, val_encrypt) progress.complete()
def process(self, integrity_check=False, sign=False, val_image=False, val_integrity_check=False, val_sign=False, root_cert_hash=None, progress_cb=PROGRESS_CB_PYPASS, ): """Performs the secure-image related operations specified from the params. :param bool integrity_check: Add integrity check to the image. :param bool sign: Sign the images. (Re-sign if image is already signed) :param bool val_image: Validate the integrity of the image against the config file. :param bool val_integrity_check: Validate the integrity check in the image. :param bool val_sign: Validate that the image is signed and validate the integrity of the signing related data. :param cb progress_cb: Callback method to get a status update during processing. Callback method should have this format: :: def progress_cb(status_string, progress_percent): \""" :param str status_string: the current status. :param int progress_percent: the progress (in percent) \""" ... """ # Print the openssl path version = '' path_info = ('is unavailable. Please run "which openssl" and "openssl version" to ' 'check openssl version info, and upgrade to required version') try: version = 'v' + '.'.join([str(x) for x in crypto.openssl.OPENSSL_VERSION_MIN]) + ' or greater ' path_info = 'is available at: "' + crypto.discovery_factory.get_impl(crypto.modules.MOD_OPENSSL) + '"' except Exception as e: pass logger.info('Openssl ' + version + path_info) # Start processing images assert len(self.image_info_list) == 1, "multiple images are found" progress = ProgressNotifier(1, progress_cb, PROGRESS_TOTAL_STAGES) parsegens = dict() def _process(idx, image, integrity_check, sign, val_image, val_integrity_check, val_sign): assert isinstance(image, ImageInfoIot) logger.info('------------------------------------------------------') status_string = ('Processing: ' + image.image_under_operation) logger.info(status_string + '\n') # Send a progress notification to the toplevel progress.status = status_string progress.cur = idx progress.cur_stage = 0 file_logger_id = None image.authority = self.authority try: # Create the required directory structure for this image image_output_dir = image.dest_image.image_dir try: c_path.create_dir(image_output_dir) except Exception as e: raise RuntimeError('Could not create output directory: ' + image_output_dir + '\n' ' ' + 'Error: ' + str(e)) # Enable/Disable debug image.dest_image.debug_enable = self.debug c_path.create_debug_dir(image.dest_image.debug_dir) # Set the root cert hash image.validation_root_cert_hash = root_cert_hash # Enable file logging to the directory file_logger_id = logger.add_file_logger(c_path.join(image_output_dir, 'IoT_log.txt'), logger.verbosity) # Create the security policies list for this image security_policy_list = create_security_policy_list(image) # Parsegen object parsegen = None # For secure operations if integrity_check or sign: parsegen = self._process_secure_operation( image, progress, security_policy_list, integrity_check, sign, parsegens=parsegens.get(image.chipset, list())) # For validation if val_image or val_integrity_check or val_sign: parsegen = self._process_validation( image, progress, security_policy_list, val_image, val_integrity_check, val_sign) # Print the image data if parsegen is not None: logger.info('\n' + str(parsegen)) # Set overall processing to true if not ((val_image and image.status.validate_parsegen.state == StatusInfo.ERROR) or (val_integrity_check and image.status.validate_integrity_check.state == StatusInfo.ERROR) or (val_sign and image.status.validate_sign.state == StatusInfo.ERROR)): image.status.overall.state = StatusInfo.SUCCESS except Exception: logger.error(traceback.format_exc()) logger.error(sys.exc_info()[1]) finally: if file_logger_id is not None: logger.removeFileLogger(file_logger_id) logger.info('------------------------------------------------------\n') for idx, image in enumerate(self.image_info_list): _process(idx, image, integrity_check, sign, val_image, val_integrity_check, val_sign) progress.complete()
def process(self, verify_setup=False, integrity_check=False, sign=False, encrypt=False, decrypt=False, val_image=False, val_integrity_check=False, val_sign=False, val_encrypt=False, progress_cb=PROGRESS_CB_PYPASS): """Performs the secure-image related operations specified from the params. :param bool verify_setup: Verify that the configuration of the object is correct and return. This will ignore any other params. :param bool integrity_check: Add integrity check to the image. :param bool sign: Sign the images. (Re-sign if image is already signed) :param bool encrypt: Encrypt the images. (Re-encrypt if image is already encrypted) :param bool val_image: Validate the integrity of the image against the config file. :param bool val_integrity_check: Validate the integrity check in the image. :param bool val_sign: Validate that the image is signed and validate the integrity of the signing related data. :param bool val_encrypt: Validate that the image is encrypted and validate the integrity of the encryption related data. :param cb progress_cb: Callback method to get a status update during processing. Callback method should have this format: :: def progress_cb(status_string, progress_percent): \""" :param str status_string: the current status. :param int progress_percent: the progress (in percent) \""" ... """ from imageinfo import ImageInfo, StatusInfo # Ensure that one or more image files is provided for processing if self._stager is None or not self.image_path_list: raise RuntimeError( 'Please specify one or more images for processing') # Ensure the correct set of operations is provided if not (verify_setup or integrity_check or sign or encrypt or decrypt or val_image or val_integrity_check or val_sign or val_encrypt): raise RuntimeError( 'Please specify one or more operations to perform.') if verify_setup: logger.note('The inputs provided (config, cmd args) are valid.') return # Print the openssl path version = '' path_info = 'is unavailable. Please run "which openssl" and "openssl version" to check openssl version info, and upgrade to required version' try: from sectools.common import crypto from sectools.common.crypto import crypto_functions version = 'v' + crypto.discovery.openssl.OPENSSL_VERSION_MIN + ' or greater ' crypto_functions.are_available([crypto_functions.MOD_OPENSSL]) path_info = 'is available at: "' + crypto.openssl_binary_implementation.openssl_binary_path + '"' except Exception as e: pass logger.info('Openssl ' + version + path_info) # Start processing images total_images = len(self.image_info_list) progress = ProgressNotifier(total_images, progress_cb, PROGRESS_TOTAL_STAGES) for idx, image in enumerate(self.image_info_list): assert isinstance(image, ImageInfo) logger.info( '------------------------------------------------------') status_string = ('Processing ' + str(idx + 1) + '/' + str(total_images) + ': ' + image.image_under_operation) logger.info(status_string + '\n') # Send a progress notification to the toplevel progress.status = status_string progress.cur = idx progress.cur_stage = 0 file_logger_id = None try: # Create the required directory structure for this image image_output_dir = image.dest_image.image_dir try: c_path.create_dir(image_output_dir) except Exception as e: raise RuntimeError('Could not create output directory: ' + image_output_dir + '\n' ' ' + 'Error: ' + str(e)) # Enable/Disable debug image.dest_image.debug_enable = self.debug c_path.create_debug_dir(image.dest_image.debug_dir) # Enable file logging to the directory file_logger_id = logger.add_file_logger( c_path.join(image_output_dir, 'SecImage_log.txt'), logger.verbosity) # Create the security policies list for this image security_policy_list = create_security_policy_list(image) # Parsegen object parsegen = None # For secure operations if integrity_check or sign or encrypt or decrypt: parsegen = self._process_secure_operation( image, progress, security_policy_list, integrity_check, sign, encrypt, decrypt) # For validation if val_image or val_integrity_check or val_sign or val_encrypt: parsegen = self._process_validation( image, progress, security_policy_list, val_image, val_integrity_check, val_sign, val_encrypt) # Print the image data if parsegen is not None: logger.info('\n' + str(parsegen)) # Set overall processing to true if not ((val_image and image.status.validate_parsegen.state == StatusInfo.ERROR) or (val_integrity_check and image.status.validate_integrity_check.state == StatusInfo.ERROR) or (val_sign and image.status.validate_sign.state == StatusInfo.ERROR) or (val_encrypt and image.status.validate_encrypt.state == StatusInfo.ERROR)): image.status.overall.state = StatusInfo.SUCCESS except Exception: logger.error(traceback.format_exc()) logger.error(sys.exc_info()[1]) if file_logger_id is not None: logger.removeFileLogger(file_logger_id) logger.info( '------------------------------------------------------\n') progress.complete()
def process(self, verify_setup=False, generate=False, sign=False, validate=False, rch=None, sign_id=None, progress_cb=PROGRESS_CB_PYPASS): """Performs the debugpolicy operations specified from the params. :param bool verify_setup: Verify that the configuration of the object is correct and return. This will ignore any other params. :param bool generate: Generate the debugpolicy elf using the config files. :param bool validate: Validate the debugpolicy elf :param cb progress_cb: Callback method to get a status update during processing. Callback method should have this format: :: def progress_cb(status_string, progress_percent): \""" :param str status_string: the current status. :param int progress_percent: the progress (in percent) \""" ... """ # Verify setup if verify_setup: self.verify_setup(generate, sign, validate) logger.note('The inputs provided (config, cmd args) are valid.') return # Total number of stages. This is used for progress notification via the # callback. _PROGRESS_TOTAL_STAGES = 3 # Start processing debugpolicy progress = ProgressNotifier(1, progress_cb, _PROGRESS_TOTAL_STAGES) progress.status = 'Processing..' # Create debug dirs self.create_debug_dir(self.output_dir) # Generate debugpolicy elf if generate: self.generate(sign_id) progress.push() # Sign debugpolicy elf if sign: self.sign(self.input_file_list[0], sign_id) progress.push() # Validate debugpolicy file if validate: self.validate(rch, sign_id) progress.push() # End processing progress.complete()
def process(self, verify_setup=False, generate=False, validate=False, progress_cb=PROGRESS_CB_PYPASS): """Performs the fuse blowing operations specified from the params. :param bool verify_setup: Verify that the configuration of the object is correct and return. This will ignore any other params. :param bool generate: Generate the sec.dat using the config files. :param bool validate: Validate the sec.dat :param cb progress_cb: Callback method to get a status update during processing. Callback method should have this format: :: def progress_cb(status_string, progress_percent): \""" :param str status_string: the current status. :param int progress_percent: the progress (in percent) \""" ... """ # Verify setup if verify_setup: self.verify_setup(generate, validate) logger.note('The inputs provided (config, cmd args) are valid.') return # Total number of stages. This is used for progress notification via the # callback. _PROGRESS_TOTAL_STAGES = 3 # Start processing images progress = ProgressNotifier(1, progress_cb, _PROGRESS_TOTAL_STAGES) # Send a progress notification to the toplevel progress.status = 'Processing..' progress.cur_stage = 0 progress.push() # Generate the secdat if generate: self.generate() progress.push() # Validate the secdat if validate: self.validate(self.secdat) progress.push() # End processing progress.complete()
def process(self, verify_setup=False, integrity_check=False, sign=False, encrypt=False, decrypt=False, val_image=False, val_integrity_check=False, val_sign=False, val_encrypt=False, progress_cb=PROGRESS_CB_PYPASS): """Performs the secure-image related operations specified from the params. :param bool verify_setup: Verify that the configuration of the object is correct and return. This will ignore any other params. :param bool integrity_check: Add integrity check to the image. :param bool sign: Sign the images. (Re-sign if image is already signed) :param bool encrypt: Encrypt the images. (Re-encrypt if image is already encrypted) :param bool val_image: Validate the integrity of the image against the config file. :param bool val_integrity_check: Validate the integrity check in the image. :param bool val_sign: Validate that the image is signed and validate the integrity of the signing related data. :param bool val_encrypt: Validate that the image is encrypted and validate the integrity of the encryption related data. :param cb progress_cb: Callback method to get a status update during processing. Callback method should have this format: :: def progress_cb(status_string, progress_percent): \""" :param str status_string: the current status. :param int progress_percent: the progress (in percent) \""" ... """ # Ensure that one or more image files is provided for processing if self._stager is None or not self.image_path_list: raise RuntimeError('Please specify one or more images for processing') # Ensure the correct set of operations is provided if not (verify_setup or integrity_check or sign or encrypt or decrypt or val_image or val_integrity_check or val_sign or val_encrypt): raise RuntimeError('Please specify one or more operations to perform.') if verify_setup: logger.note('The inputs provided (config, cmd args) are valid.') return # Start processing images total_images = len(self.image_info_list) progress = ProgressNotifier(total_images, progress_cb, PROGRESS_TOTAL_STAGES) for idx, image in enumerate(self.image_info_list): assert isinstance(image, ImageInfo) logger.info('------------------------------------------------------') status_string = ('Processing ' + str(idx + 1) + '/' + str(total_images) + ': ' + image.image_under_operation) logger.info(status_string + '\n') # Send a progress notification to the toplevel progress.status = status_string progress.cur = idx progress.cur_stage = 0 file_logger_id = None try: # Create the required directory structure for this image image_output_dir = image.dest_image.image_dir try: c_path.create_dir(image_output_dir) except Exception as e: raise RuntimeError('Could not create output directory: ' + image_output_dir + '\n' ' ' + 'Error: ' + str(e)) # Enable/Disable debug image.dest_image.debug_enable = self.debug c_path.create_debug_dir(image.dest_image.debug_dir) # Enable file logging to the directory file_logger_id = logger.add_file_logger(c_path.join(image_output_dir, 'SecImage_log.txt'), logger.verbosity) # Create the security policies list for this image security_policy_list = create_security_policy_list(image) # Parsegen object parsegen = None # For secure operations if integrity_check or sign or encrypt or decrypt: parsegen = self._process_secure_operation(image, progress, security_policy_list, integrity_check, sign, encrypt, decrypt) # For validation if val_image or val_integrity_check or val_sign or val_encrypt: parsegen = self._process_validation(image, progress, security_policy_list, val_image, val_integrity_check, val_sign, val_encrypt) # Print the image data if parsegen is not None: logger.info('\n' + str(parsegen)) # Set overall processing to true if not ((val_image and image.status.validate_parsegen.state == StatusInfo.ERROR) or (val_integrity_check and image.status.validate_integrity_check.state == StatusInfo.ERROR) or (val_sign and image.status.validate_sign.state == StatusInfo.ERROR) or (val_encrypt and image.status.validate_encrypt.state == StatusInfo.ERROR)): image.status.overall.state = StatusInfo.SUCCESS except Exception: logger.debug(traceback.format_exc()) logger.error(sys.exc_info()[1]) if file_logger_id is not None: logger.removeFileLogger(file_logger_id) logger.info('------------------------------------------------------\n') progress.complete()
def process(self, verify_setup=False, sign=False, encrypt=False, decrypt=False, val_image=False, val_sign=False, val_encrypt=False, progress_cb=PROGRESS_CB_PYPASS): """Performs the secure-image related operations specified from the params. :param bool verify_setup: Verify that the configuration of the object is correct and return. This will ignore any other params. :param bool sign: Sign the images. (Re-sign if image is already signed) :param bool encrypt: Encrypt the images. (Re-encrypt if image is already encrypted) :param bool val_image: Validate the integrity of the image against the config file. :param bool val_sign: Validate that the image is signed and validate the integrity of the signing related data. :param bool val_encrypt: Validate that the image is encrypted and validate the integrity of the encryption related data. :param cb progress_cb: Callback method to get a status update during processing. Callback method should have this format: :: def progress_cb(status_string, progress_percent): \""" :param str status_string: the current status. :param int progress_percent: the progress (in percent) \""" ... """ # Ensure that one or more image files is provided for processing if self._stager is None or not self.image_path_list: raise RuntimeError( 'Please specify one or more images for processing') # Ensure the correct set of operations is provided if not (verify_setup or sign or encrypt or val_image or val_sign or val_encrypt or decrypt): raise RuntimeError( 'Please specify one or more operations to perform.') if verify_setup: logger.note('The inputs provided (config, cmd args) are valid.') return # Start processing images total_images = len(self.image_info_list) progress = ProgressNotifier(total_images, progress_cb, PROGRESS_TOTAL_STAGES) for idx, image in enumerate(self.image_info_list): assert isinstance(image, ImageInfo) logger.info( '------------------------------------------------------') status_string = ('Processing ' + str(idx + 1) + '/' + str(total_images) + ': ' + image.image_under_operation) logger.info(status_string + '\n') # Send a progress notification to the toplevel progress.status = status_string progress.cur = idx progress.cur_stage = 0 try: # Create the required directory structure for this image image_output_dir = image.dest_image.image_dir try: c_path.create_dir(image_output_dir) except Exception as e: raise RuntimeError('Could not create output directory: ' + image_output_dir + '\n' ' ' + 'Error: ' + str(e)) # Enable/Disable debug image.dest_image.debug_enable = self.debug c_path.create_debug_dir(image.dest_image.debug_dir) # Create the encryptor object if encrypt or decrypt or val_encrypt: try: c_path.create_debug_dir( image.dest_image.debug_dir_encdec) encdec = get_encdec(image) except Exception: if not val_encrypt: raise else: encdec = None # Create the parsegen object image.encdec = encdec parsegen = self._status_updater(self._create_parsegen_obj, image.status.parsegen, image) progress.push() # Set the security mechanisms parsegen.sign = parsegen.is_signed() or sign parsegen.encrypt = parsegen.is_encrypted() or encrypt # If encrypt: if encrypt: parsegen.encryption_params = encdec.get_encryption_parameters_blob( ) # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # Sign the image if sign: self._status_updater(self._sign_image, image.status.sign, image, parsegen) progress.push() # Package and generate the output file if sign or encrypt: store_data_to_file(image.dest_image.image_path, parsegen.get_data()) if encrypt: image.status.encrypt.state = StatusInfo.SUCCESS logger.info(('Signed ' if sign else '') + ('& ' if sign and encrypt else '') + ('Encrypted ' if encrypt else '') + 'image is stored at ' + image.dest_image.image_path) image.image_under_operation = image.dest_image.image_path # Do any post processing self._status_updater( self._post_process, image.status.postprocess, image, image.config.post_process.pil_splitter, getattr(self._stager, '_meta_build_path', None)) progress.push() # Print the image data logger.info('\n' + str(parsegen)) # Decrypt the image if decrypt: store_data_to_file(image.dest_image.decrypted_file, parsegen.get_data(encrypt=False)) # Validate parsegen if val_image: self._validate_parsegen(image, parsegen) progress.push() # Validate sign if val_sign: self._validate_sign(image, parsegen) progress.push() # Validate encrypt if val_encrypt: self._validate_encrypt(image, parsegen) progress.push() # Set overall processing to true image.status.overall.state = StatusInfo.SUCCESS except Exception: logger.debug(traceback.format_exc()) logger.error(sys.exc_info()[1]) logger.info( '------------------------------------------------------\n') progress.complete()