Esempio n. 1
0
    def __init__(
        self,
        data,
        header_size,
        preamble_size=None,
        has_magic_num=None,
        page_size=None,
        num_pages=None,
        ota_enabled=False,
        ota_min_size=None,
        debug_dir=None,
        debug_prefix=None,
        debug_suffix=None,
    ):

        # Initialize internal properties
        self._header_size = 0
        self._preamble_size = None
        self._has_magic_num = False
        self._page_size = None
        self._num_pages = None
        self._ota_enabled = False
        self._ota_min_size = None

        self._sign = ''
        self._cert_chain = ''
        self._encryption_params = ''

        # Public properties
        self.debug_dir = debug_dir
        self.debug_prefix = debug_prefix
        self.debug_suffix = debug_suffix
        """
        Extract the various sections of the data into the following components:
        1. magic_number
        2. preamble
        3. header
        4. signature
        5. cert_chain
        6. bin
        """
        # Public attributes
        self.preamble = None
        self.header = None
        self.code = None

        # Set properties
        self.header_size = header_size
        self.preamble_size = preamble_size
        self.has_magic_num = has_magic_num
        self.page_size = page_size
        self.num_pages = num_pages
        self.ota_enabled = ota_enabled
        self.ota_min_size = ota_min_size

        # Store the original image
        self.store_debug_data(df.FILE_DATA_IN, data)

        # Extract the magic number
        if self.has_magic_num:
            data, cookies, magic_cookie = magic.remove(data)
            self.store_debug_data(df.FILE_MAGIC_REMOVED, data)
            magic.validate(cookies, magic_cookie)

        # Extract the preamble
        if self.has_preamble is True:
            # Extract the preamble from the data
            data, prmbl = preamble.remove(data, self.preamble_size)
            self.store_debug_data(df.FILE_PRMBL_REMOVED, data)
            self.store_debug_data(df.FILE_PRMBL_IN, prmbl)

            # Create a new preamble
            self.preamble = preamble.create(self.preamble_size, self.num_pages)
            self.store_debug_data(df.FILE_PRMBL_OUT, self.preamble)

            # Verify the preamble by matching to the expected preamble
            if prmbl != self.preamble:
                raise RuntimeError(
                    'Preamble is invalid. Does not match the expected preamble file.'
                )

        # Extract the header
        data, self.header = extract_header(data, self.header_size)
        self.validate_header(self.header)
        self.store_debug_data(df.FILE_HDR_REMOVED, data)
        self.store_debug_data(df.FILE_HDR_IN, self.header.pack())
        self.store_debug_data(df.FILE_HDR_IN_REPR,
                              repr(self.header),
                              suffix=df.FILE_HDR_IN_REPR_SUFFIX)

        # Extract the encryption params
        data, self.encryption_params = extract_encryption_params(
            data, self.header)
        self.store_debug_data(df.FILE_ENCRYPTION_PARAMS_REMOVED, data)
        self.store_debug_data(df.FILE_ENCRYPTION_PARAMS_IN,
                              self.encryption_params)

        # Extract the cert chain
        data, self.cert_chain = extract_cert_chain(data, self.header)
        self.store_debug_data(df.FILE_CERT_CHAIN_REMOVED, data)
        self.store_debug_data(df.FILE_CERT_CHAIN_IN, self.cert_chain)

        # Extract the signature
        data, self.sign = extract_sign(data, self.header)
        self.store_debug_data(df.FILE_SIGN_REMOVED, data)
        self.store_debug_data(df.FILE_SIGN_IN, self.sign)

        # Save the remaining as code
        self.code = data
        self.store_debug_data(df.FILE_CODE_IN, self.code)
    def __init__(self, data, header_size,
                 preamble_size=None,
                 has_magic_num=None,
                 page_size=None,
                 num_pages=None,
                 ota_enabled=False,
                 ota_min_size=None,
                 debug_dir=None,
                 debug_prefix=None,
                 debug_suffix=None,
                 ):

        # Initialize internal properties
        self._header_size = 0
        self._preamble_size = None
        self._has_magic_num = False
        self._page_size = None
        self._num_pages = None
        self._ota_enabled = False
        self._ota_min_size = None

        self._sign = ''
        self._cert_chain = ''
        self._encryption_params = ''

        # Public properties
        self.debug_dir = debug_dir
        self.debug_prefix = debug_prefix
        self.debug_suffix = debug_suffix

        """
        Extract the various sections of the data into the following components:
        1. magic_number
        2. preamble
        3. header
        4. signature
        5. cert_chain
        6. bin
        """
        # Public attributes
        self.preamble = None
        self.header = None
        self.code = None

        # Set properties
        self.header_size = header_size
        self.preamble_size = preamble_size
        self.has_magic_num = has_magic_num
        self.page_size = page_size
        self.num_pages = num_pages
        self.ota_enabled = ota_enabled
        self.ota_min_size = ota_min_size

        # Store the original image
        self.store_debug_data(df.FILE_DATA_IN, data)

        # Extract the magic number
        if self.has_magic_num:
            data, cookies, magic_cookie = magic.remove(data)
            self.store_debug_data(df.FILE_MAGIC_REMOVED, data)
            magic.validate(cookies, magic_cookie)

        # Extract the preamble
        if self.has_preamble is True:
            # Extract the preamble from the data
            data, prmbl = preamble.remove(data, self.preamble_size)
            self.store_debug_data(df.FILE_PRMBL_REMOVED, data)
            self.store_debug_data(df.FILE_PRMBL_IN, prmbl)

            # Create a new preamble
            self.preamble = preamble.create(self.preamble_size,
                                            self.num_pages)
            self.store_debug_data(df.FILE_PRMBL_OUT, self.preamble)

            # Verify the preamble by matching to the expected preamble
            if prmbl != self.preamble:
                raise RuntimeError('Preamble is invalid. Does not match the expected preamble file.')

        # Extract the header
        data, self.header = extract_header(data, self.header_size)
        self.validate_header(self.header)
        self.store_debug_data(df.FILE_HDR_REMOVED, data)
        self.store_debug_data(df.FILE_HDR_IN, self.header.pack())
        self.store_debug_data(df.FILE_HDR_IN_REPR, repr(self.header), suffix=df.FILE_HDR_IN_REPR_SUFFIX)

        # Extract the encryption params
        data, self.encryption_params = extract_encryption_params(data, self.header)
        self.store_debug_data(df.FILE_ENCRYPTION_PARAMS_REMOVED, data)
        self.store_debug_data(df.FILE_ENCRYPTION_PARAMS_IN, self.encryption_params)

        # Extract the cert chain
        data, self.cert_chain = extract_cert_chain(data, self.header)
        self.store_debug_data(df.FILE_CERT_CHAIN_REMOVED, data)
        self.store_debug_data(df.FILE_CERT_CHAIN_IN, self.cert_chain)

        # Extract the signature
        data, self.sign = extract_sign(data, self.header)
        self.store_debug_data(df.FILE_SIGN_REMOVED, data)
        self.store_debug_data(df.FILE_SIGN_IN, self.sign)

        # Save the remaining as code
        self.code = data
        self.store_debug_data(df.FILE_CODE_IN, self.code)
Esempio n. 3
0
    def __init__(
        self,
        data,
        header_size,
        debug_dir=None,
        debug_prefix=None,
        debug_suffix=None,
    ):

        # Initialize internal properties
        self._header_size = 0
        self._sign = ''
        self._cert_chain = ''
        self._encryption_params = ''

        # Public properties
        self.debug_dir = debug_dir
        self.debug_prefix = debug_prefix
        self.debug_suffix = debug_suffix
        self.invalidate_pointers = False
        """
        Extract the various sections of the data into the following components:
        1. header
        2. signature
        3. cert_chain
        4. bin
        """
        # Public attributes
        self.header = None
        self.code = None

        # Set properties
        self.header_size = header_size

        # Store the original image
        self.store_debug_data(df.FILE_DATA_IN, data)

        # Extract the header
        data, self.header = extract_header(data, self.header_size)
        self.validate_header(self.header)
        self.store_debug_data(df.FILE_HDR_REMOVED, data)
        self.store_debug_data(df.FILE_HDR_IN, self.header.pack())
        self.store_debug_data(df.FILE_HDR_IN_REPR,
                              repr(self.header),
                              suffix=df.FILE_HDR_IN_REPR_SUFFIX)

        # Extract the encryption params
        data, self.encryption_params = extract_encryption_params(
            data, self.header)
        self.store_debug_data(df.FILE_ENCRYPTION_PARAMS_REMOVED, data)
        self.store_debug_data(df.FILE_ENCRYPTION_PARAMS_IN,
                              self.encryption_params)

        # Extract the cert chain
        data, self.cert_chain = extract_cert_chain(data, self.header)
        self.store_debug_data(df.FILE_CERT_CHAIN_REMOVED, data)
        self.store_debug_data(df.FILE_CERT_CHAIN_IN, self.cert_chain)

        # Extract the signature
        data, self.sign = extract_sign(data, self.header)
        self.store_debug_data(df.FILE_SIGN_REMOVED, data)
        self.store_debug_data(df.FILE_SIGN_IN, self.sign)

        # Save the remaining as code
        self.code = data
        self.store_debug_data(df.FILE_CODE_IN, self.code)
Esempio n. 4
0
    def __init__(
        self,
        data=None,
        header_size=None,
        version=MBN_HDR_VERSION_3,
        debug_dir=None,
        debug_prefix=None,
        debug_suffix=None,
        pad_max_sig_size=0,
        pad_max_cert_chain_size=0,
        pad_max_encr_params_size=0,
    ):

        # Param Checks
        if header_size is None:
            raise RuntimeError('Header size must be given.')

        # Create empty mbn file if data is None
        if data is None:
            data = create_empty_mbn(header_size, version)

        # Initialize internal properties
        self._header_size = 0
        self._sign = ''
        self._cert_chain = ''
        self._sign_qc = ''
        self._cert_chain_qc = ''
        self._encryption_params = ''

        # Public properties
        self.debug_dir = debug_dir
        self.debug_prefix = debug_prefix
        self.debug_suffix = debug_suffix
        self.invalidate_pointers = False
        self.version = version

        # Padding sizes
        self.pad_sig_size = 0
        self.pad_cert_chain_size = 0
        self.pad_max_sig_size = pad_max_sig_size
        self.pad_max_cert_chain_size = pad_max_cert_chain_size
        self.pad_max_encr_params_size = pad_max_encr_params_size
        """
        Extract the various sections of the data into the following components:
        1. header
        2. signature
        3. cert_chain
        4. bin
        """
        # Public attributes
        self.header = None
        self.code = None

        # Set properties
        self.header_size = header_size

        # Store the original image
        self.store_debug_data(df.FILE_DATA_IN, data)

        # Extract the header
        data, self.header = extract_header(data, self.header_size,
                                           self.version)
        self.validate_header(self.header)
        self.store_debug_data(df.FILE_HDR_REMOVED, data)
        self.store_debug_data(df.FILE_HDR_IN, self.header.pack())
        self.store_debug_data(df.FILE_HDR_IN_REPR,
                              repr(self.header),
                              suffix=df.FILE_HDR_IN_REPR_SUFFIX)

        # Extract the encryption params
        data, self.encryption_params = extract_encryption_params(
            data, self.header, self.pad_max_sig_size,
            self.pad_max_cert_chain_size, self.pad_max_encr_params_size)
        self.store_debug_data(df.FILE_ENCRYPTION_PARAMS_REMOVED, data)
        self.store_debug_data(df.FILE_ENCRYPTION_PARAMS_IN,
                              self.encryption_params)

        # Extract the cert chain
        data, self.cert_chain = extract_cert_chain(data, self.header)
        self.store_debug_data(df.FILE_CERT_CHAIN_REMOVED, data)
        self.store_debug_data(df.FILE_CERT_CHAIN_IN, self.cert_chain)

        # Extract the signature
        data, self.sign = extract_sign(data, self.header)
        self.store_debug_data(df.FILE_SIGN_REMOVED, data)
        self.store_debug_data(df.FILE_SIGN_IN, self.sign)

        if self.header.supports_qc_signing():
            # Extract the QC cert chain
            data, self.cert_chain_qc = extract_cert_chain_qc(data, self.header)
            self.store_debug_data(df.FILE_CERT_CHAIN_QC_REMOVED, data)
            self.store_debug_data(df.FILE_CERT_CHAIN_QC_IN, self.cert_chain_qc)

            # Extract the QC signature
            data, self.sign_qc = extract_sign_qc(data, self.header)
            self.store_debug_data(df.FILE_SIGN_QC_REMOVED, data)
            self.store_debug_data(df.FILE_SIGN_QC_IN, self.sign_qc)

        # Save the remaining as code
        self.code = data
        self.store_debug_data(df.FILE_CODE_IN, self.code)
Esempio n. 5
0
    def get_header(self, authority=None, imageinfo=None, validating=False):
        hdr = self.header

        # Set some flags
        single_signing = self.pad_max_sig_size == 0
        signing = self.pad_sig_size != 0

        # Set header metadata
        if imageinfo is not None and hdr.supports_metadata():
            # Don't modify the internal header object if user is validating image otherwise
            # header metadata contents log will not reflect metadata of image being validated
            # but rather image metadata being validated against
            if validating:
                _, hdr = extract_header(hdr.pack(), hdr.get_size(), self.version)
                if not single_signing and authority == AUTHORITY_QTI:
                    hdr.set_metadata(None)
            else:
                if single_signing:
                    if authority == AUTHORITY_QTI:
                        hdr.set_metadata_qti(imageinfo)
                    else:
                        hdr.set_metadata(imageinfo)
                else:
                    if authority == AUTHORITY_QTI:
                        hdr.set_metadata_qti(imageinfo)
                        hdr.set_metadata(None)
                    else:
                        hdr.set_metadata(imageinfo)

        # Update the pointer & sizes
        hdr.code_size = len(self.code)
        sig_size, cert_chain_size = len(self.sign), len(self.cert_chain)
        hdr.sig_size, hdr.cert_chain_size = sig_size, cert_chain_size

        # MBN v5 and v6 usecases
        if hdr.supports_qti_signing():
            sig_size_qti, cert_chain_size_qti = len(self.sign_qti), len(self.cert_chain_qti)
            hdr.sig_size_qti, hdr.cert_chain_size_qti = sig_size_qti, cert_chain_size_qti
            if authority == AUTHORITY_QTI:
                hdr.sig_size, hdr.cert_chain_size = 0, 0

            # Single signing / exclusive usecase
            if single_signing:
                # Both QTI and OEM data cannot be set
                if sig_size and sig_size_qti:
                    raise RuntimeError('Both QTI & OEM signature must not be set')

                # If both are empty, use padding for data to sign
                if (sig_size, sig_size_qti) == (0, 0):
                    if authority == AUTHORITY_QTI:
                        sig_size_qti, cert_chain_size_qti = self.pad_sig_size, self.pad_cert_chain_size
                        hdr.sig_size_qti, hdr.cert_chain_size_qti = sig_size_qti, cert_chain_size_qti
                    else:
                        sig_size, cert_chain_size = self.pad_sig_size, self.pad_cert_chain_size
                        hdr.sig_size, hdr.cert_chain_size = sig_size, cert_chain_size

            # Double signing
            else:
                # Both QTI & OEM are empty, use padding to return to sign
                if (sig_size, sig_size_qti) == (0, 0):
                    if authority == AUTHORITY_QTI:
                        sig_size_qti, cert_chain_size_qti = self.pad_sig_size, self.pad_cert_chain_size
                        hdr.sig_size_qti, hdr.cert_chain_size_qti = sig_size_qti, cert_chain_size_qti

                        if signing:
                            sig_size = self.pad_max_sig_size
                            cert_chain_size = self.pad_max_cert_chain_size
                    else:
                        sig_size, cert_chain_size = self.pad_sig_size, self.pad_cert_chain_size
                        hdr.sig_size, hdr.cert_chain_size = sig_size, cert_chain_size

                        if signing:
                            sig_size_qti = self.pad_max_sig_size
                            cert_chain_size_qti = self.pad_max_cert_chain_size

                # QTI is empty
                elif (sig_size_qti, cert_chain_size_qti) == (0, 0):
                    if signing:
                        sig_size_qti = self.pad_max_sig_size
                        cert_chain_size_qti = self.pad_max_cert_chain_size
                    if authority == AUTHORITY_QTI:
                        hdr.sig_size_qti = self.pad_sig_size
                        hdr.cert_chain_size_qti = self.pad_cert_chain_size
                    else:
                        sig_size, cert_chain_size = self.pad_sig_size, self.pad_cert_chain_size
                        hdr.sig_size, hdr.cert_chain_size = sig_size, cert_chain_size

                # OEM is empty
                elif (sig_size, cert_chain_size) == (0, 0):
                    if signing:
                        sig_size = self.pad_max_sig_size
                        cert_chain_size = self.pad_max_cert_chain_size
                    if authority == AUTHORITY_QTI:
                        sig_size_qti, cert_chain_size_qti = self.pad_sig_size, self.pad_cert_chain_size
                        hdr.sig_size_qti, hdr.cert_chain_size_qti = sig_size_qti, cert_chain_size_qti
                    else:
                        hdr.sig_size = self.pad_sig_size
                        hdr.cert_chain_size = self.pad_cert_chain_size

                # Both are non empty
                else:
                    sig_size += self.pad_max_sig_size - sig_size

            # Add QTI sizes for the full size to be used for image size
            sig_size += sig_size_qti
            cert_chain_size += cert_chain_size_qti
        # MBN v3 usecases. This is legacy OEM signing usecase
        else:
            if (sig_size, cert_chain_size) == (0, 0):
                sig_size, cert_chain_size = self.pad_sig_size, self.pad_cert_chain_size
                hdr.sig_size, hdr.cert_chain_size = sig_size, cert_chain_size

        # Invalidate pointers
        if self.invalidate_pointers:
            if hasattr(hdr, 'image_dest_ptr'):
                hdr.image_dest_ptr = MBN_PTR_MAX
            hdr.sig_ptr = MBN_PTR_MAX
            hdr.cert_chain_ptr = MBN_PTR_MAX
        elif not hdr.supports_qti_signing():
            hdr.sig_ptr = hdr.image_dest_ptr + hdr.code_size
            hdr.cert_chain_ptr = hdr.sig_ptr + hdr.sig_size

        # Calculate & byte align the total image size
        image_size = ALIGNED_IMAGE_SIZE(hdr.code_size + sig_size + cert_chain_size)

        # Update the image size in the header
        hdr.image_size = image_size

        return hdr