Beispiel #1
0
/*
 * External function used to verify EPID Blob and check whether QE has
 * been updated.
 *
 * @param p_blob[in, out] Pointer to EPID Blob.
 * @param blob_size[in] The size of EPID Blob, in bytes.
 * @param p_is_resealed[out] Whether the EPID Blob is resealed within this function call.
 * @param p_cpusvn[out] Return the raw CPUSVN.
 * @return uint32_t AE_SUCCESS or other error cases.
 */
uint32_t verify_blob(
    uint8_t *p_blob,
    uint32_t blob_size,
    uint8_t *p_is_resealed,
    sgx_cpu_svn_t *p_cpusvn)
{
    se_plaintext_epid_data_sdk_t plain_text;

    /* Actually, some cases here will be checked with code generated by
       edger8r. Here we just want to defend in depth. */
    if(NULL == p_blob || NULL == p_is_resealed || NULL == p_cpusvn)
        return QE_PARAMETER_ERROR;

    if(SGX_TRUSTED_EPID_BLOB_SIZE_SDK != blob_size)
        return QE_PARAMETER_ERROR;

	//
	// if we mispredict here and blob_size is too
	// small, we might overflow
	//
	sgx_lfence();

    if(!sgx_is_within_enclave(p_blob, blob_size))
        return QE_PARAMETER_ERROR;

    return random_stack_advance(verify_blob_internal, p_blob, blob_size,
                                p_is_resealed, FALSE, plain_text, (MemberCtx**) NULL, p_cpusvn);
}
Beispiel #2
0
/*
 * External function used to get quote. Prefix "emp_" means it is a pointer
 * points memory outside enclave.
 *
 * @param p_blob[in, out] Pointer to the EPID Blob.
 * @param blob_size[in] The size of EPID Blob, in bytes.
 * @param p_enclave_report[in] The application enclave's report.
 * @param quote_type[in] The type of quote, random based or name based.
 * @param p_spid[in] Pointer to SPID.
 * @param p_nonce[in] Pointer to nonce.
 * @param emp_sig_rl[in] Pointer to SIG-RL.
 * @param sig_rl_size[in] The size of SIG-RL, in bytes.
 * @param p_qe_report[out] Pointer to QE report, which reportdata is
 *                         sha256(nonce || quote)
 * @param emp_quote[out] Pointer to the output buffer for quote.
 * @param quote_size[in] The size of emp_quote, in bytes.
 * @param pce_isvsvn[in] The ISVSVN of PCE.
 * @return ae_error_t AE_SUCCESS for success, otherwise for errors.
 */
uint32_t get_quote(
    uint8_t *p_blob,
    uint32_t blob_size,
    const sgx_report_t *p_enclave_report,
    sgx_quote_sign_type_t quote_type,
    const sgx_spid_t *p_spid,
    const sgx_quote_nonce_t *p_nonce,
    const uint8_t *emp_sig_rl,
    uint32_t sig_rl_size,
    sgx_report_t *p_qe_report,
    uint8_t *emp_quote,
    uint32_t quote_size,
    sgx_isv_svn_t pce_isvsvn)
{
    ae_error_t ret = AE_SUCCESS;
    EpidStatus epid_ret = kEpidNoErr;
    MemberCtx *p_epid_context = NULL;
    sgx_quote_t quote_body;
    uint8_t is_resealed = 0;
    sgx_basename_t basename = {{0}};
    uint64_t sign_size = 0;
    sgx_status_t se_ret = SGX_SUCCESS;
    sgx_report_t qe_report;
    uint64_t required_buffer_size = 0;
    se_sig_rl_t sig_rl_header;
    se_plaintext_epid_data_sdk_t plaintext;
    sgx_ec256_signature_t ec_signature;
    sgx_cpu_svn_t cpusvn;

    memset(&quote_body, 0, sizeof(quote_body));
    memset(&sig_rl_header, 0, sizeof(sig_rl_header));
    memset(&plaintext, 0, sizeof(plaintext));
    memset(&ec_signature, 0, sizeof(ec_signature));
    memset(&cpusvn, 0, sizeof(cpusvn));


    /* Actually, some cases here will be checked with code generated by
       edger8r. Here we just want to defend in depth. */
    if((NULL == p_blob)
       || (NULL == p_enclave_report)
       || (NULL == p_spid)
       || (NULL == emp_quote)
       || (!quote_size)
       || ((NULL != emp_sig_rl) && (sig_rl_size < sizeof(se_sig_rl_t)
                                                  + 2 * SE_ECDSA_SIGN_SIZE))

		//
		// this size check could mispredict and cause us to
		// overflow, but we have an lfence below
		// that's safe to use for this case
		//

       || ((NULL == emp_sig_rl) && (sig_rl_size != 0)))
        return QE_PARAMETER_ERROR;
    if(SGX_TRUSTED_EPID_BLOB_SIZE_SDK != blob_size)
        return QE_PARAMETER_ERROR;

	//
	// this could mispredict and cause us to
	// overflow, but we have an lfence below
	// that's safe to use for this case
	//

    if(SGX_LINKABLE_SIGNATURE != quote_type
       && SGX_UNLINKABLE_SIGNATURE != quote_type)
        return QE_PARAMETER_ERROR;
    if(!p_nonce && p_qe_report)
        return QE_PARAMETER_ERROR;
    if(p_nonce && !p_qe_report)
        return QE_PARAMETER_ERROR;

    /* To reduce the memory footprint of QE, we should leave sig_rl and
       quote buffer outside enclave. */
    if(!sgx_is_outside_enclave(emp_sig_rl, sig_rl_size))
        return QE_PARAMETER_ERROR;

    //
    // for user_check SigRL input
    // based on quote_size input parameter
    //
    sgx_lfence();

    if(!sgx_is_outside_enclave(emp_quote, quote_size))
        return QE_PARAMETER_ERROR;

    /* Check whether p_blob is copied into EPC. If we want to reduce the
       memory usage, maybe we can leave the p_blob outside EPC. */
    if(!sgx_is_within_enclave(p_blob, blob_size))
        return QE_PARAMETER_ERROR;
    if(!sgx_is_within_enclave(p_enclave_report, sizeof(*p_enclave_report)))
        return QE_PARAMETER_ERROR;
    if(!sgx_is_within_enclave(p_spid, sizeof(*p_spid)))
        return QE_PARAMETER_ERROR;
    /* If the code reach here, if p_nonce is NULL, then p_qe_report will be
       NULL also. So we only check p_nonce here.*/
    if(p_nonce)
    {
        /* Actually Edger8r will alloc the buffer within EPC, this is just kind
           of defense in depth. */
        if(!sgx_is_within_enclave(p_nonce, sizeof(*p_nonce)))
            return QE_PARAMETER_ERROR;
        if(!sgx_is_within_enclave(p_qe_report, sizeof(*p_qe_report)))
            return QE_PARAMETER_ERROR;
    }

    /* Verify the input report. */
    if(SGX_SUCCESS != sgx_verify_report(p_enclave_report))
        return QE_PARAMETER_ERROR;

    /* Verify EPID p_blob and create the context */
    ret = random_stack_advance(verify_blob_internal, p_blob,
        blob_size,
        &is_resealed,
        TRUE,
        plaintext,
        &p_epid_context,
        &cpusvn);
    if(AE_SUCCESS != ret)
        goto CLEANUP;

    /* If SIG-RL is provided, we should check its size. */
    if(emp_sig_rl)
    {
        uint64_t temp_size = 0;
        uint64_t n2 = 0;

        memcpy(&sig_rl_header, emp_sig_rl, sizeof(sig_rl_header));
        if(sig_rl_header.protocol_version != SE_EPID_SIG_RL_VERSION)
        {
            ret = QE_PARAMETER_ERROR;
            goto CLEANUP;
        }

        if(sig_rl_header.epid_identifier != SE_EPID_SIG_RL_ID)
        {
            ret = QE_PARAMETER_ERROR;
            goto CLEANUP;
        }

        if(memcmp(&sig_rl_header.sig_rl.gid, &plaintext.epid_group_cert.gid,
                   sizeof(sig_rl_header.sig_rl.gid)))
        {
            ret = QE_PARAMETER_ERROR;
            goto CLEANUP;
        }
        temp_size = se_get_sig_rl_size(&sig_rl_header);
        if(temp_size != sig_rl_size)
        {
            ret = QE_PARAMETER_ERROR;
            goto CLEANUP;
        }

        se_static_assert(sizeof(ec_signature.x) == SE_ECDSA_SIGN_SIZE);
        se_static_assert(sizeof(ec_signature.y) == SE_ECDSA_SIGN_SIZE);
        memcpy(ec_signature.x,
               emp_sig_rl + sig_rl_size - (SE_ECDSA_SIGN_SIZE * 2),
               sizeof(ec_signature.x));
        SWAP_ENDIAN_32B(ec_signature.x);
        memcpy(ec_signature.y,
               emp_sig_rl + sig_rl_size - (SE_ECDSA_SIGN_SIZE * 1),
               sizeof(ec_signature.y));
        SWAP_ENDIAN_32B(ec_signature.y);

        n2 = SWAP_4BYTES(sig_rl_header.sig_rl.n2);
        temp_size = sizeof(EpidSignature) - sizeof(NrProof)
                    + n2 * sizeof(NrProof);
        if(temp_size > UINT32_MAX)
        {
            ret = QE_PARAMETER_ERROR;
            goto CLEANUP;
        }
        sign_size = temp_size;
    }
    else
    {
        sign_size = sizeof(BasicSignature)
                    + sizeof(uint32_t) // rl_ver
                    + sizeof(uint32_t); // rl_num
    }

    /* Verify sizeof basename is large enough and it should always be true*/
    se_static_assert(sizeof(basename) > sizeof(*p_spid));
    /* Because basename has already been zeroed,
       so we don't need to concatenating with 0s.*/
    memcpy(&basename, p_spid, sizeof(*p_spid));
    if(SGX_UNLINKABLE_SIGNATURE == quote_type)
    {
        uint8_t *p = (uint8_t *)&basename + sizeof(*p_spid);
        se_ret = sgx_read_rand(p, sizeof(basename) - sizeof(*p_spid));
        if(SGX_SUCCESS != se_ret)
        {
            ret = QE_UNEXPECTED_ERROR;
            goto CLEANUP;
        }
    }

    epid_ret = EpidRegisterBasename(p_epid_context, (uint8_t *)&basename,
        sizeof(basename));
    if(kEpidNoErr != epid_ret)
    {
        ret = QE_UNEXPECTED_ERROR;
        goto CLEANUP;
    }

    required_buffer_size = SE_QUOTE_LENGTH_WITHOUT_SIG + sign_size;

    /* We should make sure the buffer size is big enough. */
    if(quote_size < required_buffer_size)
    {
        ret = QE_PARAMETER_ERROR;
        goto CLEANUP;
    }

    //
    // for user_check SigRL input
    // based on n2 field in SigRL
    //
    sgx_lfence();

    /* Copy the data in the report into quote body. */
    memset(emp_quote, 0, quote_size);
    quote_body.version = QE_QUOTE_VERSION;
    quote_body.sign_type = (uint16_t)quote_type;
    quote_body.pce_svn = pce_isvsvn; // Both are little endian
    quote_body.xeid = plaintext.xeid; // Both are little endian
    se_static_assert(sizeof(plaintext.epid_group_cert.gid) == sizeof(OctStr32));
    se_static_assert(sizeof(quote_body.epid_group_id) == sizeof(uint32_t));
    ((uint8_t *)(&quote_body.epid_group_id))[0] = plaintext.epid_group_cert.gid.data[3];
    ((uint8_t *)(&quote_body.epid_group_id))[1] = plaintext.epid_group_cert.gid.data[2];
    ((uint8_t *)(&quote_body.epid_group_id))[2] = plaintext.epid_group_cert.gid.data[1];
    ((uint8_t *)(&quote_body.epid_group_id))[3] = plaintext.epid_group_cert.gid.data[0];
    memcpy(&quote_body.basename, &basename, sizeof(quote_body.basename));

    // Get the QE's report.
    se_ret = sgx_create_report(NULL, NULL, &qe_report);
    if(SGX_SUCCESS != se_ret)
    {
        ret = QE_PARAMETER_ERROR;
        goto CLEANUP;
    }

    // Copy QE's security version in to Quote body.
    quote_body.qe_svn = qe_report.body.isv_svn;

    // Copy the incoming report into Quote body.
    memcpy(&quote_body.report_body, &(p_enclave_report->body),
           sizeof(quote_body.report_body));
    /* Because required_buffer_size is larger than signature_len, so if we
       get here, then no integer overflow will ocur. */
    quote_body.signature_len = (uint32_t)(sizeof(se_wrap_key_t)
                               + QUOTE_IV_SIZE
                               + sizeof(uint32_t)
                               + sign_size
                               + sizeof(sgx_mac_t));

    /* Make the signature. */
    ret = qe_epid_sign(p_epid_context,
                       plaintext,
                       &basename,
                       emp_sig_rl ? ((const se_sig_rl_t *)emp_sig_rl)->sig_rl.bk
                                    : NULL,
                       &sig_rl_header,
                       &ec_signature,
                       p_enclave_report,
                       p_nonce,
                       p_qe_report,
                       emp_quote,
                       &quote_body,
                       (uint32_t)sign_size);
    if(AE_SUCCESS != ret)
    {
        // Only need to clean the buffer after the fixed length part.
        memset_s(emp_quote + sizeof(sgx_quote_t), quote_size - sizeof(sgx_quote_t),
                 0, quote_size - sizeof(sgx_quote_t));
        goto CLEANUP;
    }

    memcpy(emp_quote, &quote_body, sizeof(sgx_quote_t));

CLEANUP:
    if(p_epid_context)
		epid_member_delete(&p_epid_context);
    return ret;
}
Beispiel #3
0
//Function to create data for ProvMsg3 generation 
// The sigrl of ProvMsg2 will processed in this function in piece-meal method
//@msg2_blob_input: structure to hold decoded data of ProvMsg2
//@performance_rekey_used[in]: 1 if performance rekey used or 0 if not
//@msg3_parm: structure to hold most information to generate ProvMsg3
//@msg3_output: structure to hold output data to create ProvMsg3
//@emp_epid_sig: output buffer to external memory for variable length EpidSignature
//@epid_sig_buffer_size: size in bytes of buffer emp_epid_sig
//@return PVEC_SUCCESS on success and error code if failed
pve_status_t gen_prov_msg3_data(const proc_prov_msg2_blob_input_t *msg2_blob_input,
                                prov_msg3_parm_t& msg3_parm,
                                uint8_t performance_rekey_used,
                                gen_prov_msg3_output_t *msg3_output,
                                external_memory_byte_t *emp_epid_sig, 
                                uint32_t epid_sig_buffer_size)
{
    pve_status_t ret = PVEC_SUCCESS;
    sgx_status_t sgx_status = SGX_ERROR_UNEXPECTED;
    uint8_t temp_buf[JOIN_PROOF_TLV_TOTAL_SIZE];
    uint8_t *data_to_encrypt = NULL;
    uint8_t  size_to_encrypt = 0;
    uint8_t  pwk2_tlv_buffer[PWK2_TLV_TOTAL_SIZE];
    sgx_key_128bit_t *pwk2=reinterpret_cast<sgx_key_128bit_t *>(pwk2_tlv_buffer+PWK2_TLV_HEADER_SIZE);
    uint8_t report_data_payload[MAC_SIZE + HARD_CODED_JOIN_PROOF_WITH_ESCROW_TLV_SIZE + NONCE_2_SIZE + PEK_MOD_SIZE];
    uint8_t* pdata = &report_data_payload[0];
    sgx_report_data_t report_data = { 0 };
    uint8_t aad[sizeof(GroupId)+sizeof(device_id_t)+CHALLENGE_NONCE_SIZE];
    void *pub_key = NULL;
    const signed_pek_t& pek = msg2_blob_input->pek;
    uint32_t le_e;
    int i;
    size_t output_len = 0;
    uint8_t le_n[sizeof(pek.n)];
    static_assert(sizeof(pek.n)==384, "pek.n should be 384 bytes");
    device_id_t *device_id_in_aad= (device_id_t *)(aad+sizeof(GroupId));
    join_proof_with_escrow_t* join_proof_with_escrow=reinterpret_cast<join_proof_with_escrow_t *>(temp_buf+JOIN_PROOF_TLV_HEADER_SIZE);
    se_static_assert(sizeof(join_proof_with_escrow_t)+JOIN_PROOF_TLV_HEADER_SIZE==JOIN_PROOF_TLV_TOTAL_SIZE); /*unmatched hardcoded size*/
    se_static_assert(sizeof(sgx_key_128bit_t)==PWK2_TLV_TOTAL_SIZE-PWK2_TLV_HEADER_SIZE); /*unmatched PWK2 size*/
    memset(temp_buf, 0 ,sizeof(temp_buf));
    memset(aad, 0, sizeof(aad));
    memset(pwk2, 0, sizeof(sgx_key_128bit_t));
    memcpy(pwk2_tlv_buffer, PWK2_TLV_HEADER, PWK2_TLV_HEADER_SIZE);
    msg3_output->is_join_proof_generated=false;
    msg3_output->is_epid_sig_generated=false;

    if ((msg2_blob_input->pce_target_info.attributes.flags & SGX_FLAGS_PROVISION_KEY) != SGX_FLAGS_PROVISION_KEY ||
        (msg2_blob_input->pce_target_info.attributes.flags & SGX_FLAGS_DEBUG) != 0){
        //PCE must have access to provisioning key
        //Can't be debug PCE
        ret = PVEC_PARAMETER_ERROR;
        goto ret_point;
    }

    if(!performance_rekey_used){
        //the temp_buf used for join_proof_with_escrow tlv
        memcpy(temp_buf, JOIN_PROOF_TLV_HEADER, JOIN_PROOF_TLV_HEADER_SIZE);//first copy in tlv header
        ret = random_stack_advance(gen_msg3_join_proof_escrow_data, msg2_blob_input, *join_proof_with_escrow);//generate the tlv payload
        if( PVEC_SUCCESS != ret )
            goto ret_point;
        msg3_output->is_join_proof_generated = true;
        data_to_encrypt = temp_buf;
        size_to_encrypt = JOIN_PROOF_TLV_TOTAL_SIZE;
    }
    //now encrypt field1
    ret = se_read_rand_error_to_pve_error(sgx_read_rand(msg3_output->field1_iv, IV_SIZE));//randomly generate IV
    if( PVEC_SUCCESS != ret)
        goto ret_point;
    memcpy(aad, &msg2_blob_input->group_cert.key.gid,sizeof(GroupId));//start to prepare AAD
    memcpy(&device_id_in_aad->fmsp, &msg2_blob_input->equiv_pi.fmsp, sizeof(fmsp_t));
    memcpy(&device_id_in_aad->psvn.cpu_svn, &msg2_blob_input->equiv_pi.cpu_svn, sizeof(sgx_cpu_svn_t));
    memcpy(&device_id_in_aad->psvn.isv_svn, &msg2_blob_input->equiv_pi.pve_svn, sizeof(sgx_isv_svn_t));
    memset(&device_id_in_aad->ppid, 0, sizeof(device_id_in_aad->ppid));
    ret = pve_rng_generate(NONCE_2_SIZE*8, msg3_output->n2);
    if(PVEC_SUCCESS !=ret){
        goto ret_point;
    }
    ret = random_stack_advance(get_pwk2, &device_id_in_aad->psvn, msg3_output->n2, pwk2);
    if( PVEC_SUCCESS != ret )
        goto ret_point;

    memcpy(aad+sizeof(GroupId)+sizeof(device_id_t), msg2_blob_input->challenge_nonce, CHALLENGE_NONCE_SIZE);
    se_static_assert(sizeof(sgx_aes_gcm_128bit_key_t)==SK_SIZE); /*sizeof sgx_aes_gcm_128bit_key_t should be same as TCB size*/
    se_static_assert(sizeof(sgx_aes_gcm_128bit_tag_t)==MAC_SIZE); /*sizeof sgx_aes_gcm_128bit_tag_t should be same as MAC_SIZE*/
    sgx_status = sgx_rijndael128GCM_encrypt(reinterpret_cast<const sgx_aes_gcm_128bit_key_t *>(pwk2),
        data_to_encrypt, size_to_encrypt, msg3_output->field1_data,
        msg3_output->field1_iv, IV_SIZE, aad, static_cast<uint32_t>(sizeof(GroupId)+sizeof(device_id_t)+CHALLENGE_NONCE_SIZE),
        reinterpret_cast<sgx_aes_gcm_128bit_tag_t *>(msg3_output->field1_mac));//encrypt field1
    if(SGX_SUCCESS != sgx_status){
        ret = sgx_error_to_pve_error(sgx_status);
        goto ret_point;
    }
    if( msg2_blob_input->is_previous_pi_provided ){
        //preparing the encryption state of ProvMsg3 and encrypt inplace of msg3_inside enclave (field1_0 and field1_1)
        //The function will randomly set the iv value too
        ret = proc_msg3_state_init(&msg3_parm, pwk2);
        if( PVEC_SUCCESS!=ret )
            goto ret_point; 
        //Now start piece-meal generation of EPIDsign 
        ret = gen_msg3_signature(msg2_blob_input, &msg3_parm, emp_epid_sig, epid_sig_buffer_size);
        if( PVEC_SUCCESS!=ret )
            goto ret_point;
        msg3_output->is_epid_sig_generated = true;
        msg3_output->epid_sig_output_size = epid_sig_buffer_size;
        memcpy(msg3_output->epid_sig_iv, msg3_parm.iv, IV_SIZE);
        //generate MAC in EPC
        ret = sgx_error_to_pve_error(sgx_aes_gcm128_enc_get_mac(msg3_output->epid_sig_mac, (sgx_aes_state_handle_t*)msg3_parm.p_msg3_state));
        if (PVEC_SUCCESS != ret)
            goto ret_point;
    }

    le_e = lv_ntohl(pek.e);
    se_static_assert(sizeof(pek.n)==sizeof(le_n));  /*unmatched size of pek.n*/
    //endian swap
    for(i=0;i<(int)(sizeof(pek.n)/sizeof(pek.n[0]));i++){
        le_n[i]=pek.n[sizeof(pek.n)/sizeof(pek.n[0])-i-1];
    }

    sgx_status = sgx_create_rsa_pub_key(sizeof(pek.n), sizeof(pek.e),
        reinterpret_cast<const unsigned char *>(le_n), reinterpret_cast<const unsigned char *>(&le_e), &pub_key);
    if (SGX_SUCCESS != sgx_status) {
        ret = sgx_error_to_pve_error(sgx_status);
        goto ret_point;
    }

    sgx_status = sgx_rsa_pub_encrypt_sha256(pub_key, NULL, &output_len, reinterpret_cast<const unsigned char*>(pwk2_tlv_buffer),
        PWK2_TLV_TOTAL_SIZE);
    if (SGX_SUCCESS != sgx_status) {
        ret = sgx_error_to_pve_error(sgx_status);
        goto ret_point;
    }
    sgx_status = sgx_rsa_pub_encrypt_sha256(pub_key, msg3_output->encrypted_pwk2, &output_len, reinterpret_cast<const unsigned char*>(pwk2_tlv_buffer),
        PWK2_TLV_TOTAL_SIZE);
    if (SGX_SUCCESS != sgx_status) {
        ret = sgx_error_to_pve_error(sgx_status);
        goto ret_point;
    }

    // X = (NT)MAC_PWK2(... (NT)E_PWK2((T)(JoinP, f)) ...) | (NT)E_PWK2((T)(JoinP, f)) | (NT)PWK2N | (NT)E_PEK((T)PWK2)
    // REPORT.ReportData == SHA256[X] 
    memcpy(pdata, msg3_output->field1_mac, MAC_SIZE);
    pdata += MAC_SIZE;
    if (!performance_rekey_used){
        memcpy(pdata, msg3_output->field1_data, HARD_CODED_JOIN_PROOF_WITH_ESCROW_TLV_SIZE);
        pdata += HARD_CODED_JOIN_PROOF_WITH_ESCROW_TLV_SIZE;
    }
    memcpy(pdata, msg3_output->n2, NONCE_2_SIZE);
    pdata += NONCE_2_SIZE;
    memcpy(pdata, msg3_output->encrypted_pwk2, PEK_MOD_SIZE);
    pdata += PEK_MOD_SIZE;
    se_static_assert(sizeof(report_data) >= sizeof(sgx_sha256_hash_t)); /*report data is no large enough*/
    sgx_status = sgx_sha256_msg(report_data_payload, (uint32_t)(pdata - &report_data_payload[0]), reinterpret_cast<sgx_sha256_hash_t *>(&report_data));
    if (SGX_SUCCESS != sgx_status){
        ret = sgx_error_to_pve_error(sgx_status);
        goto ret_point;
    }
    sgx_status = sgx_create_report(&msg2_blob_input->pce_target_info, &report_data, &msg3_output->pwk2_report);
    if (SGX_SUCCESS != sgx_status){
        ret = sgx_error_to_pve_error(sgx_status);
        goto ret_point;
    }

ret_point:
    (void)memset_s(aad, sizeof(aad), 0, sizeof(aad));
    (void)memset_s(temp_buf, sizeof(temp_buf), 0, sizeof(temp_buf));
    (void)memset_s(pwk2_tlv_buffer, sizeof(pwk2_tlv_buffer),0,sizeof(pwk2_tlv_buffer));
    if(pub_key){
        sgx_free_rsa_key(pub_key, SGX_RSA_PUBLIC_KEY, sizeof(pek.n), sizeof(pek.e));
    }

    return ret;
}