예제 #1
0
def main(args):
    global mutual_attestation_url
    global secret_url
    global order_url
    global SK

    global key_dir

    key_dir = args['key_dir']

    ip = args['ip_address']
    owner_mr_e = args.get('owner_mr_e', None)

    mutual_attestation_url = 'https://' + ip + ':443/v2/mutual_attestation'
    secret_url = 'https://' + ip + ':443/v2/secrets'
    order_url = 'https://' + ip + ':443/v2/orders'

    SPID = args['spid']
    client_verify_ias = args.get('client_verify_ias', False)
    server_verify_ias = args.get('server_verify_ias', False)
    IAS_CRT = args['ias_crt']

    global proj_id
    proj_id = args['project_id']

    global SGX
    SGX = SGXInterface()
    SGX.init_env_variables()

    enclave_id = SGX.init_enclave(SGX.barbie_c)
    do_mutual_attestation(enclave_id, owner_mr_e, SPID, IAS_CRT, client_verify_ias, server_verify_ias)
    do_secret_mgmt(enclave_id, args)
    #do_order_mgmt(enclave_id)

    SGX.destroy_enclave(SGX.barbie_c, enclave_id)
예제 #2
0
def main(args):
    global policy_url, SK, proj_id, SGX
    plain_sk_len = 16
    ip = args['ip_address']
    policy_url = 'https://' + ip + ':443/v2/policy'
    proj_id = args['project_id']

    SGX = SGXInterface()
    SGX.init_env_variables()

    enclave_id = SGX.init_enclave(SGX.barbie_c)

    sk_value = None
    with open(proj_id + "_sk", "r") as f:
        sk_value = f.read()
    if (len(SGX.ffi.from_buffer(sk_value)) != plain_sk_len):
        sk_len = SGX.barbie_c.get_sealed_data_len(enclave_id, 0, plain_sk_len)
    else:
        sk_len = plain_sk_len
    SK = Secret(sk_value, sk_len)

    policy = args.get('policy', None)
    attribute = None
    if policy:
        attribute_file = args.get('attribute_file', None)
        if not attribute_file:
            print "Error : Please provide file path with attribute for corresponding policy"
            return
        attribute = get_attribute(attribute_file)
        attribute = get_sk_attribute(attribute, enclave_id)

    do_policy_management(policy, attribute, SGX.barbie_c, enclave_id)

    SGX.destroy_enclave(SGX.barbie_c, enclave_id)
예제 #3
0
def main(args):
    global attestation_url
    global secret_url
    global kek_url
    global SK

    ip = args['ip_address']
    attestation_url = 'https://' + ip + ':443/v2/attestation'
    secret_url = 'https://' + ip + ':443/v2/secrets'
    kek_url = 'https://' + ip + ':443/v2/kek'

    SPID = args['spid']
    if args.get('client_verify_ias', False) and args.get('server_verify_ias', False):
        client_verify_ias = True
        server_verify_ias = False
    else:
        client_verify_ias = args.get('client_verify_ias', False)
        server_verify_ias = args.get('server_verify_ias', False)

    IAS_CRT = args['ias_crt']
    global proj_id
    proj_id = args['project_id']

    global key_dir
    key_dir = args['key_dir']

    global SGX

    SGX = SGXInterface()
    SGX.init_env_variables()

    enclave_id = SGX.init_enclave(SGX.barbie_c)

    is_admin = args.get('admin', None)
    if is_admin:
        cookie = do_attestation(SPID=SPID, IAS_CRT=IAS_CRT, client_verify_ias=client_verify_ias, server_verify_ias=server_verify_ias)
        do_provision_kek(cookie)
    else:
        cookie = do_attestation(SPID=SPID, IAS_CRT=IAS_CRT, client_verify_ias=client_verify_ias, server_verify_ias=server_verify_ias)
        do_secret_mgmt()

    SGX.destroy_enclave(SGX.barbie_c, enclave_id)
예제 #4
0
def main(args):
    global attestation_url

    ip = args[0]
    attestation_url = 'https://' + ip + ':443/v2/attestation'

    global proj_id
    proj_id = args[1]

    global SGX

    SGX = SGXInterface()
    SGX.init_env_variables()

    enclave_id = SGX.init_enclave(SGX.barbie_c)

    cookie = do_attestation()
    dec_secret(args[2])

    SGX.destroy_enclave(SGX.barbie_c, enclave_id)
예제 #5
0
class SGXCryptoPlugin(c.CryptoPluginBase):
    """SGX based implementation of the crypto plugin."""
    def __init__(self, conf=CONF):
        LOG.info("Initializing SGX Crypto")
        self.master_kek = conf.sgx_crypto_plugin.kek
        dir_path = os.path.dirname(os.path.realpath(__file__))
        self.kek_file = os.path.join(dir_path, "masterkey")
        self.sealed_kek = None
        self.context = {}
        self.s_p_ctxt = {}
        self.c_p_net_ctxt = {}
        self.sgx = SGXInterface()
        self.sgx.init_env_variables()
        self.spid = self.sgx.get_spid()
        self.ias_crt = self.sgx.get_ias_crt()
        self.ias_enabled = self.sgx.get_ias_enable()
        self.enclave_id = self.sgx.init_enclave(self.sgx.barbie_s)
        self.client_verify_ias = False
        self.server_verify_ias = False
        self.sha2_server = None
        self.s_pub_key, self.s_priv_key = self.sgx.generate_key_pair()

    def _get_master_kek(self):
        if self.sealed_kek:
            return self.sealed_kek
        if os.path.exists(self.kek_file):
            sealed_len = self._get_sealed_data_len(_SIXTEEN_BYTE_KEY)
            with open(self.kek_file, 'r') as f:
                kek = f.read()
            self.sealed_kek = Secret(kek, sealed_len)
        return self.sealed_kek

    def _get_sealed_data_len(self, plain_len):
        return self.sgx.barbie_c.get_sealed_data_len(self.enclave_id, 0,
                                                     plain_len)

    def do_attestation(self, data, external_project_id, enc_keys, is_mutual,
                       policy_dict):
        if is_mutual:
            return self._do_mutual_attestation(data, external_project_id,
                                               enc_keys, policy_dict)
        else:
            return self._do_attestation(data, external_project_id, enc_keys)

    def _do_attestation(self, data, external_project_id, enc_keys):
        """This method is used for attestation of the server enclave.
        The same method is used for provisioning master kek on server.
        It performs 3 operations based on the msg types in the data
        1. If no msg in data : Generate msg0 & msg1 and return
        2. If msg2 in data : Generate msg3 & return
        3. If msg4 in data : Return session key encrypted with dh key
                             Also returns session key encrypted with kek to be 
                             stored in db, if kek is provisioned.
                             If kek is not provisioned, sealed sk is returned
                             and stored in db which would be used in subsequent
                             provision kek call.
        """
        LOG.info("Call for Remote Attestation")

        response = {}
        output = None
        if 'msg2' in data:
            if not self.ias_enabled:
                if data['server_verify_ias'] and not data['client_verify_ias']:
                    response[
                        'status'] = 'Server is not configured to do IAS verification'
                else:
                    msg3, resp_crt, resp_sign, resp_body = self.get_msg3(
                        data['msg2'], self.context[external_project_id],
                        self.ias_crt, data['client_verify_ias'],
                        data['server_verify_ias'])
                    if resp_crt and resp_sign and resp_body:
                        response['resp_crt'] = resp_crt
                        response['resp_sign'] = resp_sign
                        response['resp_body'] = resp_body
                    response['msg3'] = msg3
                    response['status'] = 'OK'
                return response, output
            else:
                try:
                    msg3, resp_crt, resp_sign, resp_body = self.get_msg3(
                        data['msg2'], self.context[external_project_id],
                        self.ias_crt, data['client_verify_ias'], True)
                    if resp_crt and resp_sign and resp_body:
                        response['resp_crt'] = resp_crt
                        response['resp_sign'] = resp_sign
                        response['resp_body'] = resp_body
                    response['msg3'] = msg3
                    response['status'] = 'OK'
                    return response, output
                except Exception as e:
                    response['status'] = str(e)
                    LOG.error(e, exc_info=True)
                    return response, output

        elif 'msg4' in data:
            project_id, project_id_len = self.get_project_id(
                data['msg4'], self.context[external_project_id])
            if self.sgx.convert_to_python_data(
                    project_id) == external_project_id:
                try:
                    sealed_mk, mk_sk = self._get_enc_keys(project_id, enc_keys)
                    sealed_mk, mk_sk, dh_sk = self.new_proc_ra(
                        data['msg4'], self.context[external_project_id],
                        sealed_mk, mk_sk)
                except Exception as e:
                    LOG.error(e, exc_info=True)
                    response[
                        'status'] = 'Error in Remote Attestaion due to invalid input parameters'
                    return response, output
                response['session_key'] = dh_sk
                response['status'] = 'OK'
                output = {}
                output['sk'] = mk_sk
                output['mk'] = sealed_mk.value
                sealed_kek = self._get_master_kek()
                if sealed_kek:
                    kek_mk = self.sgx.transport(self.sgx.barbie_s,
                                                self.enclave_id, sealed_kek,
                                                sealed_mk, project_id)
                    output['mk'] = kek_mk
                return response, output
            else:
                response[
                    'status'] = 'Error in Attestaion due to Project ID miss match'
                return response, output

        else:
            msg0 = self.get_msg0(self.spid)
            response['msg0'] = msg0
            if "pub_key" in data:
                ctxt, msg1 = self.get_msg1(data["pub_key"])
            else:
                ctxt, msg1 = self.get_msg1(None)
            response['msg1'] = msg1
            self.context[external_project_id] = ctxt
            return response, output

    def get_msg0(self, spid=None):
        ret, msg0 = self.sgx.gen_msg0(self.sgx.barbie_s, spid)
        return msg0

    def get_msg1(self, pub_key):
        return self.sgx.gen_msg1(self.sgx.barbie_s, self.enclave_id, pub_key)

    def get_msg2(self,
                 msg0,
                 msg1,
                 priv_key=None,
                 spid=None,
                 client_verify_ias=False):
        ret, p_net_ctxt = self.sgx.proc_msg0(self.sgx.barbie_s, msg0, spid,
                                             client_verify_ias)
        msg2 = self.sgx.proc_msg1_gen_msg2(self.sgx.barbie_s, msg1, p_net_ctxt,
                                           priv_key)
        return p_net_ctxt, msg2

    def get_msg3(self,
                 msg2,
                 p_ctxt,
                 ias_crt=None,
                 client_verify_ias=False,
                 server_verify_ias=True):
        return self.sgx.proc_msg2_gen_msg3(self.sgx.barbie_s, self.enclave_id,
                                           msg2, p_ctxt, ias_crt,
                                           client_verify_ias,
                                           server_verify_ias)

    def get_msg4(self,
                 msg3,
                 p_net_ctxt,
                 sealed_sk,
                 project_id=None,
                 ias_crt=None,
                 client_verify_ias=False,
                 sealed_key2=None):
        return self.sgx.proc_msg3_gen_msg4(self.sgx.barbie_s, self.enclave_id,
                                           msg3, p_net_ctxt, sealed_sk,
                                           project_id, ias_crt,
                                           client_verify_ias, sealed_key2)

    def proc_msg4(self, msg4, p_ctxt, sha2_client, sha2_server):
        status, sealed_secret1 = self.sgx.proc_msg4(self.sgx.barbie_s,
                                                    self.enclave_id, msg4,
                                                    p_ctxt, sha2_client,
                                                    sha2_server)
        if status == -1:
            return None
        return sealed_secret1

    def ma_proc_msg4(self,
                     s_msg4,
                     p_ctxt,
                     c_msg3,
                     p_net_ctxt,
                     s_mk,
                     mk_sk,
                     policy_dict,
                     ias_crt=None,
                     client_verify_ias=False,
                     project_id_len=0):
        return self.sgx.ma_proc_msg4(self.sgx.barbie_s, self.enclave_id,
                                     s_msg4, p_ctxt, c_msg3, p_net_ctxt, s_mk,
                                     mk_sk, policy_dict, ias_crt,
                                     client_verify_ias, project_id_len)

    def get_dh_key(self, msg4, ctxt):
        status, sealed_dh = self.sgx.get_dh_key(self.sgx.barbie_s,
                                                self.enclave_id, msg4, ctxt)
        return sealed_dh

    def new_proc_ra(self, msg4, ctxt, sealed_mk, mk_sk):
        return self.sgx.new_proc_ra(self.sgx.barbie_s, self.enclave_id, msg4,
                                    ctxt, sealed_mk, mk_sk)

    def get_project_id(self, msg4, p_ctxt):
        project_id, project_id_len = self.sgx.get_project_id(
            self.sgx.barbie_s, self.enclave_id, msg4, p_ctxt)
        return project_id, project_id_len

    def _do_mutual_attestation(self, data, external_project_id, enc_keys,
                               policy_dict):
        LOG.info("Call for Mutual Attestation")

        response = {}
        output = None

        if all(msg in data for msg in ('c_msg0', 'c_msg1', 's_msg2')):
            try:
                if not self.ias_enabled:
                    if data['server_verify_ias'] and not data[
                            'client_verify_ias']:
                        response[
                            'status'] = 'Server is not configured to do IAS verification'
                        return response, output
                    else:
                        c_p_net_ctxt, c_msg2 = self.get_msg2(
                            data['c_msg0'], data['c_msg1'], self.s_priv_key,
                            self.spid, data['client_verify_ias'])
                        s_msg3, resp_crt, resp_sign, resp_body = self.get_msg3(
                            data['s_msg2'], self.s_p_ctxt[external_project_id],
                            self.ias_crt, data['client_verify_ias'],
                            data['server_verify_ias'])
                        if resp_crt and resp_sign and resp_body:
                            response['s_resp_crt'] = resp_crt
                            response['s_resp_sign'] = resp_sign
                            response['s_resp_body'] = resp_body
                        response['s_msg3'] = s_msg3
                        response['c_msg2'] = c_msg2
                        self.sha2_server = self.sgx.get_report_sha256(
                            self.sgx.barbie_s, s_msg3)
                        self.client_verify_ias = data['client_verify_ias']
                        self.server_verify_ias = data['server_verify_ias']
                        self.c_p_net_ctxt[external_project_id] = c_p_net_ctxt
                        response['status'] = 'OK'
                        return response, output
                else:
                    c_p_net_ctxt, c_msg2 = self.get_msg2(
                        data['c_msg0'], data['c_msg1'], self.s_priv_key,
                        self.spid, data['client_verify_ias'])
                    s_msg3, resp_crt, resp_sign, resp_body = self.get_msg3(
                        data['s_msg2'], self.s_p_ctxt[external_project_id],
                        self.ias_crt, data['client_verify_ias'], True)
                    if resp_crt and resp_sign and resp_body:
                        response['s_resp_crt'] = resp_crt
                        response['s_resp_sign'] = resp_sign
                        response['s_resp_body'] = resp_body
                    response['s_msg3'] = s_msg3
                    response['c_msg2'] = c_msg2
                    self.client_verify_ias = data['client_verify_ias']
                    self.server_verify_ias = data['server_verify_ias']
                    self.c_p_net_ctxt[external_project_id] = c_p_net_ctxt
                    response['status'] = 'OK'
                return response, output
            except Exception as e:
                LOG.error(e, exc_info=True)
                response['status'] = str(e)
                return response, output

        elif all(msg in data for msg in ('c_msg3', 's_msg4')):

            if all(response in data
                   for response in ('c_resp_crt', 'c_resp_sign',
                                    'c_resp_body')):
                crt, cacrt = self.sgx.get_crt(data['c_resp_crt'])
                try:
                    self.sgx.verify_certificate(crt, cacrt)
                    self.sgx.verify_signature(crt, data['c_resp_sign'],
                                              data['c_resp_body'])
                except Exception as e:
                    LOG.error(e, exc_info=True)
                    response['status'] = str(e)
                    return response, output
            project_id, project_id_len = self.get_project_id(
                data['s_msg4'], self.s_p_ctxt[external_project_id])
            if self.sgx.convert_to_python_data(
                    project_id) == external_project_id:
                if not self.ias_enabled and self.client_verify_ias:
                    response[
                        'status'] = 'Server is not configured to do IAS verification'
                    return response, output
                else:
                    try:
                        sealed_mk, mk_sk = self._get_enc_keys(
                            project_id, enc_keys)
                        sealed_mk, mk_sk, c_msg4 = self.ma_proc_msg4(
                            data['s_msg4'], self.s_p_ctxt[external_project_id],
                            data['c_msg3'],
                            self.c_p_net_ctxt[external_project_id], sealed_mk,
                            mk_sk, policy_dict, self.ias_crt,
                            self.client_verify_ias, project_id_len)
                        response['c_msg4'] = c_msg4
                        response['status'] = 'OK'
                    except Exception as e:
                        LOG.error(e, exc_info=True)
                        response['status'] = str(e)
                        return response, output
                sealed_kek = self._get_master_kek()
                output = {}
                output['sk'] = mk_sk
                kek_mk = self.sgx.transport(self.sgx.barbie_s, self.enclave_id,
                                            sealed_kek, sealed_mk, project_id)
                output['mk'] = kek_mk

                return response, output
            else:
                response[
                    'status'] = 'Error in Mutual Attestaion due to Project ID miss match'
                return response, output

        else:
            s_msg0 = self.get_msg0(self.spid)
            response['s_msg0'] = s_msg0
            if "pub_key" in data:
                s_p_ctxt, s_msg1 = self.get_msg1(data["pub_key"])
            else:
                s_p_ctxt, s_msg1 = self.get_msg1(None)

            response['s_msg1'] = s_msg1
            self.s_p_ctxt[external_project_id] = s_p_ctxt
            response['s_pub_key'] = self.s_pub_key
            response['status'] = 'OK'
            return response, output

    def _get_enc_keys(self, project_id=None, enc_keys=None):
        sealed_mk = None
        mk_sk = None
        if enc_keys:
            LOG.info("Using already created session key")
            sealed_kek = self._get_master_kek()
            if sealed_kek:
                mk = self.sgx.provision_kek(self.sgx.barbie_s, self.enclave_id,
                                            sealed_kek, enc_keys['mk'],
                                            project_id)
            else:
                mk = enc_keys['mk']
            sealed_len = self._get_sealed_data_len(_SIXTEEN_BYTE_KEY)
            sealed_mk = Secret(mk, sealed_len)
            mk_sk = enc_keys['sk']
        return sealed_mk, mk_sk

    def compare_buffer(self, buffer1, buffer2, length):
        return self.sgx.compare_secret(self.sgx.barbie_s, buffer1, buffer2,
                                       length)

    def do_provision_kek(self, data, external_project_id, enc_keys):
        LOG.info("In KEK Provisioning")
        if self._get_master_kek() is None:
            sealed_mk, mk_sk = self._get_enc_keys(external_project_id,
                                                  enc_keys)
            self.sealed_kek = self.sgx.get_kek(self.sgx.barbie_s,
                                               self.enclave_id, sealed_mk,
                                               mk_sk, data['kek'],
                                               external_project_id,
                                               len(external_project_id))
            kek_mk = self.sgx.transport(self.sgx.barbie_s, self.enclave_id,
                                        self.sealed_kek, sealed_mk,
                                        external_project_id)
            with open(self.kek_file, 'w') as f:
                f.write(self.sealed_kek.value)
            return {"status": "OK"}, {'sk': enc_keys['sk'], 'mk': kek_mk}
        else:
            return {"status": "Key Encryption Key already provisioned"}, None

    def encrypt(self, encrypt_dto, kek_meta_dto, project_id):
        project_id = unicodedata.normalize('NFKD', project_id).encode(
            'ascii', 'ignore')
        unencrypted = encrypt_dto.unencrypted
        enc_keys = encrypt_dto.enc_keys
        if not isinstance(unencrypted, six.binary_type):
            raise ValueError(
                u._('Unencrypted data must be a byte type, but was '
                    '{unencrypted_type}').format(
                        unencrypted_type=type(unencrypted)))
        s_mk, mk_sk = self._get_enc_keys(project_id, enc_keys)
        mk_secret = self.sgx.secret_encrypt(self.sgx.barbie_s, self.enclave_id,
                                            s_mk, mk_sk, unencrypted,
                                            project_id, len(project_id))

        return c.ResponseDTO(mk_secret, None)

    def decrypt(self, encrypted_dto, kek_meta_dto, kek_meta_extended,
                project_id):
        project_id = unicodedata.normalize('NFKD', project_id).encode(
            'ascii', 'ignore')
        encrypted = encrypted_dto.encrypted
        enc_keys = encrypted_dto.enc_keys
        s_mk, mk_sk = self._get_enc_keys(project_id, enc_keys)
        return self.sgx.secret_decrypt(self.sgx.barbie_s, self.enclave_id,
                                       s_mk, mk_sk, encrypted, project_id,
                                       len(project_id))

    def mk_decrypt(self, enc_keys, mk_data, project_id):
        sealed_mk, mk_sk = self._get_enc_keys(project_id, enc_keys)
        sk_data = self.sgx.get_sk_data(self.sgx.barbie_s, self.enclave_id,
                                       mk_sk, sealed_mk, mk_data, project_id,
                                       len(project_id))
        return sk_data

    def mk_encrypt(self, enc_keys, sk_data, project_id, mk_mr_list=None):
        sealed_mk, mk_sk = self._get_enc_keys(project_id, enc_keys)
        mk_data = self.sgx.get_mk_mr_list(self.sgx.barbie_s, self.enclave_id,
                                          mk_sk,
                                          sealed_mk, sk_data, project_id,
                                          len(project_id), mk_mr_list)
        return mk_data

    def bind_kek_metadata(self, kek_meta_dto):
        kek_meta_dto.algorithm = 'aes'
        kek_meta_dto.bit_length = 128
        kek_meta_dto.mode = 'gcm'
        if not kek_meta_dto.plugin_meta:
            # the kek is stored encrypted in the plugin_meta field
            encryptor = fernet.Fernet(self.master_kek)
            key = fernet.Fernet.generate_key()
            kek_meta_dto.plugin_meta = encryptor.encrypt(key)
        return kek_meta_dto

    def generate_symmetric(self, generate_dto, kek_meta_dto, project_id):
        byte_length = int(generate_dto.bit_length) // 8
        sealed_secret = self.sgx.generate_key(self.sgx.barbie_s,
                                              self.enclave_id, byte_length)
        sealed_kek = self._get_master_kek()
        if not sealed_kek:
            raise Exception(
                "Master key is not provisioned. Please contact administrator.")
        proj_id = unicodedata.normalize('NFKD',
                                        project_id).encode('ascii', 'ignore')
        kek_secret = self.sgx.transport(self.sgx.barbie_s, self.enclave_id,
                                        sealed_kek, sealed_secret, proj_id)
        return c.ResponseDTO(kek_secret, None)

    def generate_asymmetric(self, generate_dto, kek_meta_dto, project_id):
        """Generate asymmetric keys based on below rules:

        - RSA, with passphrase (supported)
        - RSA, without passphrase (supported)
        - DSA, without passphrase (supported)
        - DSA, with passphrase (not supported)

        Note: PyCrypto is not capable of serializing DSA
        keys and DER formated keys. Such keys will be
        serialized to Base64 PEM to store in DB.

        TODO (atiwari/reaperhulk): PyCrypto is not capable to serialize
        DSA keys and DER formated keys, later we need to pick better
        crypto lib.
        """
        if (generate_dto.algorithm is None
                or generate_dto.algorithm.lower() == 'rsa'):
            private_key = RSA.generate(generate_dto.bit_length, None, None,
                                       65537)
        elif generate_dto.algorithm.lower() == 'dsa':
            private_key = DSA.generate(generate_dto.bit_length, None, None)
        else:
            raise c.CryptoPrivateKeyFailureException()

        public_key = private_key.publickey()

        # Note (atiwari): key wrapping format PEM only supported
        if generate_dto.algorithm.lower() == 'rsa':
            public_key, private_key = self._wrap_key(public_key, private_key,
                                                     generate_dto.passphrase)
        if generate_dto.algorithm.lower() == 'dsa':
            if generate_dto.passphrase:
                raise ValueError(u._('Passphrase not supported for DSA key'))
            public_key, private_key = self._serialize_dsa_key(
                public_key, private_key)
        private_dto = self.encrypt(c.EncryptDTO(private_key), kek_meta_dto,
                                   project_id)

        public_dto = self.encrypt(c.EncryptDTO(public_key), kek_meta_dto,
                                  project_id)

        passphrase_dto = None
        if generate_dto.passphrase:
            if isinstance(generate_dto.passphrase, six.text_type):
                generate_dto.passphrase = generate_dto.passphrase.encode(
                    'utf-8')

            passphrase_dto = self.encrypt(
                c.EncryptDTO(generate_dto.passphrase), kek_meta_dto,
                project_id)

        return private_dto, public_dto, passphrase_dto

    def supports(self, type_enum, algorithm=None, bit_length=None, mode=None):
        if type_enum == c.PluginSupportTypes.ENCRYPT_DECRYPT:
            return True

        if type_enum == c.PluginSupportTypes.SYMMETRIC_KEY_GENERATION:
            return self._is_algorithm_supported(algorithm, bit_length)
        elif type_enum == c.PluginSupportTypes.ASYMMETRIC_KEY_GENERATION:
            return self._is_algorithm_supported(algorithm, bit_length)
        else:
            return False

    def _wrap_key(self, public_key, private_key, passphrase):
        pkcs = 8
        key_wrap_format = 'PEM'

        private_key = private_key.exportKey(key_wrap_format, passphrase, pkcs)
        public_key = public_key.exportKey(key_wrap_format)

        return public_key, private_key

    def _serialize_dsa_key(self, public_key, private_key):

        pub_seq = asn1.DerSequence()
        pub_seq[:] = [
            0, public_key.p, public_key.q, public_key.g, public_key.y
        ]
        public_key = pub_seq.encode()

        prv_seq = asn1.DerSequence()
        prv_seq[:] = [
            0, private_key.p, private_key.q, private_key.g, private_key.y,
            private_key.x
        ]
        private_key = prv_seq.encode()

        return public_key, private_key

    def _is_algorithm_supported(self, algorithm=None, bit_length=None):
        """check if algorithm and bit_length combination is supported."""
        if algorithm is None or bit_length is None:
            return False

        if (algorithm.lower() in c.PluginSupportTypes.SYMMETRIC_ALGORITHMS
                and bit_length in c.PluginSupportTypes.SYMMETRIC_KEY_LENGTHS):
            return True
        elif (algorithm.lower() in c.PluginSupportTypes.ASYMMETRIC_ALGORITHMS
              and bit_length in c.PluginSupportTypes.ASYMMETRIC_KEY_LENGTHS):
            return True
        else:
            return False