/*****************************************************************************
 * @ingroup IKE_RSA
 *
 * @description
 *      This function frees all the dynamically allocated memory used in the
 * ikeRsaPerform
 * Each pointer is checked to see if its null and if not it is free'd,
 * The underlying free function ensures that when freeing the pointer is reset
 * to NULL
 ******************************************************************************/
static void ikeRsaMemFree(asym_test_params_t* setup,
        ike_rsa_client_data_t* alice,
        ike_rsa_client_data_t* bob,
        CpaCyRsaPrivateKey    *pPrivateKey[],
        CpaCyRsaPublicKey     *pPublicKey[]
)
{
    rsaFreeDataMemory(setup, alice->ppDecryptOpData, alice->ppSignatures,
            alice->ppEncryptOpData, alice->ppPVverifier);
    rsaFreeKeyMemory(setup, pPrivateKey, pPublicKey);
    rsaFreeDataMemory(setup, bob->ppDecryptOpData, bob->ppSignatures,
            bob->ppEncryptOpData, bob->ppPVverifier);
    rsaFreeDataMemory(setup, NULL, NULL,
            bob->ppEncryptOpData2, bob->ppPVverifier2);
    rsaFreeDataMemory(setup, NULL, NULL,
            alice->ppEncryptOpData2, alice->ppPVverifier2);
    /*free the signature pointer arrays because in RSA code this is allocated
     * as a local variable*/
    ikeRsaMemFreeRsaData(alice);
    ikeRsaMemFreeRsaData(bob);
    dhMemFreePh1(setup, alice->ppPhase1, alice->ppPublicValues,
            bob->ppPhase1, bob->ppPublicValues);
    dhMemFreePh2(setup, alice->ppSecretKeys, alice->ppPhase2,
            bob->ppSecretKeys, bob->ppPhase2);
    if (NULL != pPrivateKey)
    {
      qaeMemFreeNUMA((void**)&pPrivateKey);
    }
    if (NULL != pPublicKey)
    {
      qaeMemFreeNUMA((void**)&pPublicKey);
    }
}
/**
 *****************************************************************************
 * @ingroup dsaPerformance
 *
 * @description
 *      free all memory used in DSA performance code in this file
 *
 *****************************************************************************/
void freeDsaMem(dsa_test_params_t* setup,
        CpaFlatBuffer* dsaX,
        CpaFlatBuffer* dsaY,
        CpaFlatBuffer* dsaK,
        CpaFlatBuffer* dsaM,
        CpaFlatBuffer* dsaZ,
        CpaFlatBuffer* dsaR,
        CpaFlatBuffer* dsaS,
        CpaCyDsaVerifyOpData* verifyOpData,
        CpaFlatBuffer dsaG,
        CpaFlatBuffer dsaP,
        CpaFlatBuffer dsaH,
        CpaFlatBuffer dsaQ)
{
    freeArrayFlatBufferNUMA(dsaX, setup->numBuffers);
    freeArrayFlatBufferNUMA(dsaY, setup->numBuffers);
    freeArrayFlatBufferNUMA(dsaK, setup->numBuffers);
    freeArrayFlatBufferNUMA(dsaM, setup->numBuffers);
    freeArrayFlatBufferNUMA(dsaZ, setup->numBuffers);
    freeArrayFlatBufferNUMA(dsaR, setup->numBuffers);
    freeArrayFlatBufferNUMA(dsaS, setup->numBuffers);
    qaeMemFree((void**)&verifyOpData);
    /*free the normal flatBuffer pData */
    qaeMemFreeNUMA((void**)&dsaG.pData);
    qaeMemFreeNUMA((void**)&dsaP.pData);
    qaeMemFreeNUMA((void**)&dsaH.pData);
    qaeMemFreeNUMA((void**)&dsaQ.pData);
}
Exemple #3
0
void qaeCryptoMemFree(void *ptr)
{
    int rc;

    MEM_DEBUG("%s: Address: %p\n", __func__, ptr);

    if (NULL == ptr) {
        MEM_WARN("qaeCryptoMemFree trying to free NULL pointer.\n");
        return;
    }

    MEM_DEBUG("%s: pthread_mutex_lock\n", __func__);
    if ((rc = pthread_mutex_lock(&mem_mutex)) != 0) {
        MEM_ERROR("pthread_mutex_lock: %s\n", strerror(rc));
        return;
    }

    qaeMemFreeNUMA(&ptr);

    if ((rc = pthread_mutex_unlock(&mem_mutex)) != 0) {
        MEM_ERROR("pthread_mutex_unlock: %s\n", strerror(rc));
        return;
    }
    MEM_DEBUG("%s: pthread_mutex_unlock\n", __func__);
}
/*****************************************************************************
 * @ingroup IKE_RSA
 *
 * @description
 * This function is free an array of operation data structures for
 * ikersa operations, any memory allocation is freed in
 * ikeRsaPerform
 ******************************************************************************/
static void ikeRsaMemFreeRsaData(ike_rsa_client_data_t* client)
{
    if(NULL != client)
    {
        if(NULL != client->ppSignatures)
        {
            qaeMemFreeNUMA((void**)&client->ppSignatures);
        }
        if(NULL != client->ppDecryptOpData)
        {
            qaeMemFreeNUMA((void**)&client->ppDecryptOpData);
        }
        if(NULL != client->ppEncryptOpData)
        {
            qaeMemFreeNUMA((void**)&client->ppEncryptOpData);
        }
        if(NULL != client->ppPVverifier)
        {
            qaeMemFreeNUMA((void**)&client->ppPVverifier);
        }
        if(NULL != client->ppEncryptOpData2)
        {
            qaeMemFreeNUMA((void**)&client->ppEncryptOpData2);
        }
        if(NULL != client->ppPVverifier2)
        {
            qaeMemFreeNUMA((void**)&client->ppPVverifier2);
        }
    }
}
/*****************************************************************************
 * @ingroup IKE_RSA
 *
 * @description
 *      This function sets up the QA API asymmetric functions of an IKE
 *      transaction using RSA to sign/verify DH generated keys
 ******************************************************************************/
static CpaStatus ikeRsaPerform(asym_test_params_t* setup)
{
    CpaStatus status = CPA_STATUS_SUCCESS;
    Cpa32U i = 0;
    Cpa32U innerLoop = 0;
    ike_rsa_client_data_t alice = {0};
    ike_rsa_client_data_t bob = {0};
    CpaCyRsaPrivateKey    **pPrivateKey = NULL;
    CpaCyRsaPublicKey     **pPublicKey = NULL;
    Cpa32U node = 0;
    /*functions called in this code over writes the performanceStats->response,
     * so we use a local counter to count responses */
    Cpa32U responses = 0;

    status = sampleCodeCyGetNode(setup->cyInstanceHandle, &node);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("sampleCodeCyGetNode failed with status %u\n", status);
        return status;
    }
    /************************************************************************/
    /* Allocate all the memory for DH and RSA operations                    */
    /************************************************************************/
    /*these macros internally free memory return fail if they fail*/
   status = allocArrayOfPointers(
            setup->cyInstanceHandle,
            (void**)&pPrivateKey,
            setup->numBuffers);
    if(CPA_STATUS_SUCCESS != status)
    {
        return CPA_STATUS_FAIL;
    }

    status = allocArrayOfPointers(
            setup->cyInstanceHandle,
            (void**)&pPublicKey,
            setup->numBuffers);
    if(CPA_STATUS_SUCCESS != status)
    {
        qaeMemFreeNUMA((void**)&pPrivateKey);
        return CPA_STATUS_FAIL;
    }

    /*Allocate for Alice*/
    if(CPA_STATUS_SUCCESS != allocClientMem(setup, &alice))
    {
        PRINT_ERR("allocClientMem error\n");
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return CPA_STATUS_FAIL;
    }
    /*Allocate for Bob*/
    if(CPA_STATUS_SUCCESS != allocClientMem(setup, &bob))
    {
        PRINT_ERR("allocClientMem error\n");
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return CPA_STATUS_FAIL;
    }
    /* *************************************************************************
     * STEP 1. Alice & Bob generate public & private RSA keys
     * ************************************************************************/
    status = genKeyArray(setup, pPrivateKey, pPublicKey);
    if(status != CPA_STATUS_SUCCESS)
    {
        PRINT_ERR("Error, failed genKeyArray, status: %d\n",
                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }
    /**************************************************************************
    * STEP 2. Alice & Bob agree on a p & g and generate secret random x
     **************************************************************************/
    status = dhPhase1Setup(setup, alice.ppPhase1, bob.ppPhase1,
            alice.ppPublicValues, bob.ppPublicValues, pPublicKey);
    if(status != CPA_STATUS_SUCCESS)
    {
        PRINT_ERR("Error, failed dhPhase1Setup, status: %d\n",
                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }
    /**************************************************************************
     * STEP 3. Alice & Bob Perform DH Phase1 to produce Public Value -
     * PV = g^x mod p
     **************************************************************************/
    status = dhPhase1(alice.ppPhase1, alice.ppPublicValues, setup,
            setup->numBuffers, ONE_LOOP);
    if(status !=CPA_STATUS_SUCCESS)
    {
        PRINT_ERR("Error, failed to complete dhPhase1 for Alice, status: %d\n",
                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }
    /**************************************************************************/
    /*Perform DH phase1 for Bob                                               */
    /**************************************************************************/
    status = dhPhase1(bob.ppPhase1,bob.ppPublicValues, setup,
            setup->numBuffers, ONE_LOOP);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed to complete dhPhase1 for Bob, status: %d\n",
                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }

    /**************************************************************************/
    /*Perform Phase2 setup for Bob                                            */
    /**************************************************************************/
    status = dhPhase2Setup(bob.ppSecretKeys, bob.ppPhase1, bob.ppPhase2,
                alice.ppPublicValues, setup);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed to setup phase2 for Bob, status: %d\n",
                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }
    /**************************************************************************/
    /*Calculate Bobs secret keys                                            */
    /**************************************************************************/
    status = dhPhase2Perform(bob.ppSecretKeys, bob.ppPhase2,
            setup, setup->numBuffers, ONE_LOOP);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed to perform phase2 for Bob, status: %d\n",
                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }

    /***************************************************************************
     * STEP 5. Sign Bobs Public Value using peers public key ->
     * Bobs Signature = RSA decrypt bobsPV
     * ************************************************************************/
    /**************************************************************************/
    /*Setup the RSA decrypt structure                                         */
    /**************************************************************************/
    status = rsaDecryptDataSetup(bob.ppPublicValues, bob.ppDecryptOpData,
            bob.ppSignatures, setup);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed rsaDecryptDataSetup for Bob, status: %d\n",
                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }
    /**************************************************************************
     * setup encryption, we need an encryptOpData structure, because the
     * rsaSetOpDataKeys generates a public key and needs to copy it into
     * an encryptOpData structure
    **************************************************************************/
    status = rsaEncryptDataSetup(bob.ppSignatures, bob.ppEncryptOpData,
            bob.ppPVverifier, setup);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed rsaEncryptDataSetup for Bob, status: %d\n",
                        status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }
    status = rsaEncryptDataSetup(bob.ppSignatures, bob.ppEncryptOpData2,
            bob.ppPVverifier2, setup);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed rsaEncryptDataSetup for Bob, status: %d\n",
                        status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }
    /**************************************************************************/
    /* Setup decryption opData structure with RSA key                         */
    /**************************************************************************/
    rsaSetOpDataKeys(setup, bob.ppDecryptOpData, bob.ppEncryptOpData,
            pPrivateKey,pPublicKey);
    rsaSetOpDataKeys(setup, bob.ppDecryptOpData, bob.ppEncryptOpData2,
            pPrivateKey,pPublicKey);
    /**************************************************************************/
    /* Sign all of Bobs public value buffers, but loop only once              */
    /**************************************************************************/
    status = sampleRsaDecrypt(setup,
            bob.ppDecryptOpData,
            bob.ppSignatures,
            setup->numBuffers,
            ONE_LOOP);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed sampleRsaDecrypt for Bob, status: %d\n",
                        status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }
    /* Copy the RSADecrypt output into the Encrypt Op structure
     * in the performance loop we verify bobs signature. Bobs signature is
     * the input the the encrypt operation*/
    for(i=0;i<setup->numBuffers;i++)
    {
        /*check that the signature is the expected length*/
        if(bob.ppEncryptOpData[i]->inputData.dataLenInBytes !=
            bob.ppSignatures[i]->dataLenInBytes)
        {
            PRINT_ERR("encrypt data len does not match the signature len\n");
            ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
            return status;
        }
        memcpy(bob.ppEncryptOpData[i]->inputData.pData,
                bob.ppSignatures[i]->pData,
                bob.ppEncryptOpData[i]->inputData.dataLenInBytes);
        /*check that the signature is the expected length*/
        if(bob.ppEncryptOpData2[i]->inputData.dataLenInBytes !=
            bob.ppSignatures[i]->dataLenInBytes)
        {
            PRINT_ERR("encrypt data len does not match the signature len\n");
            ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
            return status;
        }
        memcpy(bob.ppEncryptOpData2[i]->inputData.pData,
                bob.ppSignatures[i]->pData,
                bob.ppEncryptOpData2[i]->inputData.dataLenInBytes);
    }
    /***************************************************************************
     * STEP 6. Setup Alices Decrypt and Diffie Hellman Data for performance Loop
     * ************************************************************************/
    /**************************************************************************/
    /* Setup the RSA decrypt structure*/
    /**************************************************************************/
    status = rsaDecryptDataSetup(alice.ppPublicValues, alice.ppDecryptOpData,
            alice.ppSignatures, setup);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed rsaDecryptDataSetup for Alice, status: %d\n",
                                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return CPA_STATUS_FAIL;
    }
    /**************************************************************************
     * Setup encryption: we need an encryptOpData structure, because the
     * rsaSetOpDataKeys generates a public key and needs to copy it into
     * an encryptOpData structure
    **************************************************************************/
    status = rsaEncryptDataSetup(alice.ppSignatures, alice.ppEncryptOpData,
            alice.ppPVverifier, setup);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed rsaEncryptDataSetup for Alice, status: %d\n",
                                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return CPA_STATUS_FAIL;
    }
    /**************************************************************************/
    /*setup decryption opData structure with RSA key                          */
    /**************************************************************************/
    rsaSetOpDataKeys(setup, alice.ppDecryptOpData, alice.ppEncryptOpData,
            pPrivateKey,pPublicKey);

    /**************************************************************************/
    /* Perform Phase2 setup for Alice                                         */
    /**************************************************************************/
    status = dhPhase2Setup(alice.ppSecretKeys, alice.ppPhase1, alice.ppPhase2,
                bob.ppPVverifier, setup);
    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed to setup phase2 for Alice, status: %d\n",
                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }

    /***************************************************************************
     * STEP 7 IKE main mode Asymmetric steps
     **************************************************************************/

    if(CPA_STATUS_SUCCESS != status)
    {
        PRINT_ERR("Error, failed to allcate ppPVverifier2, status: %d\n",
                status);
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }
    /*this barrier will wait until all threads get to this point*/
    sampleCodeBarrier();
    memset(setup->performanceStats,0, sizeof(perf_data_t));
    setup->performanceStats->startCyclesTimestamp = sampleCodeTimestamp();

    /*pre-set the number of ops we plan to submit*/
    /*number of responses equals the number of QA APIs we have chained together
     * multiplied by the number of buffers and how many times we have looped
     * over the buffers */
    setup->performanceStats->numOperations = (Cpa64U)NUMBER_OF_CHAINED_OPS *
                         setup->numBuffers * setup->numLoops;
    setup->performanceStats->averagePacketSizeInBytes =
                                     setup->modulusSizeInBytes;
    setup->performanceStats->responses=0;
    /* Completion used in callback */
    sampleCodeSemaphoreInit(&setup->performanceStats->comp, 0);

    for(i = 0; i < setup->numLoops; i++)
    {
        for(innerLoop = 0; innerLoop < setup->numBuffers; innerLoop++)
        {
            /******************************************************************/
            /* Step 7a Perform DH phase1 for Alice
             * This step, performs setup->NumBuffers DH Phase1 Operations to
             * Calculate setup->numBuffers Public Values for Alice*/
            /******************************************************************/
            do
            {
            /*****************************************************************/
            /* ikeRsaCallback  : used in asynchronous mode
             * performanceStats: Opaque user data
             * ppPhase1        : Structure containing p, g and x
             * ppPublicValues  : Public value (output) */
            /******************************************************************/

                status = cpaCyDhKeyGenPhase1(setup->cyInstanceHandle,
                        NULL/*ikeRsaCallback*/,
                        setup->performanceStats,
                        alice.ppPhase1[innerLoop],
                        alice.ppPublicValues[innerLoop]);

                /*this is a back off mechanism to stop the code
                 * continually submitting requests. Without this the CPU
                 * can report a soft lockup if it continually loops
                 * on busy*/
                if(status == CPA_STATUS_RETRY)
                {
                    setup->performanceStats->retries++;
                    AVOID_SOFTLOCKUP;
                }
            } while (CPA_STATUS_RETRY == status);

            if(CPA_STATUS_SUCCESS != status)
            {
                PRINT_ERR("Failed to complete dhPhase1 for Alice, status: %d\n",
                        status);
                break;
            }
            /******************************************************************/
            /* Step 7b Perform RSA verify of third party...normally this is done
             *  on at third party to verify that bob is who he says he is, but
             *  here we are performing a second RSA encrypt on Bobs signature to
             *  test the sequence of calls                                    */
            /******************************************************************/
            do
            {
               status = cpaCyRsaEncrypt(
                  setup->cyInstanceHandle,
                  NULL/*ikeRsaCallback*/,
                  setup->performanceStats,
                  bob.ppEncryptOpData[innerLoop],
                  bob.ppPVverifier[innerLoop]);
               if(status == CPA_STATUS_RETRY)
               {
                 setup->performanceStats->retries++;
                 AVOID_SOFTLOCKUP;
               }
            } while (CPA_STATUS_RETRY == status);

            if (CPA_STATUS_SUCCESS != status)
            {
                PRINT_ERR("Failed on RsaVerify for Bob using buffer=%d \n",
                        innerLoop);
                break;
            }

            /***************************************************************
             * Step 7c Perform RSA verify of Bobs signed public values.
             * Bobs Public values and Bobs RSA Signature have been
             * pre-calculated Bobs signature is in the EncryptOpData
             * structure, the verifier value should match bobsPublic value,
             * but in this code we dont check if they match
             **************************************************************/
            do
            {
                status = cpaCyRsaEncrypt(
                    setup->cyInstanceHandle,
                    NULL/*ikeRsaCallback*/,
                    setup->performanceStats,
                    bob.ppEncryptOpData2[innerLoop],
                    bob.ppPVverifier2[innerLoop]);
                if(status == CPA_STATUS_RETRY)
                {
                    setup->performanceStats->retries++;
                    AVOID_SOFTLOCKUP;
                }
            } while (CPA_STATUS_RETRY == status);

            if (CPA_STATUS_SUCCESS != status)
            {
                PRINT_ERR("Failed on RsaVerify for Bob using buffer=%d \n ",
                        innerLoop);
                break;
            }

            /******************************************************************
             * Step 7d Sign all of Alices public value buffers,
             * Alices Public Value is in the Decrypt opData setup, the signature
             *  is placed in alices signature
            ******************************************************************/
            do
            {
               status = cpaCyRsaDecrypt(
                  setup->cyInstanceHandle,
                  NULL/*ikeRsaCallback*/,
                  setup->performanceStats,
                  alice.ppDecryptOpData[innerLoop],
                  alice.ppSignatures[innerLoop]);
               if(status == CPA_STATUS_RETRY)
               {
                   setup->performanceStats->retries++;
                   AVOID_SOFTLOCKUP;
               }
            } while (CPA_STATUS_RETRY == status);

            if (CPA_STATUS_SUCCESS != status)
            {
                PRINT_ERR("Failed to complete RsaSign for Alice, status: %d\n",
                  innerLoop);
                break;
            }
            /******************************************************************/
            /* Step 7e Perform the DH phase2 operation for Alice,
             * using Bobs verified Public values                              */

            do
            {
                status = cpaCyDhKeyGenPhase2Secret(setup->cyInstanceHandle,
                        NULL/*ikeRsaCallback*/,
                        setup->performanceStats,
                        alice.ppPhase2[innerLoop],
                        alice.ppSecretKeys[innerLoop]);

                /*this is a back off mechanism to stop the code
                * continually calling the Decrypt operation when the
                * acceleration units are busy. Without this the CPU
                * can report a soft lockup if it continually loops
                * on busy*/
                if(status == CPA_STATUS_RETRY)
                {
                    setup->performanceStats->retries++;
                    AVOID_SOFTLOCKUP;
                }
            } while (CPA_STATUS_RETRY == status);

            if (CPA_STATUS_SUCCESS != status)
            {
                PRINT_ERR("Diffie Hellman Phase2 for Alice, status: %d\n",
                        status);
                break;
            }
            /*At this point Bob and Alice should have created the same shared
             * secret key*/
            responses++;
        } /*end innerLoop*/
        if (CPA_STATUS_SUCCESS != status)
        {
          break;
        }

    } /*end numLoops*/
    setup->performanceStats->endCyclesTimestamp = sampleCodeTimestamp();
    /*if (CPA_STATUS_SUCCESS == status)
    {
        if(sampleCodeSemaphoreWait(&setup->performanceStats->comp,
                SAMPLE_CODE_WAIT_FOREVER) != CPA_STATUS_SUCCESS)
        {
           PRINT_ERR("interruption in ike rsa Loop\n");
           status = CPA_STATUS_FAIL;
        }
    }*/

    sampleCodeSemaphoreDestroy(&setup->performanceStats->comp);

    if(CPA_STATUS_SUCCESS != status)
    {
        ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
        return status;
    }

    ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey);
    /*set the total number of responses and requests. */
    setup->performanceStats->numOperations = (Cpa64U)responses * NUMBER_OF_CHAINED_OPS;
    setup->performanceStats->responses = responses * NUMBER_OF_CHAINED_OPS;
    if(CPA_STATUS_SUCCESS != setup->performanceStats->threadReturnStatus)
    {
        status = CPA_STATUS_FAIL;
    }
    return status;
}