def __init__(self, data, imageinfo=None, mbn_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: mbn_properties = imageinfo.image_type.mbn_properties if mbn_properties is None: raise RuntimeError('MBN properties must not be None.') # Initialize the mbn parsegen self._mbn_parsegen = mbn.ParseGenMbn(data, mbn_properties.header_size, mbn_properties.preamble_size, mbn_properties.has_magic_num, mbn_properties.page_size, mbn_properties.num_of_pages, mbn_properties.ota_enabled, mbn_properties.min_size_with_pad, self.debug_dir, self.debug_prefix, self.debug_suffix) # Set the security attributes from the mbn parser self.data_signature = self._mbn_parsegen.sign self.cert_chain = self._mbn_parsegen.cert_chain self.encryption_params = self._mbn_parsegen.encryption_params
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 if file is encrypted bin_encryption_params = '' if self.encdec is not None: data, bin_encryption_params = self.encdec.extract_encryption_parameters( data) if bin_encryption_params: decryptor = self.encdec.get_decryptor( bin_encryption_params, self.encdec.get_dummy_key()) data = decryptor.decrypt_segment(data, 0) SecParseGenElf.__init__(self, data, imageinfo=imageinfo, elf_properties=elf_properties, general_properties=general_properties, encdec=self.encdec, debug_dir=debug_dir, debug_prefix=debug_prefix, debug_suffix=debug_suffix) self.encryption_params = bin_encryption_params
def __init__(self, data, imageinfo=None, pmbl_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: pmbl_properties = imageinfo.image_type.pmbl_properties if pmbl_properties is None: raise RuntimeError('PMBL properties must not be None.') # Initialize the pmbl parsegen self._pmbl_parsegen = pmbl.ParseGenPmbl(data, pmbl_properties.preamble_size, pmbl_properties.has_magic_num, pmbl_properties.page_size, pmbl_properties.num_of_pages, pmbl_properties.ota_enabled, pmbl_properties.min_size_with_pad, self.debug_dir, self.debug_prefix, self.debug_suffix)
def __init__(self, data, imageinfo=None, bin_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: bin_properties = imageinfo.image_type.bin_properties if bin_properties is None: raise RuntimeError('BIN properties must not be None.') """ # Check if file is encrypted encryption_params = '' if self.encdec is not None: data, encryption_params = self.encdec.extract_encryption_parameters(data) if encryption_params: decryptor = self.encdec.get_decryptor(encryption_params, self.encdec.get_dummy_key()) data = decryptor.decrypt_segment(data, 0) self.data, self.encryption_params = data, encryption_params
def __init__(self, data, imageinfo=None, ewm_properties=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: ewm_properties = imageinfo.image_type.ewm_properties elf_properties = imageinfo.image_type.elf_properties general_properties = imageinfo.general_properties if ewm_properties is None: raise RuntimeError('EWM properties must not be None.') if elf_properties is None: raise RuntimeError('EWM ELF properties must not be None.') # Initialize internal properties self._image_entry = 0 self._relocatable = False # Set properties from the config file self.image_entry = int(ewm_properties.image_entry, 16) self.relocatable = ewm_properties.relocatable # Wrap the data in elf if it doesnt already if not self.is_elf(data): data = self.inject_elf_wrapper(data) SecParseGenElf.__init__(self, data, None, elf_properties, general_properties, self.encdec, debug_dir, debug_prefix, debug_suffix)
def __init__(self, data, imageinfo=None, ewm_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: ewm_properties = imageinfo.image_type.ewm_properties general_properties = imageinfo.general_properties if ewm_properties is None: raise RuntimeError('EWM properties must not be None.') # Initialize internal properties self._image_entry = 0 self._relocatable = False # Set properties from the config file self.image_entry = int(ewm_properties.image_entry, 16) self.relocatable = ewm_properties.relocatable # Remove elf header if it already exists data = self.extract_elf_wrapper(data) # Initialize the base mbn parser SecParseGenMbn.__init__(self, data, None, ewm_properties, general_properties, self.encdec, debug_dir, debug_prefix, debug_suffix)
def __init__( self, data, imageinfo=None, aost_lic_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) # Disable cert chain padding self.pad_cert_chain = False # Initialize the aost license parsegen self._aost_lic_parsegen = ParseGenAOSTLic(data, self.debug_dir, self.debug_prefix, self.debug_suffix) # Set the security attributes from the license parser self.data_signature = self._aost_lic_parsegen.sign self.cert_chain = self._aost_lic_parsegen.cert_chain
def get_data(self, integrity_check=None, sign=None): # Resolve the operation integrity_check = self.integrity_check if integrity_check is None else integrity_check sign = self.sign if sign is None else sign integrity_check = True if (integrity_check or sign) else False # Allow base to do any checks SecParseGenBase.get_data(self, integrity_check, sign) if not (integrity_check or sign): data = self._elf_parsegen.get_data() else: # Add the header and hash segment prog_phdr_entry, hash_phdr_entry, hash_segment_size =\ self._add_phdr_and_hash_segs(sign) try: # Generate the hash segment now hash_segment = self.get_hash_segment(sign) hash_segment += PAD_BYTE_1 * self._hash_padding_size # Check here for sizes mismatching just in case if len(hash_segment) != hash_segment_size: raise RuntimeError( 'Estimated hash table size was wrong. Estimate - ' + str(hash_segment_size) + ', Actual - ' + str(len(hash_segment))) # Re-add the hash segment, this time with the real data self._elf_parsegen.remove_segment(hash_phdr_entry) self._elf_parsegen.remove_segment(prog_phdr_entry) self._elf_parsegen.add_segment(prog_phdr_entry, '', toalign=self._align) self._elf_parsegen.add_segment(hash_phdr_entry, hash_segment, index=1, toalign=self._align) try: # Get the elf data data = self._elf_parsegen.get_data() finally: pass finally: # Remove the prog try: self._elf_parsegen.remove_segment(prog_phdr_entry) except Exception as e: logger.warning(str(e)) # Remove the hash try: self._elf_parsegen.remove_segment(hash_phdr_entry) except Exception as e: logger.warning(str(e)) return data
def __init__(self, data, imageinfo=None, bin_to_sign_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) self.data = data
def get_data(self, integrity_check=None, sign=None, encrypt=None, get_hash_segment=False): # Resolve the operation integrity_check = self.integrity_check if integrity_check is None else integrity_check sign = self.sign if sign is None else sign encrypt = self.encrypt if encrypt is None else encrypt integrity_check = True if (integrity_check or sign or encrypt) else False # Allow base to do any checks SecParseGenBase.get_data(self, integrity_check, sign, encrypt) hash_segment = None if not (integrity_check or sign or encrypt): data = self._elf_parsegen.get_data() else: # Add the header and hash segment prog_phdr_entry, hash_phdr_entry, hash_segment_size = self._add_phdr_and_hash_segs(integrity_check, sign, encrypt) try: # Generate the hash segment now hash_segment = self.get_hash_segment(integrity_check, sign, encrypt) # Check here for sizes mismatching just in case if len(hash_segment) != hash_segment_size: raise RuntimeError('Estimated hash table size was wrong. Estimate - ' + str(hash_segment_size) + ', Actual - ' + str(len(hash_segment))) # Re-add the hash segment, this time with the real data self._elf_parsegen.remove_segment(hash_phdr_entry) self._elf_parsegen.remove_segment(prog_phdr_entry) self._elf_parsegen.add_segment(prog_phdr_entry, '') self._elf_parsegen.add_segment(hash_phdr_entry, hash_segment, index=1) # If encrypting, change the process segment data if encrypt: parsegen_updater = ParseGenEncDec(self.store_debug_data, self.encrypt_segment) parsegen_updater.update_parsegen(self.encdec.get_segment_num_scheme(), self._elf_parsegen) try: # Get the elf data data = self._elf_parsegen.get_data() finally: # Restore the process segment data if encrypt: try: parsegen_updater.revert_parsegen(self._elf_parsegen) except Exception as e: logger.warning(str(e)) finally: # Remove the prog try: self._elf_parsegen.remove_segment(prog_phdr_entry) except Exception as e: logger.warning(str(e)) # Remove the hash try: self._elf_parsegen.remove_segment(hash_phdr_entry) except Exception as e: logger.warning(str(e)) if get_hash_segment: return hash_segment return data
def get_data(self, integrity_check=None, sign=None): # Resolve the operation integrity_check = self.integrity_check if integrity_check is None else integrity_check sign = self.sign if sign is None else sign # Allow base to do any checks SecParseGenBase.get_data(self, integrity_check, sign) if integrity_check: raise RuntimeError('Mbn Images do not support integrity check.') return self._get_data_int(sign)
def get_data(self, sign=None, encrypt=None): # Resolve the operation sign = self.sign if sign is None else sign encrypt = self.encrypt if encrypt is None else encrypt # Allow base to do any checks SecParseGenBase.get_data(self, sign, encrypt) if sign: logger.error('Bin Images do not support signing. Returning the raw image.') return self._get_data_int(False, encrypt)
def get_data(self, sign=None, encrypt=None): # Resolve the operation sign = self.sign if sign is None else sign encrypt = self.encrypt if encrypt is None else encrypt # Allow base to do any checks SecParseGenBase.get_data(self, sign, encrypt) if encrypt: logger.error('Mbn Images do not support encryption. Returning the ' + ('signed' if sign else 'raw') + ' image.') return self._get_data_int(sign, False)
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, bin_to_sign_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) self.data = data
def get_data(self, integrity_check=None, sign=None, encrypt=None): # Resolve the operation integrity_check = self.integrity_check if integrity_check is None else integrity_check sign = self.sign if sign is None else sign encrypt = self.encrypt if encrypt is None else encrypt # Allow base to do any checks SecParseGenBase.get_data(self, integrity_check, sign, encrypt) if integrity_check: raise RuntimeError('Mbn Images do not support integrity check.') if encrypt: raise RuntimeError('Mbn Images do not support encryption.') return self._get_data_int(sign, False)
def get_data(self, integrity_check=None, sign=None, encrypt=None): # Resolve the operation integrity_check = self.integrity_check if integrity_check is None else integrity_check sign = self.sign if sign is None else sign encrypt = self.encrypt if encrypt is None else encrypt # Allow base to do any checks SecParseGenBase.get_data(self, integrity_check, sign, encrypt) if integrity_check: raise RuntimeError('AOST Licenses do not support integrity check.') if encrypt: raise RuntimeError('AOST Licenses do not support encryption.') return self._get_data_int(sign)
def get_data(self, integrity_check=None, sign=None, encrypt=None): # Resolve the operation integrity_check = self.integrity_check if integrity_check is None else integrity_check sign = self.sign if sign is None else sign encrypt = self.encrypt if encrypt is None else encrypt # Allow base to do any checks SecParseGenBase.get_data(self, integrity_check, sign, encrypt) if integrity_check: logger.error('Mbn Images do not support integrity check.') if encrypt: logger.error('Mbn Images do not support encryption.') return self._get_data_int(sign, False)
def __init__(self, data, imageinfo=None, aost_bin_lic_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) # Disable cert chain padding self.pad_cert_chain = False # Save data for signing self.data = data
def __repr__(self): return ('Base Properties: ' + '\n' + SecParseGenBase.__repr__(self) + '\n' 'ELF Properties: ' + '\n' + repr(self._elf_parsegen) + '\n' 'Hash Segment Properties: ' + '\n' + repr(self._mbn_parsegen) + '\n' 'SecElf Properties: ' + '\n' '' + properties_repr([('image_type', self.image_type), ('testsig_serialnum', hex_addr(self.serial_num) if self.serial_num is not None else self.serial_num),]))
def get_data(self, sign=None, encrypt=None): # Resolve the operation sign = self.sign if sign is None else sign encrypt = self.encrypt if encrypt is None else encrypt # Allow base to do any checks SecParseGenBase.get_data(self, sign=sign, encrypt=False) # Get the signed data from the elf parser data = SecParseGenMbn.get_data(self, sign=sign, encrypt=False) # Add encryption params if encrypt is true if encrypt: data = self.encryption_params + self.encrypt_segment(data, 0) return data
def __init__(self, data, imageinfo=None, ewm_properties=None, elf_properties=None, general_properties=None, encdec=None, debug_dir=None, debug_prefix=None, debug_suffix=None, validating=False, signing=False, parsegens=None, sign_attr=False): SecParseGenBase.__init__(self, data, imageinfo, general_properties, encdec, debug_dir, debug_prefix, debug_suffix, validating, signing, parsegens, sign_attr) # Check the arguments if imageinfo is not None: ewm_properties = imageinfo.image_type.ewm_properties elf_properties = imageinfo.image_type.elf_properties general_properties = imageinfo.general_properties if ewm_properties is None: raise RuntimeError('EWM properties must not be None.') if elf_properties is None: raise RuntimeError('EWM ELF properties must not be None.') # Initialize internal properties self._image_entry = 0 self._relocatable = False # Set properties from the config file if general_properties.image_entry: self.image_entry = int(general_properties.image_entry, 16) else: self.image_entry = int(ewm_properties.image_entry, 16) self.relocatable = ewm_properties.relocatable # Wrap the data in elf if it doesnt already if not self.is_elf(data): data = self.inject_elf_wrapper(data) SecParseGenElf.__init__(self, data, None, elf_properties, general_properties, self.encdec, debug_dir, debug_prefix, debug_suffix, validating, signing, parsegens, sign_attr)
def __init__(self, data, imageinfo=None, bin_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: bin_properties = imageinfo.image_type.bin_properties if bin_properties is None: raise RuntimeError('BIN properties must not be None.') # Extract the encryption params self.data, self.encryption_params = self.extract_encryption_params(data)
def __repr__(self): def segment_properties(seg, segment_name): if seg: return segment_name + ' Segment Properties: ' + '\n' + repr(seg) + '\n' else: return '' return ('Base Properties: ' + '\n' + SecParseGenBase.__repr__(self) + '\n' 'ELF Properties: ' + '\n' + repr(self._elf_parsegen) + '\n' 'Hash Segment Properties: ' + '\n' + repr(self._mbn_parsegen) + '\n' + segment_properties(self._license_manager_segment, 'License Manager') + 'SecElf Properties: ' + '\n' '' + properties_repr([('image_type', self.image_type), ('max_elf_segments', self.max_elf_segments), ('testsig_serialnum', hex_addr(self.serial_num) if self.serial_num is not None else self.serial_num), ]))
def __init__(self, data, imageinfo=None, mbn_properties=None, general_properties=None, encdec=None, debug_dir=None, debug_prefix=None, debug_suffix=None, validating=False, signing=False, parsegens=None, sign_attr=False): SecParseGenBase.__init__(self, data, imageinfo, general_properties, encdec, debug_dir, debug_prefix, debug_suffix, validating, signing, parsegens, sign_attr) # Check the arguments if imageinfo is not None: mbn_properties = imageinfo.image_type.mbn_properties if mbn_properties is None: raise RuntimeError('MBN properties must not be None.') # Set padding based on authorities if self.qti_signing_enabled and self.oem_signing_enabled: pad_max_sig_size, pad_max_cc_size = MAX_SIG_SIZE, self.get_cert_chain_size( defines.AUTHORITY_OEM) else: pad_max_sig_size, pad_max_cc_size = 0, 0 pad_max_ep_size = len(self.encdec.get_encryption_parameters_blob() ) if self.encdec is not None else 0 # Initialize the mbn parsegen self._mbn_parsegen = mbn.ParseGenMbn( data, mbn_properties.header_size, SECBOOT_MBN_HDR[self.secboot_version], self.debug_dir, self.debug_prefix, self.debug_suffix, pad_max_sig_size, pad_max_cc_size, pad_max_ep_size) self.code_size = self._mbn_parsegen.code_size # Sig or cert chain should not exist when corresponding authority permissions are disabled self.validate_image_sig() # Private variables self._data_signature_qti = '' self._cert_chain_qti = '' # Extract encryption params self.encryption_params = self._mbn_parsegen.encryption_params # Backup authority authority = self.authority # Set the QTI signature/QTI cert chain if QTI signing is enabled # Needs to be done before getting OEM data self.authority = defines.AUTHORITY_QTI self.data_signature = self._mbn_parsegen.sign_qti self.cert_chain = self._mbn_parsegen.cert_chain_qti # Set the OEM signature/OEM cert chain self.authority = defines.AUTHORITY_OEM self.data_signature = self._mbn_parsegen.sign self.cert_chain = self._mbn_parsegen.cert_chain # Restore authority self.authority = authority # If incoming image is signed or encrypted, validate the header version if self.is_signed() or self.is_encrypted(): self._mbn_parsegen.header.validate()
def __repr__(self): return ('Base Properties: ' + '\n' + SecParseGenBase.__repr__(self) + '\n' 'MBN Properties: ' + '\n' + repr(self._mbn_parsegen))
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 get_data(self, integrity_check=None, sign=None, encrypt=None): # Resolve the operation integrity_check = self.integrity_check if integrity_check is None else integrity_check sign = self.sign if sign is None else sign encrypt = self.encrypt if encrypt is None else encrypt integrity_check = True if (integrity_check or sign or encrypt) else False # Allow base to do any checks SecParseGenBase.get_data(self, integrity_check, sign, encrypt) if not (integrity_check or sign or encrypt): data = self._elf_parsegen.get_data() else: # Get the size of the hash segment hash_segment_size = self._compute_hash_segment_size( integrity_check, sign, encrypt) hash_segment_addr = self._compute_hash_address(self._elf_parsegen) # Add the prog & hash entries in phdrs # The data in the prog and hash at this time maybe dummy data phdr_class = self._elf_parsegen.get_new_phdr_entry() prog_phdr_entry = self._get_prog_phdr_entry( phdr_class(), self._elf_parsegen.ehdr) hash_phdr_entry = self._get_hash_phdr_entry( phdr_class(), hash_segment_size, hash_segment_addr, prog_phdr_entry.p_offset + prog_phdr_entry.p_filesz) self._elf_parsegen.shift( prog_phdr_entry.p_offset, hash_phdr_entry.p_offset + hash_phdr_entry.p_filesz - prog_phdr_entry.p_offset, hash_phdr_entry.p_align) self._elf_parsegen.add_segment(prog_phdr_entry, '') self._elf_parsegen.add_segment(hash_phdr_entry, PAD_BYTE_1 * hash_segment_size, index=1) # Update the dest pointer for the mbn self._mbn_parsegen.header.image_dest_ptr = hash_segment_addr + self._mbn_parsegen.header.get_size( ) try: # Generate the hash segment now hash_segment = self.get_hash_segment(integrity_check, sign, encrypt) # Check here for sizes mismatching just in case if len(hash_segment) != hash_segment_size: raise RuntimeError( 'Estimating the size of the hash table was wrong.') # Re-add the hash segment, this time with the real data self._elf_parsegen.remove_segment(hash_phdr_entry) self._elf_parsegen.remove_segment(prog_phdr_entry) self._elf_parsegen.add_segment(prog_phdr_entry, '') self._elf_parsegen.add_segment(hash_phdr_entry, hash_segment, index=1) # If encrypting, change the process segment data if encrypt: parsegen_updater_cls = ParseGenEncDecMap[ self.encdec.get_segment_num_scheme()] parsegen_updater = parsegen_updater_cls( self.store_debug_data, self.encrypt_segment) parsegen_updater.update_parsegen(self._elf_parsegen) try: # Get the elf data data = self._elf_parsegen.get_data() finally: # Restore the process segment data if encrypt: try: parsegen_updater.revert_parsegen( self._elf_parsegen) except Exception as e: logger.warning(str(e)) finally: # Remove the prog try: self._elf_parsegen.remove_segment(prog_phdr_entry) except Exception as e: logger.warning(str(e)) # Remove the hash try: self._elf_parsegen.remove_segment(hash_phdr_entry) except Exception as e: logger.warning(str(e)) return data
def __repr__(self): return ('Base Properties: ' + '\n' + SecParseGenBase.__repr__(self) + '\n' 'PMBL Properties: ' + '\n' + repr(self._pmbl_parsegen))
def get_data(self, integrity_check=None, sign=None, encrypt=None): # Resolve the operation integrity_check = self.integrity_check if integrity_check is None else integrity_check sign = self.sign if sign is None else sign encrypt = self.encrypt if encrypt is None else encrypt integrity_check = True if (integrity_check or sign or encrypt) else False # Allow base to do any checks SecParseGenBase.get_data(self, integrity_check, sign, encrypt) if not (integrity_check or sign or encrypt): data = self._elf_parsegen.get_data() else: # Get the size of the hash segment hash_segment_size = self._compute_hash_segment_size( integrity_check, sign, encrypt) hash_segment_addr = self._compute_hash_address(self._elf_parsegen) # Add the prog & hash entries in phdrs # The data in the prog and hash at this time maybe dummy data phdr_class = self._elf_parsegen.get_new_phdr_entry() prog_phdr_entry = self._get_prog_phdr_entry( phdr_class(), self._elf_parsegen.ehdr) hash_phdr_entry = self._get_hash_phdr_entry( phdr_class(), hash_segment_size, hash_segment_addr) self._elf_parsegen.add_segment(hash_phdr_entry, PAD_BYTE_1 * hash_segment_size) self._elf_parsegen.add_segment(prog_phdr_entry, '') # Update the dest pointer for the mbn self._mbn_parsegen.header.image_dest_ptr = hash_segment_addr + self._mbn_parsegen.header.get_size( ) error = None try: # Generate the hash segment now hash_segment = self.get_hash_segment(integrity_check, sign, encrypt) # Check here for sizes mismatching just in case if len(hash_segment) != hash_segment_size: raise RuntimeError( 'Estimating the size of the hash table was wrong.') # Re-add the hash segment, this time with the real data index = self._elf_parsegen.remove_segment(hash_phdr_entry) self._elf_parsegen.add_segment(hash_phdr_entry, hash_segment, index) # If encrypting, change the process segment data if encrypt: orig_process_data = self._elf_parsegen._process_segment_data self._elf_parsegen._process_segment_data = self._int_process_data self._int_process_data_segment_number = 0 try: # Get the elf data data = self._elf_parsegen.get_data() except Exception as e: error = e finally: # Restore the process segment data if encrypt: try: self._elf_parsegen._process_segment_data = orig_process_data except Exception as tmp_e: logger.warning(str(tmp_e)) # Raise error if needed if error is not None: raise error except Exception as e: error = e finally: # Remove the prog try: self._elf_parsegen.remove_segment(prog_phdr_entry) except Exception as tmp_e: logger.warning(str(tmp_e)) # Remove the hash try: self._elf_parsegen.remove_segment(hash_phdr_entry) except Exception as e: logger.warning(str(tmp_e)) # Raise error if needed if error is not None: raise error return data
def __repr__(self): return ('Base Properties: ' + '\n' + SecParseGenBase.__repr__(self) + '\n' 'ELF Properties: ' + '\n' + repr(self._elf_parsegen) + '\n' 'Hash Segment Properties: ' + '\n' + repr(self._mbn_parsegen))
def get_data(self, integrity_check=None, sign=None, encrypt=None): # Resolve the operation integrity_check = self.integrity_check if integrity_check is None else integrity_check sign = self.sign if sign is None else sign encrypt = self.encrypt if encrypt is None else encrypt integrity_check = True if (integrity_check or sign or encrypt) else False # Allow base to do any checks SecParseGenBase.get_data(self, integrity_check, sign, encrypt) if not (integrity_check or sign or encrypt): data = self._elf_parsegen.get_data() else: # Get the size of the hash segment hash_segment_size = self._compute_hash_segment_size(integrity_check, sign, encrypt) hash_segment_addr = self._compute_hash_address(self._elf_parsegen) # Add the prog & hash entries in phdrs # The data in the prog and hash at this time maybe dummy data phdr_class = self._elf_parsegen.get_new_phdr_entry() prog_phdr_entry = self._get_prog_phdr_entry(phdr_class(), self._elf_parsegen.ehdr) hash_phdr_entry = self._get_hash_phdr_entry(phdr_class(), hash_segment_size, hash_segment_addr) self._elf_parsegen.add_segment(hash_phdr_entry, PAD_BYTE_1 * hash_segment_size) self._elf_parsegen.add_segment(prog_phdr_entry, '') # Update the dest pointer for the mbn self._mbn_parsegen.header.image_dest_ptr = hash_segment_addr + self._mbn_parsegen.header.get_size() error = None try: # Generate the hash segment now hash_segment = self.get_hash_segment(integrity_check, sign, encrypt) # Check here for sizes mismatching just in case if len(hash_segment) != hash_segment_size: raise RuntimeError('Estimating the size of the hash table was wrong.') # Re-add the hash segment, this time with the real data self._elf_parsegen.remove_segment(hash_phdr_entry) self._elf_parsegen.remove_segment(prog_phdr_entry) self._elf_parsegen.add_segment(hash_phdr_entry, hash_segment) self._elf_parsegen.add_segment(prog_phdr_entry, '') # If encrypting, change the process segment data if encrypt: orig_process_data = self._elf_parsegen._process_segment_data self._elf_parsegen._process_segment_data = self._int_process_data self._int_process_data_segment_number = 0 try: # Get the elf data data = self._elf_parsegen.get_data() except Exception as e: error = e finally: # Restore the process segment data if encrypt: try: self._elf_parsegen._process_segment_data = orig_process_data except Exception as tmp_e: logger.warning(str(tmp_e)) # Raise error if needed if error is not None: raise error except Exception as e: error = e finally: # Remove the prog try: self._elf_parsegen.remove_segment(prog_phdr_entry) except Exception as tmp_e: logger.warning(str(tmp_e)) # Remove the hash try: self._elf_parsegen.remove_segment(hash_phdr_entry) except Exception as e: logger.warning(str(tmp_e)) # Raise error if needed if error is not None: raise error return data
def __repr__(self): return ('Base Properties: ' + '\n' + SecParseGenBase.__repr__(self))
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,): 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 = general_properties.testsig_serialnum # 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()) 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) # 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)