Exemple #1
0
    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
Exemple #2
0
 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()
Exemple #6
0
    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