def check_if_file_encrypted(self, general_properties): # Check if the file is encrypted if self.is_encrypted(): if encrypted_key_provider_id_supported(general_properties.UIE_key): raise RuntimeError( "Cannot decrypt an encrypted image while using encrypted key provider" ) self._decrypt_data() self.store_debug_data(FILE_DECRYPTED_IN, self._elf_parsegen.get_data()) # Get the original data self._elf_parsegen = elf.ParseGenElf(self._elf_parsegen.get_data(), self.debug_dir, self.debug_prefix, self.debug_suffix) # Ensure that hashes match. If they don't we can assume that decryption failed if (self._mbn_parsegen.code[self.HASH_ALGO_TO_SIZE_MAP[ self._mbn_parsegen.extracted_segment_hash_algorithm] * 2:] != self.get_hash_table()): raise RuntimeError( "Decryption of image failed. This can be caused by:" "\n\t1) use of an invalid L3 key" "\n\t2) use of an incorrect segment hash algorithm") # Set the elf parsegen delegate delegate = ElfDelegate(self._elf_parsegen, self.validate_ph_addrs, self.validate_vir_addrs) self._elf_parsegen.delegate = delegate
def __init__(self, data, imageinfo=None, elf_properties=None, general_properties=None, encdec=None, debug_dir=None, debug_prefix=None, debug_suffix=None,): SecParseGenBase.__init__(self, data, imageinfo, general_properties, encdec, debug_dir, debug_prefix, debug_suffix) # Check the arguments if imageinfo is not None: elf_properties = imageinfo.image_type.elf_properties general_properties = imageinfo.general_properties if elf_properties is None: raise RuntimeError('ELF properties must not be None.') # Initialize internal properties self._image_type = 0 self._serial_num = None # Set properties from the config file self.image_type = elf_properties.image_type self.serial_num = elf_properties.serial_num # Initialize the elf parsegen self._elf_parsegen = elf.ParseGenElf(data, self.debug_dir, self.debug_prefix, self.debug_suffix) # Remove the prog header and hash segment phdr_segment, hash_segment = self.extract_phdr_hash(self._elf_parsegen) self.store_debug_data(FILE_PROG_SEG_IN, phdr_segment) self.store_debug_data(FILE_HASH_SEG_IN, hash_segment) self.store_debug_data(FILE_PROG_HASH_REMOVED_IN, self._elf_parsegen.get_data()) # If hash_segment is empty, create dummy hash_segment if not hash_segment: hash_segment = self._generate_default_hash_segment() # Initialize the base now SecParseGenMbn.__init__(self, data=hash_segment, imageinfo=None, mbn_properties=self._get_sec_parsegen_mbn_properties(), general_properties=general_properties, encdec=self.encdec, debug_dir=debug_dir, debug_prefix=debug_prefix, debug_suffix=debug_suffix) # Check if the file is encrypted if self.is_encrypted(): self._decrypt_data() self.store_debug_data(FILE_DECRYPTED_IN, self._elf_parsegen.get_data())
def __init__( self, data, imageinfo=None, elf_properties=None, general_properties=None, encdec=None, debug_dir=None, debug_prefix=None, debug_suffix=None, ): SecParseGenBase.__init__(self, data, imageinfo, general_properties, encdec, debug_dir, debug_prefix, debug_suffix) # Check the arguments if imageinfo is not None: elf_properties = imageinfo.image_type.elf_properties general_properties = imageinfo.general_properties if elf_properties is None: raise RuntimeError('ELF properties must not be None.') # Initialize internal properties self._image_type = 0 self._serial_num = None self._max_elf_segments = MAX_PHDR_COUNT # Set properties from the config file self.image_type = elf_properties.image_type self.serial_num = general_properties.testsig_serialnum if elf_properties.max_elf_segments is not None: self.max_elf_segments = elf_properties.max_elf_segments # Initialize the elf parsegen self._elf_parsegen = elf.ParseGenElf(data, self.debug_dir, self.debug_prefix, self.debug_suffix) self._elf_parsegen.stabilize_phdrs() # Remove the prog header and hash segment phdr_segment, hash_segment = self.extract_phdr_hash(self._elf_parsegen) self.store_debug_data(FILE_PROG_SEG_IN, phdr_segment) self.store_debug_data(FILE_HASH_SEG_IN, hash_segment) self.store_debug_data(FILE_PROG_HASH_REMOVED_IN, self._elf_parsegen.get_data()) self.hash_segment = hash_segment # If hash_segment is empty, create dummy hash_segment if not hash_segment: hash_segment = self._generate_default_hash_segment() # Initialize the base now SecParseGenMbn.__init__( self, data=hash_segment, imageinfo=None, mbn_properties=self._get_sec_parsegen_mbn_properties(), general_properties=general_properties, encdec=self.encdec, debug_dir=debug_dir, debug_prefix=debug_prefix, debug_suffix=debug_suffix) if self._elf_parsegen.ehdr.e_ident_class == ELFCLASS64: self._mbn_parsegen.invalidate_pointers = True # Check if the file is encrypted if self.is_encrypted(): self._decrypt_data() self.store_debug_data(FILE_DECRYPTED_IN, self._elf_parsegen.get_data()) # Get the original data self._elf_parsegen = elf.ParseGenElf(self._elf_parsegen.get_data(), self.debug_dir, self.debug_prefix, self.debug_suffix) # Do any segment checks self._validate_segments()
def __init__( self, data, imageinfo=None, elf_properties=None, general_properties=None, encdec=None, debug_dir=None, debug_prefix=None, debug_suffix=None, ): SecParseGenBase.__init__(self, data, imageinfo, general_properties, encdec, debug_dir, debug_prefix, debug_suffix) # Check the arguments if imageinfo is not None: elf_properties = imageinfo.image_type.elf_properties general_properties = imageinfo.general_properties if elf_properties is None: raise RuntimeError('ELF properties must not be None.') # Initialize internal properties self._image_type = 0 self._serial_num = None self._max_elf_segments = MAX_PHDR_COUNT self._validate_ph_addrs = True self._validate_vir_addrs = False # Set properties from the config file self.image_type = elf_properties.image_type self.hash_seg_placement = elf_properties.hash_seg_placement self.serial_num = general_properties.testsig_serialnum if elf_properties.max_elf_segments is not None: self.max_elf_segments = elf_properties.max_elf_segments if elf_properties.validate_ph_addrs is not None: self.validate_ph_addrs = elf_properties.validate_ph_addrs if elf_properties.validate_vir_addrs is not None: self.validate_vir_addrs = elf_properties.validate_vir_addrs # Initialize the elf parsegen self._elf_parsegen = elf.ParseGenElf(data, self.debug_dir, self.debug_prefix, self.debug_suffix) self._elf_parsegen.stabilize_phdrs() # Remove the prog header and hash segment phdr_segment, hash_segment = self.extract_phdr_hash(self._elf_parsegen) self.store_debug_data(FILE_PROG_SEG_IN, phdr_segment) self.store_debug_data(FILE_HASH_SEG_IN, hash_segment) self.store_debug_data(FILE_PROG_HASH_REMOVED_IN, self._elf_parsegen.get_data()) self.hash_segment = hash_segment # If hash_segment is empty, create dummy hash_segment if not hash_segment: hash_segment = self._generate_default_hash_segment( self.secboot_version) # Initialize the base now SecParseGenMbn.__init__( self, data=hash_segment, imageinfo=None, mbn_properties=self._get_sec_parsegen_mbn_properties(), general_properties=general_properties, encdec=self.encdec, debug_dir=debug_dir, debug_prefix=debug_prefix, debug_suffix=debug_suffix) if self._elf_parsegen.ehdr.e_ident_class == ELFCLASS64 or self.secboot_version == SECBOOT_VERSION_2_0: self._mbn_parsegen.invalidate_pointers = True # Set the elf parsegen delegate delegate = SecParseGenElfDelegate(self._elf_parsegen, self.validate_ph_addrs, self.validate_vir_addrs) self._elf_parsegen.delegate = delegate # Check if the file is encrypted if self.is_encrypted(): self._decrypt_data() self.store_debug_data(FILE_DECRYPTED_IN, self._elf_parsegen.get_data()) # Get the original data self._elf_parsegen = elf.ParseGenElf(self._elf_parsegen.get_data(), self.debug_dir, self.debug_prefix, self.debug_suffix) # Ensure that hashes match. If they don't we can assume that decryption failed if self._mbn_parsegen.code[32 * 2:] != self.get_hash_table(): raise RuntimeError( "Decryption of image failed. This can be caused by the use of an invalid L3 key" ) # Set the elf parsegen delegate delegate = SecParseGenElfDelegate(self._elf_parsegen, self.validate_ph_addrs, self.validate_vir_addrs) self._elf_parsegen.delegate = delegate
def __init__(self, data, imageinfo=None, elf_properties=None, general_properties=None, encdec=None, debug_dir=None, debug_prefix=None, debug_suffix=None, validating=False, signing=False, sign_attr=False): SecParseGenBase.__init__(self, data, imageinfo, general_properties, encdec, debug_dir, debug_prefix, debug_suffix, validating, signing, sign_attr) # Check the arguments if imageinfo is not None: elf_properties = imageinfo.image_type.elf_properties general_properties = imageinfo.general_properties if elf_properties is None: raise RuntimeError('ELF properties must not be None.') # Initialize internal properties self._image_type = 0 self._serial_num = None self._max_elf_segments = MAX_PHDR_COUNT self._validate_ph_addrs = True self._validate_vir_addrs = False # Set properties from the config file self.has_license_manager_segment = False self.lib_id = general_properties.lib_id self.client_id = general_properties.client_id self.image_type = elf_properties.image_type self.hash_seg_placement = elf_properties.hash_seg_placement self.serial_num = general_properties.testsig_serialnum self.signer = general_properties.selected_signer if elf_properties.max_elf_segments is not None: self.max_elf_segments = elf_properties.max_elf_segments if elf_properties.validate_ph_addrs is not None: self.validate_ph_addrs = elf_properties.validate_ph_addrs if elf_properties.validate_vir_addrs is not None: self.validate_vir_addrs = elf_properties.validate_vir_addrs if elf_properties.has_license_manager_segment is not None: self.has_license_manager_segment = elf_properties.has_license_manager_segment self._license_manager_segment = None # Initialize the elf parsegen self._elf_parsegen = elf.ParseGenElf(data, self.debug_dir, self.debug_prefix, self.debug_suffix) self._elf_parsegen.stabilize_phdrs() # Remove the prog header and hash segment phdr_segment, hash_segment = self.extract_phdr_hash(self._elf_parsegen) self.store_debug_data(FILE_PROG_SEG_IN, phdr_segment) self.store_debug_data(FILE_HASH_SEG_IN, hash_segment) self.store_debug_data(FILE_PROG_HASH_REMOVED_IN, self._elf_parsegen.get_data()) self.hash_segment = hash_segment # Extract the hash table from the extracted hash segment if hash_segment: extracted_hash_table_size = SecParseGenMbn(data=hash_segment, imageinfo=None, mbn_properties=self._get_sec_parsegen_mbn_properties(), general_properties=general_properties, encdec=self.encdec, debug_dir=debug_dir, debug_prefix=debug_prefix, debug_suffix=debug_suffix, validating=validating, signing=signing).code_size else: extracted_hash_table_size = 0 # If hash_segment is empty, create dummy hash_segment hash_segment = self._generate_default_hash_segment(self.secboot_version) # Initialize the base now SecParseGenMbn.__init__(self, data=hash_segment, imageinfo=None, mbn_properties=self._get_sec_parsegen_mbn_properties(), general_properties=general_properties, encdec=self.encdec, debug_dir=debug_dir, debug_prefix=debug_prefix, debug_suffix=debug_suffix, validating=validating, signing=signing, sign_attr=sign_attr) if self._elf_parsegen.ehdr.e_ident_class == ELFCLASS64 or self.secboot_version in [SECBOOT_VERSION_2_0, SECBOOT_VERSION_3_0]: self._mbn_parsegen.invalidate_pointers = True # Extract the hash algorithm that was used to generate the extracted hash table self._extract_hash_segment_algorithm(extracted_hash_table_size) # Set the elf parsegen delegate delegate = SecParseGenElfDelegate(self._elf_parsegen, self.validate_ph_addrs, self.validate_vir_addrs) self._elf_parsegen.delegate = delegate # Check if the file is encrypted if self.is_encrypted(): if encrypted_key_provider_id_supported(general_properties.UIE_key): raise RuntimeError("Cannot decrypt an encrypted image when encrypted key provider is configured as UIE server") self._decrypt_data() self.store_debug_data(FILE_DECRYPTED_IN, self._elf_parsegen.get_data()) # Get the original data self._elf_parsegen = elf.ParseGenElf(self._elf_parsegen.get_data(), self.debug_dir, self.debug_prefix, self.debug_suffix) # Ensure that hashes match. If they don't we can assume that decryption failed if self._mbn_parsegen.code[SecParseGenElf.HASH_ALGO_TO_SIZE_MAP[self._mbn_parsegen.extracted_segment_hash_algorithm]*2:] != self.get_hash_table(): raise RuntimeError("Decryption of image failed. This can be caused by:" "\n\t1) use of an invalid L3 key" "\n\t2) use of an incorrect segment hash algorithm") # Set the elf parsegen delegate delegate = SecParseGenElfDelegate(self._elf_parsegen, self.validate_ph_addrs, self.validate_vir_addrs) self._elf_parsegen.delegate = delegate # Perform license manager segment operations self.add_or_update_license_manager_segment()
def __init__(self, data, parsegen_mbn_class=ParseGenMbnV3, imageinfo=None, elf_properties=None, general_properties=None, debug_dir=None, debug_prefix=None, debug_suffix=None, validating=False, signing=False, parsegens=None, sign_attr=False, **kwargs): # Check the arguments if imageinfo is not None: elf_properties = imageinfo.image_type.elf_properties general_properties = imageinfo.general_properties if elf_properties is None: raise RuntimeError('ELF properties must not be None.') self.secboot_version = general_properties.secboot_version self.parsegen_mbn_class = parsegen_mbn_class self.HASH_ALGO_TO_SIZE_MAP = dict( (algo, size) for size, algo in self.HASH_SIZE_TO_ALGO_MAP.items()) self.HASH_ALGO_TO_SIZE_MAP[ self.parsegen_mbn_class.UNKNOWN_ALGORITHM] = self.HASH_SIZE_32 self.HASH_ALGO_TO_SIZE_MAP[ self.parsegen_mbn_class.NONE_ALGORITHM] = self.HASH_SIZE_32 # Initialize internal properties self._image_type = 0 self._max_elf_segments = MAX_PHDR_COUNT self._validate_ph_addrs = True self._validate_vir_addrs = False self._hash_padding_size = 0 self._has_additional_padding = False # Following is needed to ensure LOAD segments are not shifted for # 4k alignment from previous segment offset; needed for adding prog_hdr and hash segment self._align = True # Following is needed to keep track of segments which are enclosed within other segments self.encapsulated_segments = [] # Set properties from the config file self.image_type = elf_properties.image_type self.hash_seg_placement = elf_properties.hash_seg_placement self.signer = general_properties.selected_signer self.segment_hash_algorithm = general_properties.segment_hash_algorithm if elf_properties.max_elf_segments is not None: self.max_elf_segments = elf_properties.max_elf_segments if elf_properties.validate_ph_addrs is not None: self.validate_ph_addrs = elf_properties.validate_ph_addrs if elf_properties.validate_vir_addrs is not None: self.validate_vir_addrs = elf_properties.validate_vir_addrs # Initialize the elf parsegen self._elf_parsegen = elf.ParseGenElf(data, debug_dir=debug_dir, debug_prefix=debug_prefix, debug_suffix=debug_suffix, elf_properties=elf_properties) _, hash_seg_entry = self.get_phdr_and_hash_entry(self._elf_parsegen) # Populating hash segment address from the extracted hash segment entry from phdr if imageinfo and hash_seg_entry: imageinfo.hash_seg_address = hash_seg_entry.p_paddr self._elf_parsegen.stabilize_phdrs() if self.hash_seg_placement == 'POST_PHDR_LOAD_ALIGNED': # Below is needed so that segments are not shifted for 4k alignment # from offset of previous segment self._align = False # Get the list of segments which are encapsulated within other segments sorted_phdrs, self.encapsulated_segments = self._elf_parsegen.get_sorted_phdrs_and_encapsulated_phdrs( self._elf_parsegen.phdrs) # pad LOAD segments with 0s if there are any gaps between two consecutive LOAD segments self._elf_parsegen.phdrs = sorted_phdrs self._update_segments(self._elf_parsegen.phdrs) if validating: self._validate_filesz( self._elf_parsegen.phdrs, os.path.getsize(imageinfo.image_under_operation)) # Remove the prog header and hash segment phdr_segment, hash_segment = self.extract_phdr_hash(self._elf_parsegen) self.store_debug_data(FILE_PROG_SEG_IN, phdr_segment, debug_dir, debug_prefix, debug_suffix) self.store_debug_data(FILE_HASH_SEG_IN, hash_segment, debug_dir, debug_prefix, debug_suffix) self.store_debug_data(FILE_PROG_HASH_REMOVED_IN, self._elf_parsegen.get_data(), debug_dir, debug_prefix, debug_suffix) self.hash_segment = hash_segment self.physical_address_hash_seg = None # This will be populated with hash segment address present in double signed images for oem signing/re-signing and populated during validation for all kind of images # Construct a MBN object super(ElfV3Base, self).__init__( hash_segment if hash_segment else self._generate_default_hash_segment(), imageinfo=None, mbn_properties=self._get_sec_parsegen_mbn_properties(), general_properties=general_properties, debug_dir=debug_dir, debug_prefix=debug_prefix, debug_suffix=debug_suffix, validating=validating, signing=signing, parsegens=parsegens, sign_attr=sign_attr, **kwargs) # Controls whether hash table entries should be created for each segment page self.hash_pageseg_as_segment = False # Extract the hash table from the extracted hash segment extracted_hash_table_size = self.code_size if hash_segment else 0 # By now, self should have already had a MBN object, which in turn has # self._mbn_parsegen or an instance of ParseGenMbn class. So, update # self._mbn_parsegen.invalidate_pointers state to either True or False. self.update_invalidate_pointers_state( self._elf_parsegen.ehdr.e_ident_class == ELFCLASS64) # Compute hash table size from the extracted hash segment if any. # This needs to wait until the self object is created. self._extract_hash_segment_algorithm(extracted_hash_table_size) # Set the elf parsegen delegate delegate = ElfDelegate(self._elf_parsegen, self.validate_ph_addrs, self.validate_vir_addrs) self._elf_parsegen.delegate = delegate