#include "cpa.h"
#include "cpa_cy_sym.h"
#include "cpa_cy_im.h"
#include "icp_adf_init.h"
#include "icp_adf_transport.h"
#include "icp_adf_transport_dp.h"
#include "icp_accel_devices.h"
#include "icp_adf_debug.h"
#include "icp_qat_fw_la.h"
#include "lac_common.h"
#include "lac_log.h"
#include "lac_mem.h"
#include "lac_mem_pools.h"
#include "lac_list.h"
#include "lac_sym.h"
#include "lac_sym_qat.h"
#include "lac_sal.h"
#include "lac_sal_ctrl.h"
#include "lac_session.h"
#include "lac_sym_cipher.h"
#include "lac_sym_hash.h"
#include "lac_sym_alg_chain.h"
#include "lac_sym_stats.h"
#include "lac_sym_partial.h"
#include "lac_sym_qat_hash_defs_lookup.h"
#include "lac_sym_cb.h"
#include "lac_buffer_desc.h"
#include "lac_sync.h"
#include "lac_hooks.h"
#include "lac_sal_types_crypto.h"
#include "sal_service_state.h"
#define IS_EXT_ALG_CHAIN_UNSUPPORTED(cipherAlgorithm, \
hashAlgorithm, \
extAlgchainSupported) \
((((CPA_CY_SYM_CIPHER_ZUC_EEA3 == cipherAlgorithm || \
CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == cipherAlgorithm) && \
CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) || \
((CPA_CY_SYM_CIPHER_NULL == cipherAlgorithm || \
CPA_CY_SYM_CIPHER_AES_CTR == cipherAlgorithm || \
CPA_CY_SYM_CIPHER_ZUC_EEA3 == cipherAlgorithm) && \
CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) || \
((CPA_CY_SYM_CIPHER_NULL == cipherAlgorithm || \
CPA_CY_SYM_CIPHER_AES_CTR == cipherAlgorithm || \
CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == cipherAlgorithm) && \
CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm)) && \
!extAlgchainSupported)
static CpaStatus
LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer,
const CpaBufferList *const pDstBuffer,
const lac_session_desc_t *const pSessionDesc,
const CpaCySymOpData *const pOpData);
void LacDp_WriteRingMsgFull(CpaCySymDpOpData *pRequest,
icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
void LacDp_WriteRingMsgOpt(CpaCySymDpOpData *pRequest,
icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
void getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData,
Cpa32U *pSessionCtxSizeInBytes);
void
LacSync_GenBufListVerifyCb(void *pCallbackTag,
CpaStatus status,
CpaCySymOp operationType,
void *pOpData,
CpaBufferList *pDstBuffer,
CpaBoolean opResult)
{
LacSync_GenVerifyWakeupSyncCaller(pCallbackTag, status, opResult);
}
static CpaStatus
LacSymSession_ParamCheck(const CpaInstanceHandle instanceHandle,
const CpaCySymSessionSetupData *pSessionSetupData)
{
const CpaCySymCipherSetupData *const pCipherSetupData =
(const CpaCySymCipherSetupData *)&pSessionSetupData
->cipherSetupData;
const CpaCySymHashSetupData *const pHashSetupData =
&pSessionSetupData->hashSetupData;
CpaCySymCapabilitiesInfo capInfo;
CpaCyCapabilitiesInfo cyCapInfo;
cpaCySymQueryCapabilities(instanceHandle, &capInfo);
SalCtrl_CyQueryCapabilities(instanceHandle, &cyCapInfo);
if ((CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
pSessionSetupData->symOperation) ||
(CPA_CY_SYM_OP_CIPHER == pSessionSetupData->symOperation)) {
if (pCipherSetupData->cipherAlgorithm >=
CPA_CY_SYM_CIPHER_CAP_BITMAP_SIZE) {
LAC_INVALID_PARAM_LOG("cipherAlgorithm");
return CPA_STATUS_INVALID_PARAM;
}
if (!CPA_BITMAP_BIT_TEST(capInfo.ciphers,
pCipherSetupData->cipherAlgorithm)) {
LAC_UNSUPPORTED_PARAM_LOG(
"UnSupported cipherAlgorithm");
return CPA_STATUS_UNSUPPORTED;
}
}
if ((CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
pSessionSetupData->symOperation) ||
(CPA_CY_SYM_OP_HASH == pSessionSetupData->symOperation)) {
if (pHashSetupData->hashAlgorithm >=
CPA_CY_SYM_HASH_CAP_BITMAP_SIZE) {
LAC_INVALID_PARAM_LOG("hashAlgorithm");
return CPA_STATUS_INVALID_PARAM;
}
if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
pHashSetupData->hashAlgorithm)) {
LAC_UNSUPPORTED_PARAM_LOG("UnSupported hashAlgorithm");
return CPA_STATUS_UNSUPPORTED;
}
}
if (CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
pSessionSetupData->symOperation) {
if (((CPA_CY_SYM_CIPHER_CHACHA ==
pCipherSetupData->cipherAlgorithm) &&
(CPA_CY_SYM_HASH_POLY != pHashSetupData->hashAlgorithm)) ||
((CPA_CY_SYM_HASH_POLY == pHashSetupData->hashAlgorithm) &&
(CPA_CY_SYM_CIPHER_CHACHA !=
pCipherSetupData->cipherAlgorithm))) {
LAC_INVALID_PARAM_LOG(
"Invalid combination of Cipher/Hash "
"Algorithms for CHACHA/POLY");
return CPA_STATUS_INVALID_PARAM;
}
if (((CPA_CY_SYM_CIPHER_AES_CCM ==
pCipherSetupData->cipherAlgorithm) &&
(CPA_CY_SYM_HASH_AES_CCM !=
pHashSetupData->hashAlgorithm)) ||
((CPA_CY_SYM_HASH_AES_CCM ==
pHashSetupData->hashAlgorithm) &&
(CPA_CY_SYM_CIPHER_AES_CCM !=
pCipherSetupData->cipherAlgorithm))) {
LAC_INVALID_PARAM_LOG(
"Invalid combination of Cipher/Hash Algorithms for CCM");
return CPA_STATUS_INVALID_PARAM;
}
if ((CPA_CY_SYM_CIPHER_AES_GCM ==
pCipherSetupData->cipherAlgorithm &&
(CPA_CY_SYM_HASH_AES_GCM !=
pHashSetupData->hashAlgorithm &&
CPA_CY_SYM_HASH_AES_GMAC !=
pHashSetupData->hashAlgorithm)) ||
((CPA_CY_SYM_HASH_AES_GCM ==
pHashSetupData->hashAlgorithm ||
CPA_CY_SYM_HASH_AES_GMAC ==
pHashSetupData->hashAlgorithm) &&
CPA_CY_SYM_CIPHER_AES_GCM !=
pCipherSetupData->cipherAlgorithm)) {
LAC_INVALID_PARAM_LOG(
"Invalid combination of Cipher/Hash Algorithms for GCM");
return CPA_STATUS_INVALID_PARAM;
}
if (((CPA_CY_SYM_CIPHER_KASUMI_F8 ==
pCipherSetupData->cipherAlgorithm) &&
(CPA_CY_SYM_HASH_KASUMI_F9 !=
pHashSetupData->hashAlgorithm)) ||
((CPA_CY_SYM_HASH_KASUMI_F9 ==
pHashSetupData->hashAlgorithm) &&
(CPA_CY_SYM_CIPHER_KASUMI_F8 !=
pCipherSetupData->cipherAlgorithm))) {
LAC_INVALID_PARAM_LOG(
"Invalid combination of Cipher/Hash Algorithms for Kasumi");
return CPA_STATUS_INVALID_PARAM;
}
if (IS_EXT_ALG_CHAIN_UNSUPPORTED(
pCipherSetupData->cipherAlgorithm,
pHashSetupData->hashAlgorithm,
cyCapInfo.extAlgchainSupported)) {
LAC_UNSUPPORTED_PARAM_LOG(
"ExtAlgChain feature not supported");
return CPA_STATUS_UNSUPPORTED;
}
if (((CPA_CY_SYM_CIPHER_SNOW3G_UEA2 ==
pCipherSetupData->cipherAlgorithm) &&
(CPA_CY_SYM_HASH_SNOW3G_UIA2 !=
pHashSetupData->hashAlgorithm)) ||
((CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
pHashSetupData->hashAlgorithm) &&
(CPA_CY_SYM_CIPHER_SNOW3G_UEA2 !=
pCipherSetupData->cipherAlgorithm))) {
LAC_INVALID_PARAM_LOG(
"Invalid combination of Cipher/Hash Algorithms for Snow3G");
return CPA_STATUS_INVALID_PARAM;
}
if (((CPA_CY_SYM_CIPHER_ZUC_EEA3 ==
pCipherSetupData->cipherAlgorithm) &&
(CPA_CY_SYM_HASH_ZUC_EIA3 !=
pHashSetupData->hashAlgorithm)) ||
((CPA_CY_SYM_HASH_ZUC_EIA3 ==
pHashSetupData->hashAlgorithm) &&
(CPA_CY_SYM_CIPHER_ZUC_EEA3 !=
pCipherSetupData->cipherAlgorithm))) {
LAC_INVALID_PARAM_LOG(
"Invalid combination of Cipher/Hash Algorithms for ZUC");
return CPA_STATUS_INVALID_PARAM;
}
}
else if (CPA_CY_SYM_OP_CIPHER == pSessionSetupData->symOperation) {
if ((CPA_CY_SYM_CIPHER_AES_CCM ==
pCipherSetupData->cipherAlgorithm) ||
(CPA_CY_SYM_CIPHER_AES_GCM ==
pCipherSetupData->cipherAlgorithm) ||
(CPA_CY_SYM_CIPHER_CHACHA ==
pCipherSetupData->cipherAlgorithm)) {
LAC_INVALID_PARAM_LOG(
"Invalid Cipher Algorithm for non-Algorithm "
"Chaining operation");
return CPA_STATUS_INVALID_PARAM;
}
} else if (CPA_CY_SYM_OP_HASH == pSessionSetupData->symOperation) {
if ((CPA_CY_SYM_HASH_AES_CCM ==
pHashSetupData->hashAlgorithm) ||
(CPA_CY_SYM_HASH_AES_GCM ==
pHashSetupData->hashAlgorithm) ||
(CPA_CY_SYM_HASH_AES_GMAC ==
pHashSetupData->hashAlgorithm) ||
(CPA_CY_SYM_HASH_POLY == pHashSetupData->hashAlgorithm)) {
LAC_INVALID_PARAM_LOG(
"Invalid Hash Algorithm for non-Algorithm Chaining operation");
return CPA_STATUS_INVALID_PARAM;
}
}
else {
LAC_INVALID_PARAM_LOG("symOperation");
return CPA_STATUS_INVALID_PARAM;
}
if (CPA_CY_SYM_OP_HASH != pSessionSetupData->symOperation) {
if ((pCipherSetupData->cipherDirection !=
CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) &&
(pCipherSetupData->cipherDirection !=
CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT)) {
LAC_INVALID_PARAM_LOG("Invalid Cipher Direction");
return CPA_STATUS_INVALID_PARAM;
}
}
return CPA_STATUS_SUCCESS;
}
static CpaStatus
LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer,
const CpaBufferList *const pDstBuffer,
const lac_session_desc_t *const pSessionDesc,
const CpaCySymOpData *const pOpData)
{
Cpa64U srcBufferLen = 0, dstBufferLen = 0;
CpaStatus status = CPA_STATUS_SUCCESS;
switch (pOpData->packetType) {
case CPA_CY_SYM_PACKET_TYPE_FULL:
case CPA_CY_SYM_PACKET_TYPE_PARTIAL:
case CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL:
break;
default: {
LAC_INVALID_PARAM_LOG("packetType");
return CPA_STATUS_INVALID_PARAM;
}
}
if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation &&
CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) &&
(0 == pOpData->messageLenToHashInBytes))) {
if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(
pSessionDesc->cipherAlgorithm,
pSessionDesc->hashAlgorithm)) {
status = LacBuffDesc_BufferListVerifyNull(
pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT);
} else {
status = LacBuffDesc_BufferListVerify(
pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT);
}
if (CPA_STATUS_SUCCESS != status) {
LAC_INVALID_PARAM_LOG("Source buffer invalid");
return CPA_STATUS_INVALID_PARAM;
}
} else {
if (NULL == pSrcBuffer->pPrivateMetaData) {
LAC_INVALID_PARAM_LOG(
"Source buffer MetaData cannot be NULL");
return CPA_STATUS_INVALID_PARAM;
}
}
if (pSrcBuffer != pDstBuffer) {
if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation &&
CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) &&
(0 == pOpData->messageLenToHashInBytes))) {
if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(
pSessionDesc->cipherAlgorithm,
pSessionDesc->hashAlgorithm)) {
status = LacBuffDesc_BufferListVerifyNull(
pDstBuffer,
&dstBufferLen,
LAC_NO_ALIGNMENT_SHIFT);
} else {
status = LacBuffDesc_BufferListVerify(
pDstBuffer,
&dstBufferLen,
LAC_NO_ALIGNMENT_SHIFT);
}
if (CPA_STATUS_SUCCESS != status) {
LAC_INVALID_PARAM_LOG(
"Destination buffer invalid");
return CPA_STATUS_INVALID_PARAM;
}
} else {
if (NULL == pDstBuffer->pPrivateMetaData) {
LAC_INVALID_PARAM_LOG(
"Dest buffer MetaData cannot be NULL");
return CPA_STATUS_INVALID_PARAM;
}
}
if (srcBufferLen != dstBufferLen &&
pSessionDesc->cipherAlgorithm !=
CPA_CY_SYM_CIPHER_AES_CCM) {
LAC_INVALID_PARAM_LOG(
"Source and Dest buffer lengths need to be equal ");
return CPA_STATUS_INVALID_PARAM;
}
}
if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) {
if (CPA_FALSE == pSessionDesc->isPartialSupported) {
LAC_INVALID_PARAM_LOG(
"Partial packets not supported for operation");
return CPA_STATUS_INVALID_PARAM;
} else {
if (CPA_STATUS_SUCCESS !=
LacSym_PartialPacketStateCheck(
pOpData->packetType,
pSessionDesc->partialState)) {
LAC_INVALID_PARAM_LOG("Partial packet Type");
return CPA_STATUS_INVALID_PARAM;
}
}
}
return CPA_STATUS_SUCCESS;
}
CpaStatus
cpaCySymInitSession(const CpaInstanceHandle instanceHandle_in,
const CpaCySymCbFunc pSymCb,
const CpaCySymSessionSetupData *pSessionSetupData,
CpaCySymSessionCtx pSessionCtx)
{
CpaStatus status = CPA_STATUS_SUCCESS;
CpaInstanceHandle instanceHandle = NULL;
sal_service_t *pService = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
pService = (sal_service_t *)instanceHandle;
SAL_RUNNING_CHECK(pService);
status = LacSym_InitSession(instanceHandle,
pSymCb,
pSessionSetupData,
CPA_FALSE,
pSessionCtx);
if (CPA_STATUS_SUCCESS == status) {
LAC_SYM_STAT_INC(numSessionsInitialized, instanceHandle);
} else
{
LAC_SYM_STAT_INC(numSessionErrors, instanceHandle);
}
return status;
}
CpaStatus
cpaCySymSessionInUse(CpaCySymSessionCtx pSessionCtx, CpaBoolean *pSessionInUse)
{
CpaStatus status = CPA_STATUS_SUCCESS;
lac_session_desc_t *pSessionDesc = NULL;
LAC_CHECK_NULL_PARAM(pSessionInUse);
LAC_CHECK_INSTANCE_HANDLE(pSessionCtx);
*pSessionInUse = CPA_FALSE;
pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx);
if (pSessionDesc->isDPSession) {
if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount)))
*pSessionInUse = CPA_TRUE;
} else {
if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount)))
*pSessionInUse = CPA_TRUE;
}
return status;
}
CpaStatus
LacSym_InitSession(const CpaInstanceHandle instanceHandle,
const CpaCySymCbFunc pSymCb,
const CpaCySymSessionSetupData *pSessionSetupData,
const CpaBoolean isDPSession,
CpaCySymSessionCtx pSessionCtx)
{
CpaStatus status = CPA_STATUS_SUCCESS;
lac_session_desc_t *pSessionDesc = NULL;
Cpa32U sessionCtxSizeInBytes = 0;
CpaPhysicalAddr physAddress = 0;
CpaPhysicalAddr physAddressAligned = 0;
sal_service_t *pService = NULL;
const CpaCySymCipherSetupData *pCipherSetupData = NULL;
const CpaCySymHashSetupData *pHashSetupData = NULL;
LAC_CHECK_NULL_PARAM(pSessionSetupData);
LAC_CHECK_NULL_PARAM(pSessionCtx);
status = LacSymSession_ParamCheck(instanceHandle, pSessionSetupData);
LAC_CHECK_STATUS(status);
if ((CPA_CY_PRIORITY_HIGH == pSessionSetupData->sessionPriority) ||
(CPA_CY_PRIORITY_NORMAL == pSessionSetupData->sessionPriority)) {
} else {
LAC_INVALID_PARAM_LOG("sessionPriority");
return CPA_STATUS_INVALID_PARAM;
}
pCipherSetupData = &pSessionSetupData->cipherSetupData;
pHashSetupData = &pSessionSetupData->hashSetupData;
pService = (sal_service_t *)instanceHandle;
physAddress =
LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService),
(Cpa8U *)pSessionCtx + sizeof(void *));
if (0 == physAddress) {
LAC_LOG_ERROR(
"Unable to get the physical address of the session\n");
return CPA_STATUS_FAIL;
}
physAddressAligned =
LAC_ALIGN_POW2_ROUNDUP(physAddress, LAC_64BYTE_ALIGNMENT);
pSessionDesc = (lac_session_desc_t *)
((Cpa8U *)pSessionCtx + sizeof(void *) +
(physAddressAligned - physAddress));
*((LAC_ARCH_UINT *)pSessionCtx) = (LAC_ARCH_UINT)pSessionDesc;
getCtxSize(pSessionSetupData, &sessionCtxSizeInBytes);
switch (sessionCtxSizeInBytes) {
case LAC_SYM_SESSION_D1_SIZE:
memset(pSessionDesc, 0, sizeof(lac_session_desc_d1_t));
break;
case LAC_SYM_SESSION_D2_SIZE:
memset(pSessionDesc, 0, sizeof(lac_session_desc_d2_t));
break;
default:
memset(pSessionDesc, 0, sizeof(lac_session_desc_t));
break;
}
pSessionDesc->contentDescInfo.pData = (Cpa8U *)pSessionDesc;
pSessionDesc->contentDescInfo.hardwareSetupBlockPhys =
physAddressAligned;
pSessionDesc->contentDescOptimisedInfo.pData =
((Cpa8U *)pSessionDesc + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE);
pSessionDesc->contentDescOptimisedInfo.hardwareSetupBlockPhys =
(physAddressAligned + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE);
pSessionDesc->symOperation = pSessionSetupData->symOperation;
if (CPA_FALSE == isDPSession) {
pSessionDesc->pSymCb = ((void *)NULL != (void *)pSymCb) ?
pSymCb :
LacSync_GenBufListVerifyCb;
}
pSessionDesc->isDPSession = isDPSession;
if ((CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm) ||
(CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) ||
(CPA_CY_SYM_HASH_AES_CCM == pHashSetupData->hashAlgorithm) ||
(CPA_CY_SYM_CIPHER_CHACHA == pCipherSetupData->cipherAlgorithm) ||
(CPA_CY_SYM_CIPHER_ARC4 == pCipherSetupData->cipherAlgorithm)) {
pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgFull;
} else {
pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgOpt;
}
if (CPA_STATUS_SUCCESS == status) {
pSessionDesc->internalSession = CPA_FALSE;
status = LacAlgChain_SessionInit(instanceHandle,
pSessionSetupData,
pSessionDesc);
}
return status;
}
CpaStatus
cpaCySymRemoveSession(const CpaInstanceHandle instanceHandle_in,
CpaCySymSessionCtx pSessionCtx)
{
lac_session_desc_t *pSessionDesc = NULL;
CpaStatus status = CPA_STATUS_SUCCESS;
CpaInstanceHandle instanceHandle = NULL;
Cpa64U numPendingRequests = 0;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
LAC_CHECK_NULL_PARAM(pSessionCtx);
SAL_RUNNING_CHECK(instanceHandle);
pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx);
LAC_CHECK_NULL_PARAM(pSessionDesc);
if (CPA_TRUE == pSessionDesc->isDPSession) {
numPendingRequests =
qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount));
} else {
numPendingRequests =
qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount));
}
if (0 != numPendingRequests) {
QAT_UTILS_LOG("There are %llu requests pending\n",
(unsigned long long)numPendingRequests);
status = CPA_STATUS_RETRY;
if (CPA_TRUE == pSessionDesc->isDPSession) {
icp_comms_trans_handle trans_handle =
((sal_crypto_service_t *)instanceHandle)
->trans_handle_sym_tx;
if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
QAT_UTILS_LOG("Submitting enqueued requests\n");
SalQatMsg_updateQueueTail(trans_handle);
return status;
}
}
}
if (CPA_STATUS_SUCCESS == status) {
LAC_SPINLOCK_DESTROY(&pSessionDesc->requestQueueLock);
if (CPA_FALSE == pSessionDesc->isDPSession) {
LAC_SYM_STAT_INC(numSessionsRemoved, instanceHandle);
}
} else if (CPA_FALSE == pSessionDesc->isDPSession) {
LAC_SYM_STAT_INC(numSessionErrors, instanceHandle);
}
return status;
}
static CpaStatus
LacSym_Perform(const CpaInstanceHandle instanceHandle,
void *callbackTag,
const CpaCySymOpData *pOpData,
const CpaBufferList *pSrcBuffer,
CpaBufferList *pDstBuffer,
CpaBoolean *pVerifyResult,
CpaBoolean isAsyncMode)
{
lac_session_desc_t *pSessionDesc = NULL;
CpaStatus status = CPA_STATUS_SUCCESS;
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
SAL_RUNNING_CHECK(instanceHandle);
LAC_CHECK_NULL_PARAM(pOpData);
LAC_CHECK_NULL_PARAM(pOpData->sessionCtx);
LAC_CHECK_NULL_PARAM(pSrcBuffer);
LAC_CHECK_NULL_PARAM(pDstBuffer);
pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pOpData->sessionCtx);
LAC_CHECK_NULL_PARAM(pSessionDesc);
if ((CPA_CY_SYM_CIPHER_CHACHA == pSessionDesc->cipherAlgorithm) &&
(CPA_CY_SYM_HASH_POLY == pSessionDesc->hashAlgorithm) &&
(CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
if (!pOpData->messageLenToCipherInBytes) {
LAC_INVALID_PARAM_LOG(
"Invalid messageLenToCipherInBytes for CHACHA-POLY");
return CPA_STATUS_INVALID_PARAM;
}
}
if ((LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb) &&
isAsyncMode == CPA_TRUE) {
CpaBoolean opResult = CPA_FALSE;
lac_sync_op_data_t *pSyncCallbackData = NULL;
status = LacSync_CreateSyncCookie(&pSyncCallbackData);
if (CPA_STATUS_SUCCESS == status) {
status = LacSym_Perform(instanceHandle,
pSyncCallbackData,
pOpData,
pSrcBuffer,
pDstBuffer,
pVerifyResult,
CPA_FALSE);
} else {
LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle);
return status;
}
if (CPA_STATUS_SUCCESS == status) {
CpaStatus syncStatus = CPA_STATUS_SUCCESS;
syncStatus = LacSync_WaitForCallback(
pSyncCallbackData,
LAC_SYM_SYNC_CALLBACK_TIMEOUT,
&status,
&opResult);
if (CPA_STATUS_SUCCESS != syncStatus) {
LAC_SYM_STAT_INC(numSymOpCompletedErrors,
instanceHandle);
LAC_LOG_ERROR("Callback timed out");
status = syncStatus;
}
} else {
LacSync_SetSyncCookieComplete(pSyncCallbackData);
}
if (CPA_STATUS_SUCCESS == status) {
if (NULL != pVerifyResult) {
*pVerifyResult = opResult;
}
}
LacSync_DestroySyncCookie(&pSyncCallbackData);
return status;
}
status =
LacSymPerform_BufferParamCheck((const CpaBufferList *)pSrcBuffer,
pDstBuffer,
pSessionDesc,
pOpData);
LAC_CHECK_STATUS(status);
if ((!pSessionDesc->digestIsAppended) &&
(CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
LAC_CHECK_NULL_PARAM(pOpData->pDigestResult);
}
status = LacAlgChain_Perform(instanceHandle,
pSessionDesc,
callbackTag,
pOpData,
pSrcBuffer,
pDstBuffer,
pVerifyResult);
if (CPA_STATUS_SUCCESS == status) {
if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) {
LacSym_PartialPacketStateUpdate(
pOpData->packetType, &pSessionDesc->partialState);
}
LAC_SYM_STAT_INC(numSymOpRequests, instanceHandle);
}
else {
LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle);
}
return status;
}
CpaStatus
cpaCySymPerformOp(const CpaInstanceHandle instanceHandle_in,
void *callbackTag,
const CpaCySymOpData *pOpData,
const CpaBufferList *pSrcBuffer,
CpaBufferList *pDstBuffer,
CpaBoolean *pVerifyResult)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
return LacSym_Perform(instanceHandle,
callbackTag,
pOpData,
pSrcBuffer,
pDstBuffer,
pVerifyResult,
CPA_TRUE);
}
CpaStatus
cpaCySymQueryStats(const CpaInstanceHandle instanceHandle_in,
struct _CpaCySymStats *pSymStats)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
LAC_CHECK_NULL_PARAM(pSymStats);
SAL_RUNNING_CHECK(instanceHandle);
LacSym_Stats32CopyGet(instanceHandle, pSymStats);
return CPA_STATUS_SUCCESS;
}
CpaStatus
cpaCySymQueryStats64(const CpaInstanceHandle instanceHandle_in,
CpaCySymStats64 *pSymStats)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
LAC_CHECK_NULL_PARAM(pSymStats);
SAL_RUNNING_CHECK(instanceHandle);
LacSym_Stats64CopyGet(instanceHandle, pSymStats);
return CPA_STATUS_SUCCESS;
}
CpaStatus
cpaCySymSessionCtxGetSize(const CpaInstanceHandle instanceHandle_in,
const CpaCySymSessionSetupData *pSessionSetupData,
Cpa32U *pSessionCtxSizeInBytes)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
LAC_CHECK_NULL_PARAM(pSessionSetupData);
LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
SAL_RUNNING_CHECK(instanceHandle);
*pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE;
return CPA_STATUS_SUCCESS;
}
CpaStatus
cpaCySymSessionCtxGetDynamicSize(
const CpaInstanceHandle instanceHandle_in,
const CpaCySymSessionSetupData *pSessionSetupData,
Cpa32U *pSessionCtxSizeInBytes)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
LAC_CHECK_NULL_PARAM(pSessionSetupData);
LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
SAL_RUNNING_CHECK(instanceHandle);
getCtxSize(pSessionSetupData, pSessionCtxSizeInBytes);
return CPA_STATUS_SUCCESS;
}
void
getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData,
Cpa32U *pSessionCtxSizeInBytes)
{
if ((pSessionSetupData->cipherSetupData.cipherAlgorithm !=
CPA_CY_SYM_CIPHER_ARC4) &&
(pSessionSetupData->cipherSetupData.cipherAlgorithm !=
CPA_CY_SYM_CIPHER_SNOW3G_UEA2) &&
(pSessionSetupData->hashSetupData.hashAlgorithm !=
CPA_CY_SYM_HASH_SNOW3G_UIA2) &&
(pSessionSetupData->cipherSetupData.cipherAlgorithm !=
CPA_CY_SYM_CIPHER_AES_CCM) &&
(pSessionSetupData->cipherSetupData.cipherAlgorithm !=
CPA_CY_SYM_CIPHER_AES_GCM) &&
(pSessionSetupData->hashSetupData.hashMode !=
CPA_CY_SYM_HASH_MODE_AUTH) &&
(pSessionSetupData->hashSetupData.hashMode !=
CPA_CY_SYM_HASH_MODE_NESTED) &&
(pSessionSetupData->partialsNotRequired == CPA_TRUE)) {
*pSessionCtxSizeInBytes = LAC_SYM_SESSION_D1_SIZE;
}
else if (((pSessionSetupData->cipherSetupData.cipherAlgorithm ==
CPA_CY_SYM_CIPHER_AES_CCM) ||
(pSessionSetupData->cipherSetupData.cipherAlgorithm ==
CPA_CY_SYM_CIPHER_AES_GCM)) &&
(pSessionSetupData->partialsNotRequired == CPA_TRUE)) {
*pSessionCtxSizeInBytes = LAC_SYM_SESSION_D2_SIZE;
}
else {
*pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE;
}
}
CpaStatus
cpaCyBufferListGetMetaSize(const CpaInstanceHandle instanceHandle_in,
Cpa32U numBuffers,
Cpa32U *pSizeInBytes)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
LAC_CHECK_NULL_PARAM(pSizeInBytes);
if (0 == numBuffers) {
numBuffers = 1;
}
*pSizeInBytes = sizeof(icp_buffer_list_desc_t) +
(sizeof(icp_flat_buffer_desc_t) * numBuffers) +
ICP_DESCRIPTOR_ALIGNMENT_BYTES;
return CPA_STATUS_SUCCESS;
}