def store_debug_data(self, file_name, data, prefix=None, suffix=None):
     if prefix is None:
         prefix = self.debug_prefix
     if suffix is None:
         suffix = self.debug_suffix
     if prefix is not None and suffix is not None:
         store_debug_data_to_file(prefix + '_' + file_name + suffix, data,
                                  self.debug_dir)
 def store_debug_data(self, file_name, data, prefix=None, suffix=None):
     if prefix is None:
         prefix = self.debug_prefix
     if suffix is None:
         suffix = self.debug_suffix
     if prefix is not None and suffix is not None:
         store_debug_data_to_file(prefix + '_' + file_name + suffix,
                                  data, self.debug_dir)
 def store_debug_data(self, file_name, data, prefix=None, suffix=None):
     if prefix is None:
         prefix = self.debug_prefix
     if suffix is None:
         suffix = self.debug_suffix
     if prefix is not None and suffix is not None:
         store_debug_data_to_file(str(prefix) + '_' + str(file_name) + str(suffix),
                                  data, self.debug_dir)
示例#4
0
 def store_debug_data(self, file_name, data, debug_dir=None, prefix=None, suffix=None):
     if prefix is None:
         prefix = getattr(self, "debug_prefix", None)
     if suffix is None:
         suffix = getattr(self, "debug_suffix", None)
     if debug_dir is None:
         debug_dir = getattr(self, "debug_dir", None)
     if prefix is not None and suffix is not None:
         store_debug_data_to_file(prefix + '_' + file_name + suffix, data, debug_dir)
示例#5
0
    def _unpack(self, data):
        # Validate size of segment is not smaller than allowed minimum
        min_size_of_hash_entry = min(HASH_ALGO_TO_SIZE_MAP.values())
        min_size = self._get_fixed_size() + self._get_id_size() + min_size_of_hash_entry
        if len(data) < min_size:
            raise RuntimeError(multi_image_string() + " segment is of invalid size {0} bytes."
                               "\nMinimum allowed size is {1} bytes.".format(len(data), min_size))

        # Extract segment header
        offset = 0
        end = self._get_fixed_size()
        (self.magic_number,
         self.version,
         self.res0, self.res1, self.res2, self.res3, self.res4, self.res5, self.res6, self.res7, self.res8, self.res9,
         self.res10, self.res11, self.res12, self.res13, self.res14, self.res15, self.res16, self.res17, self.res18, self.res19, self.res20,
         self.res21, self.res22, self.res23, self.res24, self.res25, self.res26, self.res27, self.res28, self.res29, self.res30, self.res31,
         num_images,
         hash_algorithm,) = struct.unpack(self._get_fixed_format(), data[offset:end])

        # Validate extracted values
        if self.magic_number != MAGIC_NUM:
            raise RuntimeError(multi_image_string() + " segment contains invalid magic number {0}."
                               "\nMagic number must be {1}.".format(self.magic_number, MAGIC_NUM))
        if self.version != MULT_IMAGE_VERSION_0:
            raise RuntimeError(multi_image_string() + " segment contains invalid version number {0}."
                               "\nSupported version are: {1}.".format(self.version, SUPPORTED_VERSIONS))
        if num_images > MAX_NUM_IMAGES:
            raise RuntimeError(multi_image_string() + " segment contains {0} image entries."
                               "\nMaximum allowed number of images entries is {1}.".format(num_images, MAX_NUM_IMAGES))
        if hash_algorithm not in DECODE_HASH_ALGO:
            raise RuntimeError(multi_image_string() + " segment contains invalid hash algorithm value {0}."
                               "\nAllowed hash algorithm values are {1}.".format(hash_algorithm, DECODE_HASH_ALGO.keys()))
        elif DECODE_HASH_ALGO[hash_algorithm] != self.hash_algorithm:
            raise RuntimeError(multi_image_string() + " segment was created using {0} but segment_hash_algorithm is configured to {1}."
                               "\nChange configured segment_hash_algorithm value to {0}.".format(DECODE_HASH_ALGO[hash_algorithm], self.hash_algorithm))
        # Validate segment size
        expected_size = self._get_fixed_size() + (self._get_id_size() + HASH_ALGO_TO_SIZE_MAP[self.hash_algorithm]) * num_images
        if expected_size < len(data):
            raise RuntimeError(multi_image_string() + " segment is of invalid size {0} bytes."
                               "\nSegment containing {1} {2} image entries should be {} bytes.".format(len(data), num_images, self.hash_algorithm, expected_size))

        # Extract sw_id/app_id and hash values
        for i in range(num_images):
            offset = end
            end += self._get_id_size()
            (sw_id, app_id,) = struct.unpack(self._get_id_format(), data[offset:end])
            hash_size = HASH_ALGO_TO_SIZE_MAP[self.hash_algorithm]
            offset = end
            end += hash_size
            image_hash = data[offset:end]
            self.image_hash_dict[(sw_id, app_id)] = image_hash

        store_debug_data_to_file(FILE_EXTRACTED, data[0:end], self.debug_dir)
        store_debug_data_to_file(FILE_EXTRACTED_READABLE, str(self), self.debug_dir)
    def __init__(self,
                 encryption_params_blob=None,
                 private_key=None,
                 config=None,
                 debug_dir=None,
                 l3_key_blob=None,
                 validating=False,
                 encrypted_segments_indices=None):
        self.image_id = int(
            config.signing_attributes.sw_id[EncryptionParameters.
                                            SOFTWARE_TYPE_FLD_OFFSET:], 16)
        if encryption_params_blob is None and private_key is None and l3_key_blob is None:
            self.key_service = key_service_module.KeyService(config)
            encryption_params_blob, private_key = self._generate_new_blob(
                config,
                debug_dir,
                encrypted_segments_indices=encrypted_segments_indices)
            # Set the base params
            BaseEncryptionParameters.__init__(
                self,
                encryption_params_blob=encryption_params_blob,
                key=private_key,
                debug_dir=debug_dir,
                validating=validating)
        elif encryption_params_blob is not None and l3_key_blob is not None:
            self._set_l3_and_iv(encryption_params_blob, l3_key_blob)
            # Set the base params
            BaseEncryptionParameters.__init__(
                self,
                encryption_params_blob=encryption_params_blob,
                key=None,
                debug_dir=debug_dir,
                validating=validating)
        elif encryption_params_blob is not None and private_key is not None:
            # Set the base params
            BaseEncryptionParameters.__init__(
                self,
                encryption_params_blob=encryption_params_blob,
                key=private_key,
                debug_dir=debug_dir,
                validating=validating)
            # Get the image encryption key & iv
            self._decode_blob(encryption_params_blob, private_key, debug_dir)
        else:
            raise RuntimeError(
                "ERROR: Invalid configuration of params used to create encryption params."
            )

        store_debug_data_to_file(defines.DEST_DEBUG_FILE_ENCRYPTION_PARAMETERS,
                                 hexdump(self.encryption_params_blob),
                                 debug_dir)
    def process_signature_response(self):
        self.signature_package = SignaturePackage(
            self.connector_response,
            self.signing_package.get_digest().lower(),
            self.signature_result_file_name)

        [signature, cert_chain_list
         ] = signerutils.readSigFromZip(self.signature_result_file_name)
        if not self.validate_sig_using_hash(self.hash_to_sign, signature,
                                            cert_chain_list):
            raise ExternalSignerError(
                self.MESG_INVALID_SIG.format(self.signature_result_file_name))

        # Validate padding
        cert_text = crypto.cert.get_text(cert_chain_list[0])
        use_pss = crypto.cert.get_sign_algo(
            cert_text) == crypto.cert.SIGN_ALGO_RSA_PSS
        cass_padding = self.PAD_PSS if use_pss else self.PAD_PKCS
        if cass_padding != self.padding:
            raise ExternalSignerError(
                self.MESG_INVALID_PADDING.format(cass_padding.upper(),
                                                 self.padding.upper()))

        # Clean up/save signing package and signature response
        if self.debug_dir is None:
            c_path.clean_file(self.signing_package_file_name)
            c_path.clean_file(self.signature_result_file_name)

        c_misc.store_debug_data_to_file(self.SIGNATURE_PACKAGE_FILENAME,
                                        self.connector_response,
                                        self.debug_dir)

        # Extract certificates to create signer output
        out_root_cert = None
        out_attest_ca_cert = None
        out_attest_cert = cert_chain_list[0]
        if len(cert_chain_list) == 3:
            out_attest_ca_cert = cert_chain_list[1]
            out_root_cert = cert_chain_list[2]
        elif len(cert_chain_list) == 2:
            out_root_cert = cert_chain_list[1]

        signer_output = SignerOutput()
        signer_output.root_cert = out_root_cert
        signer_output.attestation_ca_cert = out_attest_ca_cert
        signer_output.attestation_cert = out_attest_cert
        signer_output.signature = signature

        return signer_output
    def sign(self,
             hash_to_sign,
             imageinfo,
             binary_to_sign=None,
             debug_dir=None):
        cass_signer_attributes = self.config.signing.signer_attributes.cass_signer_attributes
        self._validate_config(cass_signer_attributes)

        if debug_dir is not None:
            cass_output_dir = debug_dir
        else:
            cass_output_dir = imageinfo.dest_image.image_dir

        signingpackage_fname = os.path.join(cass_output_dir,
                                            self.SIGNINGPACKAGE_FILENAME)
        signature_result_fname = os.path.join(cass_output_dir,
                                              self.SIGNATURE_RESULT_FILENAME)
        signing_package = self._generate_signing_package(
            hash_to_sign, imageinfo.signing_attributes, cass_signer_attributes,
            imageinfo.dest_image.image_path, signingpackage_fname,
            binary_to_sign)

        connector = CassConnector(cass_signer_attributes)
        signature_package_blob = connector.sign(signingpackage_fname,
                                                imageinfo.dest_image.image_dir)
        self._process_signature_package(signature_package_blob,
                                        signing_package,
                                        signature_result_fname)

        [signature, cert_chain_list] = signerutils.\
                                    readSigFromZip(signature_result_fname)
        if self.validate_sig(binary_to_sign, signature,
                             cert_chain_list) is False:
            raise ExternalSignerError(
                self.MESG_INVALID_SIG.format(signature_result_fname))

        signer_output = self._get_signer_output(signature, cert_chain_list)

        #Clean up/save signing package and signature response
        if debug_dir is None:
            c_path.clean_file(signingpackage_fname)
            c_path.clean_file(signature_result_fname)

        c_misc.store_debug_data_to_file(self.SIGNATUREPACKAGE_FILENAME,
                                        signature_package_blob, debug_dir)

        return signer_output
    def sign(self, hash_to_sign, imageinfo, binary_to_sign = None, debug_dir=None):
        cass_signer_attributes = self.config.signing.signer_attributes.cass_signer_attributes
        self._validate_config(cass_signer_attributes)

        if debug_dir is not None:
            cass_output_dir = debug_dir
        else:
            cass_output_dir = imageinfo.dest_image.image_dir

        signingpackage_fname = os.path.join(cass_output_dir, self.SIGNINGPACKAGE_FILENAME)
        signature_result_fname = os.path.join(cass_output_dir, self.SIGNATURE_RESULT_FILENAME)
        signing_package = self._generate_signing_package(hash_to_sign,
                      imageinfo.signing_attributes,
                      cass_signer_attributes,
                      imageinfo.dest_image.image_path,
                      signingpackage_fname,
                      binary_to_sign
                      )

        connector = CassConnector(cass_signer_attributes)
        signature_package_blob = connector.sign(signingpackage_fname, imageinfo.dest_image.image_dir)
        self._process_signature_package(signature_package_blob, signing_package, signature_result_fname)

        [signature, cert_chain_list] = signerutils.\
                                    readSigFromZip(signature_result_fname)
        if self.validate_sig(binary_to_sign, signature,
                                    cert_chain_list) is False:
            raise ExternalSignerError(
                    self.MESG_INVALID_SIG.format(signature_result_fname))

        signer_output = self._get_signer_output(signature, cert_chain_list)

        #Clean up/save signing package and signature response
        if debug_dir is None:
            c_path.clean_file(signingpackage_fname)
            c_path.clean_file(signature_result_fname)

        c_misc.store_debug_data_to_file(self.SIGNATUREPACKAGE_FILENAME,
                                        signature_package_blob,
                                        debug_dir)

        return signer_output
示例#10
0
    def pack(self):
        # Pack segment header
        data = struct.pack(self._get_fixed_format(),
                           ensure_binary(self.magic_number),
                           self.version,
                           self.res0, self.res1, self.res2, self.res3, self.res4, self.res5, self.res6, self.res7, self.res8, self.res9,
                           self.res10, self.res11, self.res12, self.res13, self.res14, self.res15, self.res16, self.res17, self.res18, self.res19, self.res20,
                           self.res21, self.res22, self.res23, self.res24, self.res25, self.res26, self.res27, self.res28, self.res29, self.res30, self.res31,
                           len(self.image_hash_dict),
                           ENCODE_HASH_ALGO[self.hash_algorithm])

        # Pack sw_id/app_id and hash values
        for (sw_id, app_id), image_hash in self.image_hash_dict.items():
            data += struct.pack(self._get_id_format(), sw_id, app_id)
            data += image_hash

        store_debug_data_to_file(FILE_GENERATED, data, self.debug_dir)
        store_debug_data_to_file(FILE_GENERATED_READABLE, str(self), self.debug_dir)

        return data
    def process_signature_response(self):
        self.signature_package = SignaturePackage(
            self.connector_response,
            self.signing_package.get_digest().lower(),
            self.signature_result_file_name)

        [signature, cert_chain_list
         ] = signerutils.readSigFromZip(self.signature_result_file_name)
        if self.validate_sig_using_hash(self.hash_to_sign, signature,
                                        cert_chain_list) is False:
            raise ExternalSignerError(
                self.MESG_INVALID_SIG.format(self.signature_result_file_name))

        # Clean up/save signing package and signature response
        if self.debug_dir is None:
            c_path.clean_file(self.signing_package_file_name)
            c_path.clean_file(self.signature_result_file_name)

        c_misc.store_debug_data_to_file(self.SIGNATURE_PACKAGE_FILENAME,
                                        self.connector_response,
                                        self.debug_dir)

        # Extract certificates to create signer output
        out_root_cert = None
        out_attest_ca_cert = None
        out_attest_cert = cert_chain_list[0]
        if len(cert_chain_list) == 3:
            out_attest_ca_cert = cert_chain_list[1]
            out_root_cert = cert_chain_list[2]
        elif len(cert_chain_list) == 2:
            out_root_cert = cert_chain_list[1]

        signer_output = SignerOutput()
        signer_output.root_cert = out_root_cert
        signer_output.attestation_ca_cert = out_attest_ca_cert
        signer_output.attestation_cert = out_attest_cert
        signer_output.signature = signature

        return signer_output
示例#12
0
    def _decode_binary_blob(self, binary_blob, validating, l1_key, debug_dir):
        string_offset = 0
        string_end = EncryptionParamsSectionBody.B0block.get_spec_size()

        self.L2B0block = EncryptionParamsSectionBody.B0block(binary_blob[string_offset:string_end])
        self.L2_IV = self.L2B0block.nonce_fld
        logger.debug("L2 IV: \n" + hexdump(self.L2_IV))

        string_offset = string_end
        string_end += EncryptionParamsSectionBody.L2AssociatedData.get_spec_size()
        self.L2_associated_data = binary_blob[string_offset:string_end]
        EncryptionParamsSectionBody.L2AssociatedData(self.L2_associated_data_major_version,
                                                     self.L2_associated_data_minor_version,
                                                     self.image_id,
                                                     binary_blob=self.L2_associated_data,
                                                     validating=validating)

        string_offset = string_end
        string_end += EncryptionParamsSectionBody.ENCRYPTED_KEY_PAYLOAD_LEN_BYTES
        self.L1_key_payload = binary_blob[string_offset:string_end]

        string_offset = string_end
        string_end += EncryptionParamsSectionBody.MAC_LEN_BYTES
        self.L2_MAC = binary_blob[string_offset:string_end]

        store_debug_data_to_file(defines.DEST_DEBUG_FILE_ENCRYPTED_L2_KEY, self.L1_key_payload + self.L2_MAC, debug_dir)
        store_debug_data_to_file(defines.DEST_DEBUG_FILE_L2_IMAGE_IV, self.L2_IV, debug_dir)
        store_debug_data_to_file(defines.DEST_DEBUG_FILE_L2_ADD, self.L2_associated_data, debug_dir)

        try:
            self.l2_key = crypto.aes_ccm.decrypt(self.L1_key_payload + self.L2_MAC,
                                                 binascii.hexlify(l1_key),
                                                 binascii.hexlify(self.L2_IV),
                                                 binascii.hexlify(self.L2_associated_data))
            logger.debug("L2 Key extracted from image: \n" + hexdump(self.l2_key))
            logger.debug("Any previously generated L2 keys will be ignored.")
        except subprocess.CalledProcessError:
            raise RuntimeError("Extraction of L2 key from image failed. This can be caused by the use of an invalid L1 key.")

        string_offset = string_end
        string_end += EncryptionParamsSectionBody.B0block.get_spec_size()
        self.L3B0block = EncryptionParamsSectionBody.B0block(binary_blob[string_offset:string_end])
        self.L3_IV = self.L3B0block.nonce_fld
        logger.debug("L3 IV: \n" + hexdump(self.L3_IV))

        string_offset = string_end
        string_end += EncryptionParamsSectionBody.L3AssociatedData.get_spec_size()
        self.L3_associated_data = binary_blob[string_offset:string_end]

        string_offset = string_end
        string_end += EncryptionParamsSectionBody.ENCRYPTED_KEY_PAYLOAD_LEN_BYTES
        self.L2_key_payload = binary_blob[string_offset:string_end]

        string_offset = string_end
        string_end += EncryptionParamsSectionBody.MAC_LEN_BYTES
        self.L3_MAC = binary_blob[string_offset:string_end]

        store_debug_data_to_file(defines.DEST_DEBUG_FILE_ENCRYPTED_L3_KEY, self.L2_key_payload + self.L3_MAC, debug_dir)
        store_debug_data_to_file(defines.DEST_DEBUG_FILE_L3_IMAGE_IV, self.L3_IV, debug_dir)
        store_debug_data_to_file(defines.DEST_DEBUG_FILE_L3_ADD, self.L3_associated_data, debug_dir)

        try:
            self.l3_key = crypto.aes_ccm.decrypt(self.L2_key_payload + self.L3_MAC,
                                                 binascii.hexlify(self.l2_key),
                                                 binascii.hexlify(self.L3_IV),
                                                 binascii.hexlify(self.L3_associated_data))
            logger.debug("L3 Key extracted from image: \n" + hexdump(self.l3_key))
            logger.debug("Any previously generated L3 keys will be ignored.")
        except subprocess.CalledProcessError:
            raise RuntimeError("Extraction of L3 key from image failed. This can be caused by the use of an invalid L1 or L2 key.")

        string_offset = string_end
        string_end += EncryptionParamsSectionBody.BASE_IV_LEN_BYTES
        self.base_iv = binary_blob[string_offset:string_end]