5; i <= CPA_CY_SYM_HASH_SHA512; i++)
    {
        pContentDesc = NULL;
        pHashAlgInfo = NULL;

        LacSymQat_HashAlgLookupGet(instanceHandle, i, &pHashAlgInfo);

        status = LAC_OS_CAMALLOC(&pContentDesc,
                                 LAC_SYM_QAT_MAX_HASH_SETUP_BLK_SZ,
                                 LAC_64BYTE_ALIGNMENT,
                                 pService->nodeAffinity);

        if (CPA_STATUS_SUCCESS == status)
        {
            pService->ppHmacContentDesc[i] = (Cpa8U *)pContentDesc;
        }
        else
        {
            break;
        }
    }

    if (CPA_STATUS_SUCCESS!= status)
    {
        for (i = CPA_CY_SYM_HASH_MD5; i <= CPA_CY_SYM_HASH_SHA512; i++)
        {
            LAC_OS_CAFREE(pService->ppHmacContentDesc[i]);
        }
        LAC_OS_FREE(pService->ppHmacContentDesc);
    }

    return status;
}

void LacSymHash_HmacPrecompShutdown(CpaInstanceHandle instanceHandle)
{
    Cpa32U i = 0;
    sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;

    if (NULL!= pService->ppHmacContentDesc)
    {
        for (i = CPA_CY_SYM_HASH_MD5; i <= CPA_CY_SYM_HASH_SHA512; i++)
        {
            LAC_OS_CAFREE(pService->ppHmacContentDesc[i]);
        }
        LAC_OS_FREE(pService->ppHmacContentDesc);
    }
}

/**
*******************************************************************************
* @ingroup LacHashDefs
*      Perform single hash precompute operation for HMAC
*
* @description
*      This function builds up a request and sends it to the QAT for a single
*      hmac precompute operation.
*
* @param[in]  instanceHandle       Instance Handle
* @param[in]  hashAlgorithm        Hash Algorithm
* @param[in]  pHashOpData          Operation data used for a single hmac
*                                  precompute operation for a session
*
* @retval CPA_STATUS_SUCCESS       Success
* @retval CPA_STATUS_RETRY         Retry the operation.
* @retval CPA_STATUS_FAIL          Operation Failed
*
*****************************************************************************/
STATIC CpaStatus
LacSymHash_HmacPreCompute(CpaInstanceHandle instanceHandle,
                          CpaCySymHashAlgorithm hashAlgorithm,
                          lac_sym_hash_precomp_op_data_t *pHashOpData)
{
    CpaStatus status = CPA_STATUS_SUCCESS;
    icp_buffer_list_desc_t *pBufferListDesc = NULL;
    icp_flat_buffer_desc_t *pCurrFlatBufDesc = NULL;
    lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
    Cpa64U srcAddrPhys = 0;
    lac_sym_qat_hash_state_buffer_info_t hashStateBufferInfo = {0};
    icp_qat_fw_la_bulk_req_t bulkMsg;
    Cpa64U hashReqParamsPhys = 0;
    sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;

    /* Convenience pointer */
    lac_sym_hash_hmac_precomp_qat_t *pHmacQatData = &pHashOpData->u.hmacQatData;

    LacSymQat_HashAlgLookupGet(instanceHandle, hashAlgorithm, &pHashAlgInfo);

    hashStateBufferInfo.pData = pHmacQatData->hashStateStorage;
    hashStateBufferInfo.pDataPhys =
        LAC_MEM_CAST_PTR_TO_UINT64(LAC_OS_VIRT_TO_PHYS_EXTERNAL(
            pService->generic_service_info, pHmacQatData->hashStateStorage));

    if (hashStateBufferInfo.pDataPhys == 0)
    {
        LAC_LOG_ERROR("Unable to get the physical address of "
                      "the hashStateStorage\n");
        return CPA_STATUS_FAIL;
    }

    hashStateBufferInfo.stateStorageSzQuadWords =
        LAC_BYTES_TO_QUADWORDS(sizeof(icp_qat_hw_auth_counter_t) +
                               LAC_ALIGN_POW2_ROUNDUP(pHashAlgInfo->stateSize,
                                                      LAC_QUAD_WORD_IN_BYTES));
    hashStateBufferInfo.prefixAadSzQuadWords = 0;

    pBufferListDesc = (icp_buffer_list_desc_t *)pHmacQatData->bufferDesc;
    pBufferListDesc->numBuffers = 1;

    pCurrFlatBufDesc = (icp_flat_buffer_desc_t *)(pBufferListDesc->phyBuffers);
    pCurrFlatBufDesc->dataLenInBytes = pHashAlgInfo->blockLength;
    pCurrFlatBufDesc->phyBuffer =
        LAC_MEM_CAST_PTR_TO_UINT64(LAC_OS_VIRT_TO_PHYS_EXTERNAL(
            pService->generic_service_info, pHmacQatData->data));

    if (pCurrFlatBufDesc->phyBuffer == 0)
    {
        LAC_LOG_ERROR("Unable to get the physical address of "
                      "the HMAC data\n");
        return CPA_STATUS_FAIL;
    }

    srcAddrPhys = LAC_MEM_CAST_PTR_TO_UINT64(LAC_OS_VIRT_TO_PHYS_EXTERNAL(
        pService->generic_service_info, pBufferListDesc));

    if (srcAddrPhys == 0)
    {
        LAC_LOG_ERROR("Unable to get the physical address of "
                      "the source buffer\n");
        return CPA_STATUS_FAIL;
    }

    pHashOpData->pInstance = pService;

    hashReqParamsPhys = LAC_OS_VIRT_TO_PHYS_EXTERNAL(
        pService->generic_service_info, &(pHmacQatData->hashReqParams));

    if (hashReqParamsPhys == 0)
    {
        LAC_LOG_ERROR("Unable to get the physical address of the hash request"
                      " params\n");
        return CPA_STATUS_FAIL;
    }

    /* Send to QAT */
    status = SalQatMsg_transPutMsg(pService->trans_handle_sym_tx,
                                   (void *)&(bulkMsg),
                                   LAC_QAT_SYM_REQ_SZ_LW,
                                   LAC_LOG_MSG_SYMCYBULK,
                                   NULL);

    return status;
}

CpaStatus LacSymHash_HmacPreComputes(CpaInstanceHandle instanceHandle,
                                     CpaCySymHashAlgorithm hashAlgorithm,
                                     Cpa32U authKeyLenInBytes,
                                     Cpa8U *pAuthKey,
                                     Cpa8U *pWorkingMemory,
                                     Cpa8U *pState1,
                                     Cpa8U *pState2,
                                     lac_hash_precompute_done_cb_t callbackFn,
                                     void *pCallbackTag)
{
    CpaStatus status = CPA_STATUS_SUCCESS;

    /* Memory is carved up for pHmacIpadOpData and for pHmacOpadOpData
     * one after another. As the structure size is a multiple of 8, if the
     * first one is aligned on an 8 byte boundary, so too will the second
     * structure. The pOpStatus structure is carved up just after these two
     * structures and has no alignment constraints. Pointer arithemtic is
     * used to carve the memory up. */
    lac_sym_hash_precomp_op_data_t *pHmacIpadOpData =
        (lac_sym_hash_precomp_op_data_t *)pWorkingMemory;
    lac_sym_hash_precomp_op_data_t *pHmacOpadOpData = pHmacIpadOpData + 1;