Exemple #1
0
    def sign(self,
             data_to_sign,
             imageinfo,
             debug_dir=None,
             is_hash=False,
             **kwargs):
        """
        This function returns a SignerOutput object which has all the security assets generated
        by the signer.
        """
        # Set the input information
        self.set_input(data_to_sign,
                       imageinfo,
                       debug_dir=debug_dir,
                       is_hash=is_hash,
                       **kwargs)

        # Set the certificates and keys for output
        signer_output = self.sign_hash(self.hash_to_sign,
                                       imageinfo,
                                       data_to_sign,
                                       debug_dir=debug_dir,
                                       hash_algo=self.hash_algo)

        # Get the hmac params from attestation cert or hash segment
        extracted_image_attributes = self._attribute_extractor(
            cert_data=signer_output.attestation_cert,
            attributes=self.signing_attributes_class(),
            **kwargs).attributes
        hmac_from_image = HMAC()
        hmac_from_image.init_from_image_attributes(extracted_image_attributes,
                                                   self.signing_attributes)

        # Get the hmac params from config
        hmac_from_config = HMAC()
        hmac_from_config.init_from_config(self.signing_attributes)

        # Recreate the hash to sign if necessary
        if hmac_from_config.hmac_type == hmac_from_config.HMAC_TYPE_QTI and not hmac_from_image.is_equal(
                hmac_from_config):
            if self.data_to_sign is not None:
                self.hash_to_sign = hmac_from_image.hmac(self.data_to_sign)
            else:
                raise RuntimeError(
                    'HMAC params from image cannot be used with pre-generated hash.'
                )

        # Set the signature
        signer_output.signature = self.get_signature()
        signer_output.unsigned_hash = self.hash_to_sign

        self._print_attestation_cert_props(signer_output.attestation_cert,
                                           **kwargs)

        return signer_output
Exemple #2
0
    def sign(self, data_to_sign, imageinfo, debug_dir=None, is_hash=False):
        '''
        This function returns a SignerOutput object which has all the security assets generated
        by the signer.
        '''
        # Set the input information
        self.set_input(data_to_sign, imageinfo, debug_dir, is_hash)

        # Set the certificates and keys for output
        signer_output = SignerOutput()
        signer_output.root_cert, signer_output.root_key = self.get_root_cert_key()
        if self.CA in self.certs:
            signer_output.attestation_ca_cert, signer_output.attestation_ca_key = self.get_ca_cert_key()
        signer_output.attestation_cert, signer_output.attestation_key = self.get_attest_cert_key()

        # Set the root certs for MRC
        signer_output.root_cert_list = self.get_root_cert_list()

        # Get the hmac params from attestation cert
        hmac_from_cert = HMAC()
        hmac_from_cert.init_from_cert(signer_output.attestation_cert)

        # Get the hmac params from config
        hmac_from_config = HMAC()
        hmac_from_config.init_from_config(self.signing_attributes)

        # Recreate the hash to sign if necessary
        if (hmac_from_config.hmac_type == hmac_from_config.HMAC_TYPE_QC and
                not hmac_from_cert.is_equal(hmac_from_config)):
            if self.data_to_sign is not None:
                self.hash_to_sign = hmac_from_cert.hmac(self.data_to_sign)
            else:
                raise RuntimeError('HMAC params from attestation certificate cannot be used with pre-generated hash.')

        # Set the signature
        signer_output.signature = self.get_signature()
        signer_output.unsigned_hash = self.hash_to_sign

        # Update the certs
        signer_output.update_certs_format()

        # Set the cert chain
        signer_output.generate_cert_chain()

        # Print certificate properties (to make tests pass and give good debug information)
        logger.info('\nAttestation Certificate Properties:\n' +
                    str(Certificate(signer_output.attestation_cert)))

        return signer_output
Exemple #3
0
    def create_subject_params_attest(self, in_params):
        # Set exfile
        self.certs[self.ATTEST].extfile = self.openssl_info.attest_ca_xts

        # GET SIGNING ATTRIBUTE DATA
        debug_val = int(self.signing_attributes.debug, 16)
        oem_id = int(self.signing_attributes.oem_id, 16) & 0xFFFF
        model_id = int(self.signing_attributes.model_id, 16) & 0xFFFF
        in_use_soc_hw_version = self.signing_attributes.in_use_soc_hw_version
        use_serial_number_in_signing = self.signing_attributes.use_serial_number_in_signing

        # Get the binary to sign length
        if self.data_to_sign_len is None:
            if self.hash_to_sign is not None:
                self.data_to_sign_len = len(self.hash_to_sign)
            else:
                raise RuntimeError('Length of binary could not be computed')

        logger.debug('Generating new Attestation certificate and a random key')
        hmac_params = HMAC()
        hmac_params.init_from_config(self.signing_attributes)
        certificate_ou_sw_id = '01 ' + '%.16X' % hmac_params.sw_id + ' SW_ID'
        certificate_ou_hw_id = '02 ' + '%.16X' % hmac_params.msm_id + ' HW_ID'
        certificate_ou_oem_id = '04 ' + '%0.4X' % oem_id + ' OEM_ID'
        certificate_ou_sw_size = '05 ' + '%0.8X' % self.data_to_sign_len + ' SW_SIZE'
        certificate_ou_model_id = '06 ' + '%0.4X' % model_id + ' MODEL_ID'
        certificate_hash_alg = self.SHA_OU_MAP[
            self.signing_attributes.hash_algorithm]
        certificate_ou_debug_id = '03 ' + '%0.16X' % debug_val + ' DEBUG'

        certificate_ou = [
            certificate_ou_sw_id, certificate_ou_hw_id, certificate_ou_oem_id,
            certificate_ou_sw_size, certificate_ou_model_id,
            certificate_hash_alg, certificate_ou_debug_id
        ]

        # Optional attributes
        if in_use_soc_hw_version == 1:
            certificate_in_use_soc_hw_version = '13 ' + '%0.4X' % in_use_soc_hw_version + ' IN_USE_SOC_HW_VERSION'
            certificate_ou.append(certificate_in_use_soc_hw_version)
        if use_serial_number_in_signing == 1:
            certificate_use_serial_number_in_signing = '14 ' + '%0.4X' % use_serial_number_in_signing +\
                                                       ' USE_SERIAL_NUMBER_IN_SIGNING'
            certificate_ou.append(certificate_use_serial_number_in_signing)

        # Handle OU property binding
        params = dict(in_params)
        if 'OU' in params.keys():
            if type(params['OU']) == list:
                for item in params['OU']:
                    certificate_ou.append(item)
            else:
                certificate_ou.append(params['OU'])

        # Add OU fields
        params['OU'] = certificate_ou
        logger.debug("Adding OU fields to attest certificate.")

        return params
Exemple #4
0
    def sign(self, data_to_sign, imageinfo, debug_dir=None, is_hash=False, hash_segment_metadata=None):
        """
        This function returns a SignerOutput object which has all the security assets generated
        by the signer.
        """
        # Set the input information
        self.set_input(data_to_sign, imageinfo, debug_dir, is_hash)

        signer_output = self.sign_hash(self.hash_to_sign, imageinfo, data_to_sign, debug_dir=debug_dir, hash_algo=self.hash_algo)

        # Get the hmac params from attestation cert or hash segment
        extracted_image_attributes = AttributeExtractor(cert_data=signer_output.attestation_cert, hash_segment_metadata=hash_segment_metadata).attributes
        hmac_from_image = HMAC()
        hmac_from_image.init_from_image_attributes(extracted_image_attributes)

        # Get the hmac params from config
        hmac_from_config = HMAC()
        hmac_from_config.init_from_config(self.signing_attributes)

        # Recreate the hash to sign if necessary
        if hmac_from_config.hmac_type == hmac_from_config.HMAC_TYPE_QTI and not hmac_from_image.is_equal(hmac_from_config):
            if self.data_to_sign is not None:
                self.hash_to_sign = hmac_from_image.hmac(self.data_to_sign)
            else:
                raise RuntimeError('HMAC params from image cannot be used with pre-generated hash.')

        # Set the signature
        signer_output.signature = self.get_signature()
        signer_output.unsigned_hash = self.hash_to_sign

        # Print certificate properties (to make tests pass and give good debug information)
        if hash_segment_metadata is None:
            logger.info('\nAttestation Certificate Properties:\n' +
                        str(Certificate(signer_output.attestation_cert)))

        return signer_output
Exemple #5
0
    def set_input_impl(self,
                       data_to_sign,
                       imageinfo,
                       debug_dir=None,
                       is_hash=False,
                       **kwargs):
        """Set the input.
        :type data_to_sign: str
        :type imageinfo: ImageInfo
        """

        # Validate the image info
        self.validate_config(imageinfo)

        # Set public variables for this session
        self.debug_dir = debug_dir
        sa = self.signing_attributes = imageinfo.general_properties

        # Set the certificates dictionary
        self.certs = dict()
        self.certs[self.ROOT] = CertKeyPair()
        self.certs[self.ATTEST] = CertKeyPair()
        if sa.num_certs_in_certchain == 3:
            self.certs[self.CA] = CertKeyPair()

        # Set the data to sign and the hash to sign
        if is_hash:
            self.hash_to_sign = data_to_sign
            self.data_to_sign = None
        else:
            hasher = HMAC()
            hasher.init_from_config(sa)
            self.hash_to_sign = hasher.hmac(data_to_sign)
            self.data_to_sign = data_to_sign
            self.data_to_sign_len = len(data_to_sign)

        self.padding = (self.PAD_PSS if
                        (sa.rsa_padding and sa.rsa_padding.lower() == 'pss')
                        else self.PAD_PKCS)
        self.hash_algo = sa.hash_algorithm

        # Initialize the secure assets
        self.initialize(imageinfo, **kwargs)

        return sa
Exemple #6
0
    def set_input(self, data_to_sign, imageinfo, debug_dir=None, is_hash=False):
        """Set the input.
        :type data_to_sign: str
        :type imageinfo: ImageInfo
        """

        # Validate the image info
        self.validate_config(imageinfo)

        # Set public variables for this session
        self.debug_dir = debug_dir
        sa = self.signing_attributes = imageinfo.general_properties

        # Set the certificates dictionary
        self.certs = {}
        self.certs[self.ROOT] = CertKeyPair()
        self.certs[self.ATTEST] = CertKeyPair()
        if sa.num_certs_in_certchain == 3:
            self.certs[self.CA] = CertKeyPair()

        # Set the data to sign and the hash to sign
        if is_hash:
            self.hash_to_sign = data_to_sign
            self.data_to_sign = None
        else:
            hasher = HMAC()
            hasher.init_from_config(sa)
            self.hash_to_sign = hasher.hmac(data_to_sign)
            self.data_to_sign = data_to_sign
            self.data_to_sign_len = len(data_to_sign)
            logger.info('Using ' + hasher.hmac_type + ' (' + hasher.hash_algo + ') for hash segment')

        self.padding = (self.PAD_PSS if (sa.rsa_padding and sa.rsa_padding.lower() == 'pss') else self.PAD_PKCS)
        self.hash_algo = sa.hash_algorithm if sa.hash_algorithm is not None else 'sha256'
        if self.using_ecdsa:
            logger.info("Using ECDSA with {0} curve".format(sa.ecdsa_curve))
        else:
            logger.info('Using ' + self.padding.upper() + ' RSA padding')

        # Initialize the secure assets
        self.initialize(imageinfo)
Exemple #7
0
    def create_subject_params_attest(self, in_params):

        def create_ou_field_from_hex_list(ou_num, ou_name, hex_list, remove_0x, max_num_items_in_ou):
            item_length = 0
            ou_field = str(ou_num)
            for val in hex_list:
                item_length = len(val)-2 if remove_0x else len(val)
                ou_field += " " + (val[2:] if remove_0x else val)
            # fill remainder of OU field with zeros
            zeros = (" " + "0" * item_length) * (max_num_items_in_ou - len(hex_list))
            ou_field += zeros
            ou_field += " " + ou_name
            return ou_field

        # GET SIGNING ATTRIBUTE DATA
        num_root_certs = int(self.signing_attributes.num_root_certs) if self.signing_attributes.num_root_certs is not None else None
        debug_val = int(self.signing_attributes.debug, 16) if self.signing_attributes.debug is not None else None
        debug_serials = self.signing_attributes.debug_serials.serial if self.signing_attributes.debug_serials is not None else []
        oem_id = int(self.signing_attributes.oem_id, 16) & 0xFFFF
        model_id = int(self.signing_attributes.model_id, 16) & 0xFFFF
        app_id = int(self.signing_attributes.app_id, 16) if self.signing_attributes.app_id is not None else None
        crash_dump = int(self.signing_attributes.crash_dump, 16) if self.signing_attributes.crash_dump is not None else None
        rot_en = int(self.signing_attributes.rot_en, 16) if self.signing_attributes.rot_en is not None else None
        mask_soc_hw_version = int(self.signing_attributes.mask_soc_hw_version, 16) if self.signing_attributes.mask_soc_hw_version is not None else None
        in_use_soc_hw_version = self.signing_attributes.in_use_soc_hw_version if self.signing_attributes.in_use_soc_hw_version is not None else None
        soc_vers = self.signing_attributes.soc_vers
        use_serial_number_in_signing = self.signing_attributes.use_serial_number_in_signing if self.signing_attributes.use_serial_number_in_signing is not None else None
        oem_id_independent = self.signing_attributes.oem_id_independent if self.signing_attributes.oem_id_independent is not None else None
        revocation_enablement = int(self.signing_attributes.revocation_enablement, 16) if self.signing_attributes.revocation_enablement is not None else None
        activation_enablement = int(self.signing_attributes.activation_enablement, 16) if self.signing_attributes.activation_enablement is not None else None

        if self._is_oid_supported(self.signing_attributes) is True:
            if self.validate_oid_from_config(self.certs_info.ca.cert_path, self.signing_attributes) is False:
                raise ConfigError('{0} min and max are not set correctly in configuration.' \
                                  'Signing will not continue.'.format(self.signing_attributes.object_id.name)
                                  )
            self.certs[self.ATTEST].extfile = self._generate_attestation_certificate_extensions(
                self.openssl_info.attest_ca_xts,
                self.signing_attributes.object_id.name,
                self.signing_attributes.object_id.min,
                self.signing_attributes.object_id.max)
        else:
            self.certs[self.ATTEST].extfile = self.openssl_info.attest_ca_xts

        # Get the binary to sign length
        if self.data_to_sign_len is None:
            if self.hash_to_sign is not None:
                self.data_to_sign_len = len(self.hash_to_sign)
            else:
                raise RuntimeError('Length of binary could not be computed')

        logger.info('Generating new Attestation certificate and a random key')
        hmac_params = HMAC()
        hmac_params.init_from_config(self.signing_attributes)
        certificate_ou_sw_id = '01 ' + '%.16X' % hmac_params.sw_id + ' SW_ID'
        certificate_ou_hw_id = '02 ' + '%.16X' % hmac_params.msm_id + ' HW_ID'
        certificate_ou_oem_id = '04 ' + '%0.4X' % oem_id + ' OEM_ID'
        certificate_ou_sw_size = '05 ' + '%0.8X' % self.data_to_sign_len + ' SW_SIZE'
        certificate_ou_model_id = '06 ' + '%0.4X' % model_id + ' MODEL_ID'
        certificate_hash_alg = certificate_hash_alg_map[self.signing_attributes.hash_algorithm]

        certificate_ou = [
            certificate_ou_sw_id,
            certificate_ou_hw_id,
            certificate_ou_oem_id,
            certificate_ou_sw_size,
            certificate_ou_model_id,
            certificate_hash_alg
        ]

        # Optional attributes
        if debug_val is not None:
            certificate_ou_debug_id = '03 ' + '%0.16X' % debug_val + ' DEBUG'
            certificate_ou.append(certificate_ou_debug_id)
        if app_id is not None:
            certificate_app_id = '08 ' + '%0.16X' % app_id + ' APP_ID'
            certificate_ou.append(certificate_app_id)
        if crash_dump is not None:
            certificate_crash_dump = '09 ' + '%0.16X' % crash_dump + ' CRASH_DUMP'
            certificate_ou.append(certificate_crash_dump)
        if rot_en is not None:
            certificate_rot_en = '10 ' + '%0.16X' % rot_en + ' ROT_EN'
            certificate_ou.append(certificate_rot_en)
        if mask_soc_hw_version is not None:
            certificate_mask_soc_hw_version = '12 ' + '%0.4X' % mask_soc_hw_version + ' MASK_SOC_HW_VERSION'
            certificate_ou.append(certificate_mask_soc_hw_version)
        if in_use_soc_hw_version == 1:
            certificate_in_use_soc_hw_version = '13 ' + '%0.4X' % in_use_soc_hw_version + ' IN_USE_SOC_HW_VERSION'
            certificate_ou.append(certificate_in_use_soc_hw_version)
        if use_serial_number_in_signing == 1:
            certificate_use_serial_number_in_signing = '14 ' + '%0.4X' % use_serial_number_in_signing + ' USE_SERIAL_NUMBER_IN_SIGNING'
            certificate_ou.append(certificate_use_serial_number_in_signing)
        if oem_id_independent == 1:
            certificate_oem_id_independent = '15 ' + '%0.4X' % oem_id_independent + ' OEM_ID_INDEPENDENT'
            certificate_ou.append(certificate_oem_id_independent)

        # multiple debug serial use case
        certificate_ou_sn_list = []
        for index in xrange(0, len(debug_serials), 6):
            serial_sublist = debug_serials[index: index+6]
            certificate_ou_sn_list.append(create_ou_field_from_hex_list(16, "SN", serial_sublist, True, 6))
        certificate_ou_sn_list.reverse()
        certificate_ou.extend(certificate_ou_sn_list)

        # multiple soc hw version use case
        if soc_vers:
            if self.padding != self.PAD_PSS:
                logger.warning("soc_vers should be used with RSAPSS")
            certificate_ou.append(create_ou_field_from_hex_list(11, "SOC_VERS", soc_vers, True, 10))

        # IOT MRC use case
        if num_root_certs > 1 and self.config.metadata.chipset in IOT_MRC_CHIPSETS:
            certificate_root_cert_sel = '17 ' + '%0.4X' % self.signing_attributes.mrc_index + ' ROOT_CERT_SEL'
            certificate_ou.append(certificate_root_cert_sel)
            if revocation_enablement is not None and revocation_enablement != 0:
                certificate_revocation_enablement = '18 ' + '%0.16X' % revocation_enablement + ' REVOCATION_ENABLEMENT'
                certificate_ou.append(certificate_revocation_enablement)
            if activation_enablement is not None and activation_enablement != 0:
                certificate_activation_enablement = '19 ' + '%0.16X' % activation_enablement + ' ACTIVATION_ENABLEMENT'
                certificate_ou.append(certificate_activation_enablement)

        # Handle OU property binding
        params = dict(in_params)
        if 'OU' in params.keys():
            if type(params['OU']) == list:
                for item in params['OU']:
                    certificate_ou.append(item)
            else:
                certificate_ou.append(params['OU'])

        params['OU'] = certificate_ou
        return params
Exemple #8
0
    def create_subject_params_attest(self, in_params):
        # Set exfile
        if self._is_oid_supported(self.signing_attributes):
            if not self.validate_oid_from_config(self.certs_info.ca.cert_path,
                                                 self.signing_attributes):
                raise ConfigError(
                    '{0} min and max are not set correctly in configuration.'
                    'Signing will not continue.'.format(
                        self.signing_attributes.object_id.name))
            self.certs[
                self.
                ATTEST].extfile = self._generate_attestation_certificate_extensions(
                    self.openssl_info.attest_ca_xts,
                    self.signing_attributes.object_id.name,
                    self.signing_attributes.object_id.min,
                    self.signing_attributes.object_id.max)
        else:
            self.certs[self.ATTEST].extfile = self.openssl_info.attest_ca_xts

        # Only allow OU fields to be added to attest cert if they are not being added to hash segment
        if self.signing_attributes.secboot_version in [SECBOOT_VERSION_3_0]:
            # Don't add OU fields
            logger.debug("Skipping adding OU fields to attest certificate.")
            return dict(in_params)

        def create_ou_field_from_hex_list(ou_num, ou_name, hex_list, remove_0x,
                                          max_num_items_in_ou):
            item_length = 0
            ou_field = str(ou_num)
            for val in hex_list:
                item_length = len(val) - 2 if remove_0x else len(val)
                ou_field += " " + (val[2:] if remove_0x else val)
            # fill remainder of OU field with zeros
            zeros = (" " + "0" * item_length) * (max_num_items_in_ou -
                                                 len(hex_list))
            ou_field += zeros
            ou_field += " " + ou_name
            return ou_field

        # GET SIGNING ATTRIBUTE DATA
        num_root_certs = int(self.signing_attributes.num_root_certs)
        debug_val = int(self.signing_attributes.debug, 16)
        oem_id = int(self.signing_attributes.oem_id, 16) & 0xFFFF
        model_id = int(self.signing_attributes.model_id, 16) & 0xFFFF
        crash_dump = int(self.signing_attributes.crash_dump, 16)
        rot_en = int(self.signing_attributes.rot_en, 16)
        soc_vers = self.signing_attributes.soc_vers
        in_use_soc_hw_version = self.signing_attributes.in_use_soc_hw_version
        use_serial_number_in_signing = self.signing_attributes.use_serial_number_in_signing
        oem_id_independent = self.signing_attributes.oem_id_independent
        revocation_enablement = int(
            self.signing_attributes.revocation_enablement, 16)
        activation_enablement = int(
            self.signing_attributes.activation_enablement, 16)
        root_revoke_activate_enable = int(
            self.signing_attributes.root_revoke_activate_enable, 16)
        uie_key_switch_enable = int(
            self.signing_attributes.uie_key_switch_enable, 16)
        # Signing attributes without default values
        multi_serial_numbers = self.signing_attributes.multi_serial_numbers.serial if self.signing_attributes.multi_serial_numbers is not None else []
        app_id = int(
            self.signing_attributes.app_id,
            16) if self.signing_attributes.app_id is not None else None
        mask_soc_hw_version = int(
            self.signing_attributes.mask_soc_hw_version, 16
        ) if self.signing_attributes.mask_soc_hw_version is not None else None

        # Get the binary to sign length
        if self.data_to_sign_len is None:
            if self.hash_to_sign is not None:
                self.data_to_sign_len = len(self.hash_to_sign)
            else:
                raise RuntimeError('Length of binary could not be computed')

        logger.debug('Generating new Attestation certificate and a random key')
        hmac_params = HMAC()
        hmac_params.init_from_config(self.signing_attributes)
        certificate_ou_sw_id = '01 ' + '%.16X' % hmac_params.sw_id + ' SW_ID'
        certificate_ou_hw_id = '02 ' + '%.16X' % hmac_params.msm_id + ' HW_ID'
        certificate_ou_debug_id = '03 ' + '%0.16X' % debug_val + ' DEBUG'
        certificate_ou_oem_id = '04 ' + '%0.4X' % oem_id + ' OEM_ID'
        certificate_ou_sw_size = '05 ' + '%0.8X' % self.data_to_sign_len + ' SW_SIZE'
        certificate_ou_model_id = '06 ' + '%0.4X' % model_id + ' MODEL_ID'
        certificate_hash_alg = self.SHA_OU_MAP[
            self.signing_attributes.hash_algorithm]

        certificate_ou = [
            certificate_ou_sw_id,
            certificate_ou_hw_id,
            certificate_ou_debug_id,
            certificate_ou_oem_id,
            certificate_ou_sw_size,
            certificate_ou_model_id,
            certificate_hash_alg,
        ]

        # Optional attributes
        if app_id:
            certificate_app_id = '08 ' + '%0.16X' % app_id + ' APP_ID'
            certificate_ou.append(certificate_app_id)
        if crash_dump:
            # Include CRASH_DUMP when it's not zero.
            certificate_crash_dump = '09 ' + '%0.16X' % crash_dump + ' CRASH_DUMP'
            certificate_ou.append(certificate_crash_dump)
        if rot_en:
            # Include ROT_EN when it's not zero.
            certificate_rot_en = '10 ' + '%0.16X' % rot_en + ' ROT_EN'
            certificate_ou.append(certificate_rot_en)
        if mask_soc_hw_version:
            certificate_mask_soc_hw_version = '12 ' + '%0.4X' % mask_soc_hw_version + ' MASK_SOC_HW_VERSION'
            certificate_ou.append(certificate_mask_soc_hw_version)
        if in_use_soc_hw_version == 1:
            # Include IN_USE_SOC_HW_VERSION when it's 1.
            certificate_in_use_soc_hw_version = '13 ' + '%0.4X' % in_use_soc_hw_version + ' IN_USE_SOC_HW_VERSION'
            certificate_ou.append(certificate_in_use_soc_hw_version)
        if use_serial_number_in_signing == 1:
            # Include USE_SERIAL_NUMBER_IN_SIGNING when it's 1.
            certificate_use_serial_number_in_signing = '14 ' + '%0.4X' % use_serial_number_in_signing +\
                                                       ' USE_SERIAL_NUMBER_IN_SIGNING'
            certificate_ou.append(certificate_use_serial_number_in_signing)
        if oem_id_independent == 1:
            # Include OEM_ID_INDEPENDENT when it's 1.
            certificate_oem_id_independent = '15 ' + '%0.4X' % oem_id_independent + ' OEM_ID_INDEPENDENT'
            certificate_ou.append(certificate_oem_id_independent)

        # multiple debug serial use case
        certificate_ou_sn_list = []
        for index in xrange(0, len(multi_serial_numbers), 6):
            serial_sublist = multi_serial_numbers[index:index + 6]
            certificate_ou_sn_list.append(
                create_ou_field_from_hex_list(16, "SN", serial_sublist, True,
                                              6))
        certificate_ou_sn_list.reverse()
        certificate_ou.extend(certificate_ou_sn_list)

        # multiple soc hw version use case
        if soc_vers:
            if self.padding != self.PAD_PSS:
                logger.warning("soc_vers should be used with RSAPSS")
            certificate_ou.append(
                create_ou_field_from_hex_list(11, "SOC_VERS", soc_vers, True,
                                              10))

        # MRC 1.0 use case
        if num_root_certs > 1 and self.config.metadata.chipset in MRC_1_0_CHIPSETS:
            certificate_root_cert_sel = '17 ' + '%0.4X' % self.signing_attributes.mrc_index + ' ROOT_CERT_SEL'
            certificate_ou.append(certificate_root_cert_sel)
            if revocation_enablement:
                certificate_revocation_enablement = '18 ' + '%0.16X' % revocation_enablement + ' REVOCATION_ENABLEMENT'
                certificate_ou.append(certificate_revocation_enablement)
            if activation_enablement:
                certificate_activation_enablement = '19 ' + '%0.16X' % activation_enablement + ' ACTIVATION_ENABLEMENT'
                certificate_ou.append(certificate_activation_enablement)

        # MRC 2.0 use case
        if num_root_certs > 1 and self.config.metadata.chipset in MRC_2_0_CHIPSETS:
            certificate_root_cert_sel = '17 ' + '%0.4X' % self.signing_attributes.mrc_index + ' ROOT_CERT_SEL'
            certificate_ou.append(certificate_root_cert_sel)
            if root_revoke_activate_enable:
                certificate_root_revoke_activate_enable =\
                    '20 ' + '%0.16X' % root_revoke_activate_enable + ' ROOT_REVOKE_ACTIVATE_ENABLE'
                certificate_ou.append(certificate_root_revoke_activate_enable)

        if uie_key_switch_enable:
            certificate_uie_key_switch_enable = '21 ' + '%0.16X' % uie_key_switch_enable + ' UIE_KEY_SWITCH_ENABLE'
            certificate_ou.append(certificate_uie_key_switch_enable)

        # Handle OU property binding
        params = dict(in_params)
        if 'OU' in params.keys():
            if type(params['OU']) == list:
                for item in params['OU']:
                    certificate_ou.append(item)
            else:
                certificate_ou.append(params['OU'])

        # Add OU fields
        params['OU'] = certificate_ou
        logger.debug("Adding OU fields to attest certificate.")

        return params
Exemple #9
0
 def _set_metadata(metadata, imageinfo, metadata_fields, flag_fields, major_version, minor_version, authority):
     # Set metadata dictionary values
     for field_id, field in metadata_fields.iteritems():
         field_name = field[1]
         if field_name == "hw_id":
             if hasattr(imageinfo, field_name):
                 metadata[field_name] = getattr(imageinfo, field_name)
             else:
                 from sectools.features.isc.signer.utils.hmac import HMAC
                 hmac = HMAC()
                 hmac.init_from_config(imageinfo)
                 metadata[field_name] = hmac.msm_id
         elif field_name == "sw_size" and not hasattr(imageinfo, field_name):
             # sw_size is calculated and set inside pack method
             metadata[field_name] = None
         elif field_name != "flags":
             if hasattr(imageinfo, field_name):
                 metadata[field_name] = getattr(imageinfo, field_name)
             else:
                 raise RuntimeError("Config does not contain {0} value which is required by MBN v6 {1} metadata version {2}.{3}".format(field_name, authority, major_version, minor_version))
     # Set metadata dictionary flag values
     for field in flag_fields:
         field_name = field[2]
         if hasattr(imageinfo, field_name):
             metadata[field_name] = getattr(imageinfo, field_name)
         else:
             raise RuntimeError("Config does not contain {0} value which is required by MBN v6 {1} metadata version {2}.{3}".format(field_name, authority, major_version, minor_version))
     # Sanitize metadata values
     for field_id, field in metadata_fields.iteritems():
         field_format = field[0]
         field_count = len(field_format)
         field_name = field[1]
         if field_name != "flags" and field_name != "sw_size":
             value = metadata[field_name]
             # Sanitize non-flag metadata values
             value_count = 1
             if field_name in metadata.keys():
                 if value is None:
                     if field_name == "soc_vers" or field_name == "multi_serial_numbers":
                         value = list()
                     else:
                         value = 0
                 elif isinstance(value, int):
                     pass
                 elif isinstance(value, long):
                     pass
                 elif isinstance(value, list):
                     value = [int(x, 16) if isinstance(x, basestring) or isinstance(x, long) else x for x in value]
                     value_count = len(value)
                 elif field_name == "soc_vers":
                     value = [int(soc_ver, 16) for soc_ver in value.split()]
                     value_count = len(value)
                 elif field_name == "multi_serial_numbers":
                     value = [int(serial, 16) for serial in value.serial]
                     value_count = len(value)
                 elif isinstance(value, basestring):
                     value = int(value, 16)
                 else:
                     raise RuntimeError("Cannot pack {0} into MBN v6 {1} metadata because it is not of type int, str, or list. Type: {2}".format(field_name, authority, metadata[field_name].__class__.__name__))
                 if value_count > field_count:
                     raise RuntimeError("Config contains {0} {1} values but MBN v6 {2} metadata version {3}.{4} only supports {5} {1} values".format(value_count, field_name, authority, major_version, minor_version, field_count))
             else:
                 raise RuntimeError("Config does not contain {0} value which is required by MBN v6 {1} metadata version {2}.{3}".format(field_name, authority, major_version, minor_version))
             # Update metadata value to reflect integer value packed in header
             metadata[field_name] = value
     # Sanitize metadata flag values
     for flag in flag_fields:
         field_name = flag[2]
         value = metadata[field_name]
         if field_name in metadata.keys():
             if value is None:
                 value = 0
             elif isinstance(value, basestring):
                 value = int(value, 16)
             elif isinstance(value, int):
                 pass
             else:
                 raise RuntimeError("Cannot pack {0} into MBN v6 {1} metadata because it is not of type int or str".format(field_name, authority))
             if field_name == "root_revoke_activate_enable" and value != 0 and imageinfo.num_root_certs < 2:
                 value = 0
         else:
             raise RuntimeError("Config does not contain {0} value which is required by MBN v6 {1} metadata version {2}.{3}".format(field_name, authority, major_version, minor_version))
         # Update metadata flag value to reflect integer value packed in header
         metadata[field_name] = value