178ee8d1cSJulian Grajkowski /* SPDX-License-Identifier: BSD-3-Clause */
278ee8d1cSJulian Grajkowski /* Copyright(c) 2007-2022 Intel Corporation */
378ee8d1cSJulian Grajkowski 
478ee8d1cSJulian Grajkowski /**
578ee8d1cSJulian Grajkowski  ***************************************************************************
678ee8d1cSJulian Grajkowski  * @file lac_sym_api.c      Implementation of the symmetric API
778ee8d1cSJulian Grajkowski  *
878ee8d1cSJulian Grajkowski  * @ingroup LacSym
978ee8d1cSJulian Grajkowski  *
1078ee8d1cSJulian Grajkowski  ***************************************************************************/
1178ee8d1cSJulian Grajkowski 
1278ee8d1cSJulian Grajkowski /*
1378ee8d1cSJulian Grajkowski *******************************************************************************
1478ee8d1cSJulian Grajkowski * Include public/global header files
1578ee8d1cSJulian Grajkowski *******************************************************************************
1678ee8d1cSJulian Grajkowski */
1778ee8d1cSJulian Grajkowski 
1878ee8d1cSJulian Grajkowski #include "cpa.h"
1978ee8d1cSJulian Grajkowski #include "cpa_cy_sym.h"
2078ee8d1cSJulian Grajkowski #include "cpa_cy_im.h"
2178ee8d1cSJulian Grajkowski 
2278ee8d1cSJulian Grajkowski #include "icp_adf_init.h"
2378ee8d1cSJulian Grajkowski #include "icp_adf_transport.h"
2478ee8d1cSJulian Grajkowski #include "icp_adf_transport_dp.h"
2578ee8d1cSJulian Grajkowski #include "icp_accel_devices.h"
2678ee8d1cSJulian Grajkowski #include "icp_adf_debug.h"
2778ee8d1cSJulian Grajkowski #include "icp_qat_fw_la.h"
2878ee8d1cSJulian Grajkowski 
2978ee8d1cSJulian Grajkowski /*
3078ee8d1cSJulian Grajkowski  ******************************************************************************
3178ee8d1cSJulian Grajkowski  * Include private header files
3278ee8d1cSJulian Grajkowski  ******************************************************************************
3378ee8d1cSJulian Grajkowski  */
3478ee8d1cSJulian Grajkowski #include "lac_common.h"
3578ee8d1cSJulian Grajkowski #include "lac_log.h"
3678ee8d1cSJulian Grajkowski #include "lac_mem.h"
3778ee8d1cSJulian Grajkowski #include "lac_mem_pools.h"
3878ee8d1cSJulian Grajkowski #include "lac_list.h"
3978ee8d1cSJulian Grajkowski #include "lac_sym.h"
4078ee8d1cSJulian Grajkowski #include "lac_sym_qat.h"
4178ee8d1cSJulian Grajkowski #include "lac_sal.h"
4278ee8d1cSJulian Grajkowski #include "lac_sal_ctrl.h"
4378ee8d1cSJulian Grajkowski #include "lac_session.h"
4478ee8d1cSJulian Grajkowski #include "lac_sym_cipher.h"
4578ee8d1cSJulian Grajkowski #include "lac_sym_hash.h"
4678ee8d1cSJulian Grajkowski #include "lac_sym_alg_chain.h"
4778ee8d1cSJulian Grajkowski #include "lac_sym_stats.h"
4878ee8d1cSJulian Grajkowski #include "lac_sym_partial.h"
4978ee8d1cSJulian Grajkowski #include "lac_sym_qat_hash_defs_lookup.h"
5078ee8d1cSJulian Grajkowski #include "lac_sym_cb.h"
5178ee8d1cSJulian Grajkowski #include "lac_buffer_desc.h"
5278ee8d1cSJulian Grajkowski #include "lac_sync.h"
5378ee8d1cSJulian Grajkowski #include "lac_hooks.h"
5478ee8d1cSJulian Grajkowski #include "lac_sal_types_crypto.h"
5578ee8d1cSJulian Grajkowski #include "sal_service_state.h"
5678ee8d1cSJulian Grajkowski 
57a977168cSMichal Gulbicki #define IS_EXT_ALG_CHAIN_UNSUPPORTED(cipherAlgorithm,                          \
58a977168cSMichal Gulbicki 				     hashAlgorithm,                            \
59a977168cSMichal Gulbicki 				     extAlgchainSupported)                     \
6078ee8d1cSJulian Grajkowski 	((((CPA_CY_SYM_CIPHER_ZUC_EEA3 == cipherAlgorithm ||                   \
6178ee8d1cSJulian Grajkowski 	    CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == cipherAlgorithm) &&               \
6278ee8d1cSJulian Grajkowski 	   CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) ||                       \
6378ee8d1cSJulian Grajkowski 	  ((CPA_CY_SYM_CIPHER_NULL == cipherAlgorithm ||                       \
6478ee8d1cSJulian Grajkowski 	    CPA_CY_SYM_CIPHER_AES_CTR == cipherAlgorithm ||                    \
6578ee8d1cSJulian Grajkowski 	    CPA_CY_SYM_CIPHER_ZUC_EEA3 == cipherAlgorithm) &&                  \
6678ee8d1cSJulian Grajkowski 	   CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) ||                    \
6778ee8d1cSJulian Grajkowski 	  ((CPA_CY_SYM_CIPHER_NULL == cipherAlgorithm ||                       \
6878ee8d1cSJulian Grajkowski 	    CPA_CY_SYM_CIPHER_AES_CTR == cipherAlgorithm ||                    \
6978ee8d1cSJulian Grajkowski 	    CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == cipherAlgorithm) &&               \
7078ee8d1cSJulian Grajkowski 	   CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm)) &&                      \
7178ee8d1cSJulian Grajkowski 	 !extAlgchainSupported)
7278ee8d1cSJulian Grajkowski 
7378ee8d1cSJulian Grajkowski /*** Local functions definitions ***/
7478ee8d1cSJulian Grajkowski static CpaStatus
7578ee8d1cSJulian Grajkowski LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer,
7678ee8d1cSJulian Grajkowski 			       const CpaBufferList *const pDstBuffer,
7778ee8d1cSJulian Grajkowski 			       const lac_session_desc_t *const pSessionDesc,
7878ee8d1cSJulian Grajkowski 			       const CpaCySymOpData *const pOpData);
7978ee8d1cSJulian Grajkowski 
80a977168cSMichal Gulbicki void LacDp_WriteRingMsgFull(CpaCySymDpOpData *pRequest,
81a977168cSMichal Gulbicki 			    icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
82a977168cSMichal Gulbicki void LacDp_WriteRingMsgOpt(CpaCySymDpOpData *pRequest,
83a977168cSMichal Gulbicki 			   icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
8478ee8d1cSJulian Grajkowski void getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData,
8578ee8d1cSJulian Grajkowski 		Cpa32U *pSessionCtxSizeInBytes);
8678ee8d1cSJulian Grajkowski 
8778ee8d1cSJulian Grajkowski /**
8878ee8d1cSJulian Grajkowski  *****************************************************************************
8978ee8d1cSJulian Grajkowski  * @ingroup LacSym
9078ee8d1cSJulian Grajkowski  *      Generic bufferList callback function.
9178ee8d1cSJulian Grajkowski  * @description
9278ee8d1cSJulian Grajkowski  *      This function is used when the API is called in synchronous mode.
9378ee8d1cSJulian Grajkowski  *      It's assumed the callbackTag holds a lac_sync_op_data_t type
9478ee8d1cSJulian Grajkowski  *      and when the callback is received, this callback shall set the
9578ee8d1cSJulian Grajkowski  *      status and opResult element of that cookie structure and
9678ee8d1cSJulian Grajkowski  *      kick the sid.
9778ee8d1cSJulian Grajkowski  *      This function may be used directly as a callback function.
9878ee8d1cSJulian Grajkowski  *
9978ee8d1cSJulian Grajkowski  * @param[in]  callbackTag       Callback Tag
10078ee8d1cSJulian Grajkowski  * @param[in]  status            Status of callback
10178ee8d1cSJulian Grajkowski  * @param[in]  operationType     Operation Type
10278ee8d1cSJulian Grajkowski  * @param[in]  pOpData           Pointer to the Op Data
10378ee8d1cSJulian Grajkowski  * @param[out] pDstBuffer        Pointer to destination buffer list
10478ee8d1cSJulian Grajkowski  * @param[out] opResult          Boolean to indicate the result of the operation
10578ee8d1cSJulian Grajkowski  *
10678ee8d1cSJulian Grajkowski  * @return void
10778ee8d1cSJulian Grajkowski  *
10878ee8d1cSJulian Grajkowski  *****************************************************************************/
10978ee8d1cSJulian Grajkowski void
LacSync_GenBufListVerifyCb(void * pCallbackTag,CpaStatus status,CpaCySymOp operationType,void * pOpData,CpaBufferList * pDstBuffer,CpaBoolean opResult)11078ee8d1cSJulian Grajkowski LacSync_GenBufListVerifyCb(void *pCallbackTag,
11178ee8d1cSJulian Grajkowski 			   CpaStatus status,
11278ee8d1cSJulian Grajkowski 			   CpaCySymOp operationType,
11378ee8d1cSJulian Grajkowski 			   void *pOpData,
11478ee8d1cSJulian Grajkowski 			   CpaBufferList *pDstBuffer,
11578ee8d1cSJulian Grajkowski 			   CpaBoolean opResult)
11678ee8d1cSJulian Grajkowski {
11778ee8d1cSJulian Grajkowski 	LacSync_GenVerifyWakeupSyncCaller(pCallbackTag, status, opResult);
11878ee8d1cSJulian Grajkowski }
11978ee8d1cSJulian Grajkowski 
12078ee8d1cSJulian Grajkowski /*
12178ee8d1cSJulian Grajkowski *******************************************************************************
12278ee8d1cSJulian Grajkowski * Define static function definitions
12378ee8d1cSJulian Grajkowski *******************************************************************************
12478ee8d1cSJulian Grajkowski */
12578ee8d1cSJulian Grajkowski /**
12678ee8d1cSJulian Grajkowski  * @ingroup LacSym
12778ee8d1cSJulian Grajkowski  * Function which perform parameter checks on session setup data
12878ee8d1cSJulian Grajkowski  *
12978ee8d1cSJulian Grajkowski  * @param[in] CpaInstanceHandle     Instance Handle
13078ee8d1cSJulian Grajkowski  * @param[in] pSessionSetupData     Pointer to session setup data
13178ee8d1cSJulian Grajkowski  *
13278ee8d1cSJulian Grajkowski  * @retval CPA_STATUS_SUCCESS        The operation succeeded
13378ee8d1cSJulian Grajkowski  * @retval CPA_STATUS_INVALID_PARAM  An invalid parameter value was found
13478ee8d1cSJulian Grajkowski  */
13578ee8d1cSJulian Grajkowski static CpaStatus
LacSymSession_ParamCheck(const CpaInstanceHandle instanceHandle,const CpaCySymSessionSetupData * pSessionSetupData)13678ee8d1cSJulian Grajkowski LacSymSession_ParamCheck(const CpaInstanceHandle instanceHandle,
13778ee8d1cSJulian Grajkowski 			 const CpaCySymSessionSetupData *pSessionSetupData)
13878ee8d1cSJulian Grajkowski {
13978ee8d1cSJulian Grajkowski 	/* initialize convenient pointers to cipher and hash contexts */
14078ee8d1cSJulian Grajkowski 	const CpaCySymCipherSetupData *const pCipherSetupData =
14178ee8d1cSJulian Grajkowski 	    (const CpaCySymCipherSetupData *)&pSessionSetupData
14278ee8d1cSJulian Grajkowski 		->cipherSetupData;
14378ee8d1cSJulian Grajkowski 	const CpaCySymHashSetupData *const pHashSetupData =
14478ee8d1cSJulian Grajkowski 	    &pSessionSetupData->hashSetupData;
14578ee8d1cSJulian Grajkowski 
14678ee8d1cSJulian Grajkowski 	CpaCySymCapabilitiesInfo capInfo;
14778ee8d1cSJulian Grajkowski 	CpaCyCapabilitiesInfo cyCapInfo;
14878ee8d1cSJulian Grajkowski 	cpaCySymQueryCapabilities(instanceHandle, &capInfo);
14978ee8d1cSJulian Grajkowski 	SalCtrl_CyQueryCapabilities(instanceHandle, &cyCapInfo);
15078ee8d1cSJulian Grajkowski 
15178ee8d1cSJulian Grajkowski 	/* Ensure cipher algorithm is correct and supported */
15278ee8d1cSJulian Grajkowski 	if ((CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
15378ee8d1cSJulian Grajkowski 	     pSessionSetupData->symOperation) ||
15478ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_OP_CIPHER == pSessionSetupData->symOperation)) {
15578ee8d1cSJulian Grajkowski 		/* Protect against value of cipher outside the bitmap
15678ee8d1cSJulian Grajkowski 		 * and check if cipher algorithm is correct
15778ee8d1cSJulian Grajkowski 		 */
158a977168cSMichal Gulbicki 		if (pCipherSetupData->cipherAlgorithm >=
159a977168cSMichal Gulbicki 		    CPA_CY_SYM_CIPHER_CAP_BITMAP_SIZE) {
16078ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("cipherAlgorithm");
16178ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
16278ee8d1cSJulian Grajkowski 		}
163a977168cSMichal Gulbicki 		if (!CPA_BITMAP_BIT_TEST(capInfo.ciphers,
164a977168cSMichal Gulbicki 					 pCipherSetupData->cipherAlgorithm)) {
165a977168cSMichal Gulbicki 			LAC_UNSUPPORTED_PARAM_LOG(
166a977168cSMichal Gulbicki 			    "UnSupported cipherAlgorithm");
167a977168cSMichal Gulbicki 			return CPA_STATUS_UNSUPPORTED;
168a977168cSMichal Gulbicki 		}
16978ee8d1cSJulian Grajkowski 	}
17078ee8d1cSJulian Grajkowski 
17178ee8d1cSJulian Grajkowski 	/* Ensure hash algorithm is correct and supported */
17278ee8d1cSJulian Grajkowski 	if ((CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
17378ee8d1cSJulian Grajkowski 	     pSessionSetupData->symOperation) ||
17478ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_OP_HASH == pSessionSetupData->symOperation)) {
17578ee8d1cSJulian Grajkowski 		/* Protect against value of hash outside the bitmap
17678ee8d1cSJulian Grajkowski 		 * and check if hash algorithm is correct
17778ee8d1cSJulian Grajkowski 		 */
178a977168cSMichal Gulbicki 		if (pHashSetupData->hashAlgorithm >=
179a977168cSMichal Gulbicki 		    CPA_CY_SYM_HASH_CAP_BITMAP_SIZE) {
18078ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("hashAlgorithm");
18178ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
18278ee8d1cSJulian Grajkowski 		}
183a977168cSMichal Gulbicki 		if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
184a977168cSMichal Gulbicki 					 pHashSetupData->hashAlgorithm)) {
185a977168cSMichal Gulbicki 			LAC_UNSUPPORTED_PARAM_LOG("UnSupported hashAlgorithm");
186a977168cSMichal Gulbicki 			return CPA_STATUS_UNSUPPORTED;
187a977168cSMichal Gulbicki 		}
18878ee8d1cSJulian Grajkowski 	}
18978ee8d1cSJulian Grajkowski 
19078ee8d1cSJulian Grajkowski 	/* ensure CCM, GCM, Kasumi, Snow3G and ZUC cipher and hash algorithms
191a977168cSMichal Gulbicki 	 * are selected together for Algorithm Chaining */
19278ee8d1cSJulian Grajkowski 	if (CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
19378ee8d1cSJulian Grajkowski 	    pSessionSetupData->symOperation) {
19478ee8d1cSJulian Grajkowski 		/* ensure both hash and cipher algorithms are POLY and CHACHA */
19578ee8d1cSJulian Grajkowski 		if (((CPA_CY_SYM_CIPHER_CHACHA ==
19678ee8d1cSJulian Grajkowski 		      pCipherSetupData->cipherAlgorithm) &&
19778ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_HASH_POLY != pHashSetupData->hashAlgorithm)) ||
19878ee8d1cSJulian Grajkowski 		    ((CPA_CY_SYM_HASH_POLY == pHashSetupData->hashAlgorithm) &&
19978ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_CIPHER_CHACHA !=
20078ee8d1cSJulian Grajkowski 		      pCipherSetupData->cipherAlgorithm))) {
20178ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
20278ee8d1cSJulian Grajkowski 			    "Invalid combination of Cipher/Hash "
20378ee8d1cSJulian Grajkowski 			    "Algorithms for CHACHA/POLY");
20478ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
20578ee8d1cSJulian Grajkowski 		}
20678ee8d1cSJulian Grajkowski 
20778ee8d1cSJulian Grajkowski 		/* ensure both hash and cipher algorithms are CCM */
20878ee8d1cSJulian Grajkowski 		if (((CPA_CY_SYM_CIPHER_AES_CCM ==
20978ee8d1cSJulian Grajkowski 		      pCipherSetupData->cipherAlgorithm) &&
21078ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_HASH_AES_CCM !=
21178ee8d1cSJulian Grajkowski 		      pHashSetupData->hashAlgorithm)) ||
21278ee8d1cSJulian Grajkowski 		    ((CPA_CY_SYM_HASH_AES_CCM ==
21378ee8d1cSJulian Grajkowski 		      pHashSetupData->hashAlgorithm) &&
21478ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_CIPHER_AES_CCM !=
21578ee8d1cSJulian Grajkowski 		      pCipherSetupData->cipherAlgorithm))) {
21678ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
21778ee8d1cSJulian Grajkowski 			    "Invalid combination of Cipher/Hash Algorithms for CCM");
21878ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
21978ee8d1cSJulian Grajkowski 		}
22078ee8d1cSJulian Grajkowski 
22178ee8d1cSJulian Grajkowski 		/* ensure both hash and cipher algorithms are GCM/GMAC */
22278ee8d1cSJulian Grajkowski 		if ((CPA_CY_SYM_CIPHER_AES_GCM ==
22378ee8d1cSJulian Grajkowski 			 pCipherSetupData->cipherAlgorithm &&
22478ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_HASH_AES_GCM !=
22578ee8d1cSJulian Grajkowski 			  pHashSetupData->hashAlgorithm &&
22678ee8d1cSJulian Grajkowski 		      CPA_CY_SYM_HASH_AES_GMAC !=
22778ee8d1cSJulian Grajkowski 			  pHashSetupData->hashAlgorithm)) ||
22878ee8d1cSJulian Grajkowski 		    ((CPA_CY_SYM_HASH_AES_GCM ==
22978ee8d1cSJulian Grajkowski 			  pHashSetupData->hashAlgorithm ||
23078ee8d1cSJulian Grajkowski 		      CPA_CY_SYM_HASH_AES_GMAC ==
23178ee8d1cSJulian Grajkowski 			  pHashSetupData->hashAlgorithm) &&
23278ee8d1cSJulian Grajkowski 		     CPA_CY_SYM_CIPHER_AES_GCM !=
23378ee8d1cSJulian Grajkowski 			 pCipherSetupData->cipherAlgorithm)) {
23478ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
23578ee8d1cSJulian Grajkowski 			    "Invalid combination of Cipher/Hash Algorithms for GCM");
23678ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
23778ee8d1cSJulian Grajkowski 		}
23878ee8d1cSJulian Grajkowski 
23978ee8d1cSJulian Grajkowski 		/* ensure both hash and cipher algorithms are Kasumi */
24078ee8d1cSJulian Grajkowski 		if (((CPA_CY_SYM_CIPHER_KASUMI_F8 ==
24178ee8d1cSJulian Grajkowski 		      pCipherSetupData->cipherAlgorithm) &&
24278ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_HASH_KASUMI_F9 !=
24378ee8d1cSJulian Grajkowski 		      pHashSetupData->hashAlgorithm)) ||
24478ee8d1cSJulian Grajkowski 		    ((CPA_CY_SYM_HASH_KASUMI_F9 ==
24578ee8d1cSJulian Grajkowski 		      pHashSetupData->hashAlgorithm) &&
24678ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_CIPHER_KASUMI_F8 !=
24778ee8d1cSJulian Grajkowski 		      pCipherSetupData->cipherAlgorithm))) {
24878ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
24978ee8d1cSJulian Grajkowski 			    "Invalid combination of Cipher/Hash Algorithms for Kasumi");
25078ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
25178ee8d1cSJulian Grajkowski 		}
25278ee8d1cSJulian Grajkowski 
25378ee8d1cSJulian Grajkowski 		if (IS_EXT_ALG_CHAIN_UNSUPPORTED(
25478ee8d1cSJulian Grajkowski 			pCipherSetupData->cipherAlgorithm,
25578ee8d1cSJulian Grajkowski 			pHashSetupData->hashAlgorithm,
25678ee8d1cSJulian Grajkowski 			cyCapInfo.extAlgchainSupported)) {
25778ee8d1cSJulian Grajkowski 			LAC_UNSUPPORTED_PARAM_LOG(
25878ee8d1cSJulian Grajkowski 			    "ExtAlgChain feature not supported");
25978ee8d1cSJulian Grajkowski 			return CPA_STATUS_UNSUPPORTED;
26078ee8d1cSJulian Grajkowski 		}
26178ee8d1cSJulian Grajkowski 
26278ee8d1cSJulian Grajkowski 		/* ensure both hash and cipher algorithms are Snow3G */
26378ee8d1cSJulian Grajkowski 		if (((CPA_CY_SYM_CIPHER_SNOW3G_UEA2 ==
26478ee8d1cSJulian Grajkowski 		      pCipherSetupData->cipherAlgorithm) &&
26578ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_HASH_SNOW3G_UIA2 !=
26678ee8d1cSJulian Grajkowski 		      pHashSetupData->hashAlgorithm)) ||
26778ee8d1cSJulian Grajkowski 		    ((CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
26878ee8d1cSJulian Grajkowski 		      pHashSetupData->hashAlgorithm) &&
26978ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_CIPHER_SNOW3G_UEA2 !=
27078ee8d1cSJulian Grajkowski 		      pCipherSetupData->cipherAlgorithm))) {
27178ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
27278ee8d1cSJulian Grajkowski 			    "Invalid combination of Cipher/Hash Algorithms for Snow3G");
27378ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
27478ee8d1cSJulian Grajkowski 		}
27578ee8d1cSJulian Grajkowski 
27678ee8d1cSJulian Grajkowski 		/* ensure both hash and cipher algorithms are ZUC */
27778ee8d1cSJulian Grajkowski 		if (((CPA_CY_SYM_CIPHER_ZUC_EEA3 ==
27878ee8d1cSJulian Grajkowski 		      pCipherSetupData->cipherAlgorithm) &&
27978ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_HASH_ZUC_EIA3 !=
28078ee8d1cSJulian Grajkowski 		      pHashSetupData->hashAlgorithm)) ||
28178ee8d1cSJulian Grajkowski 		    ((CPA_CY_SYM_HASH_ZUC_EIA3 ==
28278ee8d1cSJulian Grajkowski 		      pHashSetupData->hashAlgorithm) &&
28378ee8d1cSJulian Grajkowski 		     (CPA_CY_SYM_CIPHER_ZUC_EEA3 !=
28478ee8d1cSJulian Grajkowski 		      pCipherSetupData->cipherAlgorithm))) {
28578ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
28678ee8d1cSJulian Grajkowski 			    "Invalid combination of Cipher/Hash Algorithms for ZUC");
28778ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
28878ee8d1cSJulian Grajkowski 		}
28978ee8d1cSJulian Grajkowski 	}
29078ee8d1cSJulian Grajkowski 	/* not Algorithm Chaining so prevent CCM/GCM being selected */
29178ee8d1cSJulian Grajkowski 	else if (CPA_CY_SYM_OP_CIPHER == pSessionSetupData->symOperation) {
29278ee8d1cSJulian Grajkowski 		/* ensure cipher algorithm is not CCM or GCM */
29378ee8d1cSJulian Grajkowski 		if ((CPA_CY_SYM_CIPHER_AES_CCM ==
29478ee8d1cSJulian Grajkowski 		     pCipherSetupData->cipherAlgorithm) ||
29578ee8d1cSJulian Grajkowski 		    (CPA_CY_SYM_CIPHER_AES_GCM ==
29678ee8d1cSJulian Grajkowski 		     pCipherSetupData->cipherAlgorithm) ||
29778ee8d1cSJulian Grajkowski 		    (CPA_CY_SYM_CIPHER_CHACHA ==
29878ee8d1cSJulian Grajkowski 		     pCipherSetupData->cipherAlgorithm)) {
29978ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
30078ee8d1cSJulian Grajkowski 			    "Invalid Cipher Algorithm for non-Algorithm "
30178ee8d1cSJulian Grajkowski 			    "Chaining operation");
30278ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
30378ee8d1cSJulian Grajkowski 		}
30478ee8d1cSJulian Grajkowski 	} else if (CPA_CY_SYM_OP_HASH == pSessionSetupData->symOperation) {
30578ee8d1cSJulian Grajkowski 		/* ensure hash algorithm is not CCM or GCM/GMAC */
30678ee8d1cSJulian Grajkowski 		if ((CPA_CY_SYM_HASH_AES_CCM ==
30778ee8d1cSJulian Grajkowski 		     pHashSetupData->hashAlgorithm) ||
30878ee8d1cSJulian Grajkowski 		    (CPA_CY_SYM_HASH_AES_GCM ==
30978ee8d1cSJulian Grajkowski 		     pHashSetupData->hashAlgorithm) ||
31078ee8d1cSJulian Grajkowski 		    (CPA_CY_SYM_HASH_AES_GMAC ==
31178ee8d1cSJulian Grajkowski 		     pHashSetupData->hashAlgorithm) ||
31278ee8d1cSJulian Grajkowski 		    (CPA_CY_SYM_HASH_POLY == pHashSetupData->hashAlgorithm)) {
31378ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
31478ee8d1cSJulian Grajkowski 			    "Invalid Hash Algorithm for non-Algorithm Chaining operation");
31578ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
31678ee8d1cSJulian Grajkowski 		}
31778ee8d1cSJulian Grajkowski 	}
31878ee8d1cSJulian Grajkowski 	/* Unsupported operation. Return error */
31978ee8d1cSJulian Grajkowski 	else {
32078ee8d1cSJulian Grajkowski 		LAC_INVALID_PARAM_LOG("symOperation");
32178ee8d1cSJulian Grajkowski 		return CPA_STATUS_INVALID_PARAM;
32278ee8d1cSJulian Grajkowski 	}
32378ee8d1cSJulian Grajkowski 
32478ee8d1cSJulian Grajkowski 	/* ensure that cipher direction param is
32578ee8d1cSJulian Grajkowski 	 * valid for cipher and algchain ops */
32678ee8d1cSJulian Grajkowski 	if (CPA_CY_SYM_OP_HASH != pSessionSetupData->symOperation) {
32778ee8d1cSJulian Grajkowski 		if ((pCipherSetupData->cipherDirection !=
32878ee8d1cSJulian Grajkowski 		     CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) &&
32978ee8d1cSJulian Grajkowski 		    (pCipherSetupData->cipherDirection !=
33078ee8d1cSJulian Grajkowski 		     CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT)) {
33178ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("Invalid Cipher Direction");
33278ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
33378ee8d1cSJulian Grajkowski 		}
33478ee8d1cSJulian Grajkowski 	}
33578ee8d1cSJulian Grajkowski 
33678ee8d1cSJulian Grajkowski 	return CPA_STATUS_SUCCESS;
33778ee8d1cSJulian Grajkowski }
33878ee8d1cSJulian Grajkowski 
33978ee8d1cSJulian Grajkowski 
34078ee8d1cSJulian Grajkowski /**
34178ee8d1cSJulian Grajkowski  * @ingroup LacSym
34278ee8d1cSJulian Grajkowski  * Function which perform parameter checks on data buffers for symmetric
34378ee8d1cSJulian Grajkowski  * crypto operations
34478ee8d1cSJulian Grajkowski  *
34578ee8d1cSJulian Grajkowski  * @param[in] pSrcBuffer          Pointer to source buffer list
34678ee8d1cSJulian Grajkowski  * @param[in] pDstBuffer          Pointer to destination buffer list
34778ee8d1cSJulian Grajkowski  * @param[in] pSessionDesc        Pointer to session descriptor
34878ee8d1cSJulian Grajkowski  * @param[in] pOpData             Pointer to CryptoSymOpData.
34978ee8d1cSJulian Grajkowski  *
35078ee8d1cSJulian Grajkowski  * @retval CPA_STATUS_SUCCESS        The operation succeeded
35178ee8d1cSJulian Grajkowski  * @retval CPA_STATUS_INVALID_PARAM  An invalid parameter value was found
35278ee8d1cSJulian Grajkowski  */
35378ee8d1cSJulian Grajkowski 
35478ee8d1cSJulian Grajkowski static CpaStatus
LacSymPerform_BufferParamCheck(const CpaBufferList * const pSrcBuffer,const CpaBufferList * const pDstBuffer,const lac_session_desc_t * const pSessionDesc,const CpaCySymOpData * const pOpData)35578ee8d1cSJulian Grajkowski LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer,
35678ee8d1cSJulian Grajkowski 			       const CpaBufferList *const pDstBuffer,
35778ee8d1cSJulian Grajkowski 			       const lac_session_desc_t *const pSessionDesc,
35878ee8d1cSJulian Grajkowski 			       const CpaCySymOpData *const pOpData)
35978ee8d1cSJulian Grajkowski {
36078ee8d1cSJulian Grajkowski 	Cpa64U srcBufferLen = 0, dstBufferLen = 0;
36178ee8d1cSJulian Grajkowski 	CpaStatus status = CPA_STATUS_SUCCESS;
36278ee8d1cSJulian Grajkowski 
36378ee8d1cSJulian Grajkowski 	/* verify packet type is in correct range */
36478ee8d1cSJulian Grajkowski 	switch (pOpData->packetType) {
36578ee8d1cSJulian Grajkowski 	case CPA_CY_SYM_PACKET_TYPE_FULL:
36678ee8d1cSJulian Grajkowski 	case CPA_CY_SYM_PACKET_TYPE_PARTIAL:
36778ee8d1cSJulian Grajkowski 	case CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL:
36878ee8d1cSJulian Grajkowski 		break;
36978ee8d1cSJulian Grajkowski 	default: {
37078ee8d1cSJulian Grajkowski 		LAC_INVALID_PARAM_LOG("packetType");
37178ee8d1cSJulian Grajkowski 		return CPA_STATUS_INVALID_PARAM;
37278ee8d1cSJulian Grajkowski 	}
37378ee8d1cSJulian Grajkowski 	}
37478ee8d1cSJulian Grajkowski 
37578ee8d1cSJulian Grajkowski 	if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation &&
37678ee8d1cSJulian Grajkowski 	       CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) &&
37778ee8d1cSJulian Grajkowski 	      (0 == pOpData->messageLenToHashInBytes))) {
37878ee8d1cSJulian Grajkowski 		if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(
37978ee8d1cSJulian Grajkowski 			pSessionDesc->cipherAlgorithm,
38078ee8d1cSJulian Grajkowski 			pSessionDesc->hashAlgorithm)) {
38178ee8d1cSJulian Grajkowski 			status = LacBuffDesc_BufferListVerifyNull(
38278ee8d1cSJulian Grajkowski 			    pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT);
38378ee8d1cSJulian Grajkowski 		} else {
38478ee8d1cSJulian Grajkowski 			status = LacBuffDesc_BufferListVerify(
38578ee8d1cSJulian Grajkowski 			    pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT);
38678ee8d1cSJulian Grajkowski 		}
38778ee8d1cSJulian Grajkowski 		if (CPA_STATUS_SUCCESS != status) {
38878ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("Source buffer invalid");
38978ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
39078ee8d1cSJulian Grajkowski 		}
39178ee8d1cSJulian Grajkowski 	} else {
39278ee8d1cSJulian Grajkowski 		/* check MetaData !NULL */
39378ee8d1cSJulian Grajkowski 		if (NULL == pSrcBuffer->pPrivateMetaData) {
39478ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
39578ee8d1cSJulian Grajkowski 			    "Source buffer MetaData cannot be NULL");
39678ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
39778ee8d1cSJulian Grajkowski 		}
39878ee8d1cSJulian Grajkowski 	}
39978ee8d1cSJulian Grajkowski 
40078ee8d1cSJulian Grajkowski 	/* out of place checks */
40178ee8d1cSJulian Grajkowski 	if (pSrcBuffer != pDstBuffer) {
40278ee8d1cSJulian Grajkowski 		/* exception for this check is zero length hash requests to
40378ee8d1cSJulian Grajkowski 		 * allow */
40478ee8d1cSJulian Grajkowski 		/* for srcBufflen=DstBufferLen=0 */
40578ee8d1cSJulian Grajkowski 		if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation &&
40678ee8d1cSJulian Grajkowski 		       CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) &&
40778ee8d1cSJulian Grajkowski 		      (0 == pOpData->messageLenToHashInBytes))) {
40878ee8d1cSJulian Grajkowski 			/* Verify buffer(s) for dest packet & return packet
40978ee8d1cSJulian Grajkowski 			 * length */
41078ee8d1cSJulian Grajkowski 			if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(
41178ee8d1cSJulian Grajkowski 				pSessionDesc->cipherAlgorithm,
41278ee8d1cSJulian Grajkowski 				pSessionDesc->hashAlgorithm)) {
41378ee8d1cSJulian Grajkowski 				status = LacBuffDesc_BufferListVerifyNull(
41478ee8d1cSJulian Grajkowski 				    pDstBuffer,
41578ee8d1cSJulian Grajkowski 				    &dstBufferLen,
41678ee8d1cSJulian Grajkowski 				    LAC_NO_ALIGNMENT_SHIFT);
41778ee8d1cSJulian Grajkowski 			} else {
41878ee8d1cSJulian Grajkowski 				status = LacBuffDesc_BufferListVerify(
41978ee8d1cSJulian Grajkowski 				    pDstBuffer,
42078ee8d1cSJulian Grajkowski 				    &dstBufferLen,
42178ee8d1cSJulian Grajkowski 				    LAC_NO_ALIGNMENT_SHIFT);
42278ee8d1cSJulian Grajkowski 			}
42378ee8d1cSJulian Grajkowski 			if (CPA_STATUS_SUCCESS != status) {
42478ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG(
42578ee8d1cSJulian Grajkowski 				    "Destination buffer invalid");
42678ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
42778ee8d1cSJulian Grajkowski 			}
42878ee8d1cSJulian Grajkowski 		} else {
42978ee8d1cSJulian Grajkowski 			/* check MetaData !NULL */
43078ee8d1cSJulian Grajkowski 			if (NULL == pDstBuffer->pPrivateMetaData) {
43178ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG(
43278ee8d1cSJulian Grajkowski 				    "Dest buffer MetaData cannot be NULL");
43378ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
43478ee8d1cSJulian Grajkowski 			}
43578ee8d1cSJulian Grajkowski 		}
43678ee8d1cSJulian Grajkowski 		/* Check that src Buffer and dst Buffer Lengths are equal */
437a977168cSMichal Gulbicki 		/* CCM output needs to be longer than input buffer for appending
438a977168cSMichal Gulbicki 		 * tag*/
439a977168cSMichal Gulbicki 		if (srcBufferLen != dstBufferLen &&
440a977168cSMichal Gulbicki 		    pSessionDesc->cipherAlgorithm !=
441a977168cSMichal Gulbicki 			CPA_CY_SYM_CIPHER_AES_CCM) {
44278ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
44378ee8d1cSJulian Grajkowski 			    "Source and Dest buffer lengths need to be equal ");
44478ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
44578ee8d1cSJulian Grajkowski 		}
44678ee8d1cSJulian Grajkowski 	}
44778ee8d1cSJulian Grajkowski 
44878ee8d1cSJulian Grajkowski 	/* check for partial packet suport for the session operation */
44978ee8d1cSJulian Grajkowski 	if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) {
45078ee8d1cSJulian Grajkowski 		if (CPA_FALSE == pSessionDesc->isPartialSupported) {
45178ee8d1cSJulian Grajkowski 			/* return out here to simplify cleanup */
45278ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
45378ee8d1cSJulian Grajkowski 			    "Partial packets not supported for operation");
45478ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
45578ee8d1cSJulian Grajkowski 		} else {
45678ee8d1cSJulian Grajkowski 			/* This function checks to see if the partial packet
457a977168cSMichal Gulbicki 			 * sequence is correct */
45878ee8d1cSJulian Grajkowski 			if (CPA_STATUS_SUCCESS !=
45978ee8d1cSJulian Grajkowski 			    LacSym_PartialPacketStateCheck(
46078ee8d1cSJulian Grajkowski 				pOpData->packetType,
46178ee8d1cSJulian Grajkowski 				pSessionDesc->partialState)) {
46278ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("Partial packet Type");
46378ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
46478ee8d1cSJulian Grajkowski 			}
46578ee8d1cSJulian Grajkowski 		}
46678ee8d1cSJulian Grajkowski 	}
46778ee8d1cSJulian Grajkowski 	return CPA_STATUS_SUCCESS;
46878ee8d1cSJulian Grajkowski }
46978ee8d1cSJulian Grajkowski 
47078ee8d1cSJulian Grajkowski /** @ingroup LacSym */
47178ee8d1cSJulian Grajkowski CpaStatus
cpaCySymInitSession(const CpaInstanceHandle instanceHandle_in,const CpaCySymCbFunc pSymCb,const CpaCySymSessionSetupData * pSessionSetupData,CpaCySymSessionCtx pSessionCtx)47278ee8d1cSJulian Grajkowski cpaCySymInitSession(const CpaInstanceHandle instanceHandle_in,
47378ee8d1cSJulian Grajkowski 		    const CpaCySymCbFunc pSymCb,
47478ee8d1cSJulian Grajkowski 		    const CpaCySymSessionSetupData *pSessionSetupData,
47578ee8d1cSJulian Grajkowski 		    CpaCySymSessionCtx pSessionCtx)
47678ee8d1cSJulian Grajkowski {
47778ee8d1cSJulian Grajkowski 	CpaStatus status = CPA_STATUS_SUCCESS;
47878ee8d1cSJulian Grajkowski 	CpaInstanceHandle instanceHandle = NULL;
47978ee8d1cSJulian Grajkowski 	sal_service_t *pService = NULL;
48078ee8d1cSJulian Grajkowski 
48178ee8d1cSJulian Grajkowski 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
48278ee8d1cSJulian Grajkowski 		instanceHandle =
48378ee8d1cSJulian Grajkowski 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
48478ee8d1cSJulian Grajkowski 	} else {
48578ee8d1cSJulian Grajkowski 		instanceHandle = instanceHandle_in;
48678ee8d1cSJulian Grajkowski 	}
48778ee8d1cSJulian Grajkowski 
48878ee8d1cSJulian Grajkowski 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
48978ee8d1cSJulian Grajkowski 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
49078ee8d1cSJulian Grajkowski 				(SAL_SERVICE_TYPE_CRYPTO |
49178ee8d1cSJulian Grajkowski 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
49278ee8d1cSJulian Grajkowski 
49378ee8d1cSJulian Grajkowski 	pService = (sal_service_t *)instanceHandle;
49478ee8d1cSJulian Grajkowski 
49578ee8d1cSJulian Grajkowski 	/* check crypto service is running otherwise return an error */
49678ee8d1cSJulian Grajkowski 	SAL_RUNNING_CHECK(pService);
49778ee8d1cSJulian Grajkowski 
49878ee8d1cSJulian Grajkowski 	status = LacSym_InitSession(instanceHandle,
49978ee8d1cSJulian Grajkowski 				    pSymCb,
50078ee8d1cSJulian Grajkowski 				    pSessionSetupData,
50178ee8d1cSJulian Grajkowski 				    CPA_FALSE, /* isDPSession */
50278ee8d1cSJulian Grajkowski 				    pSessionCtx);
50378ee8d1cSJulian Grajkowski 
50478ee8d1cSJulian Grajkowski 	if (CPA_STATUS_SUCCESS == status) {
50578ee8d1cSJulian Grajkowski 		/* Increment the stats for a session registered successfully */
50678ee8d1cSJulian Grajkowski 		LAC_SYM_STAT_INC(numSessionsInitialized, instanceHandle);
50778ee8d1cSJulian Grajkowski 	} else /* if there was an error */
50878ee8d1cSJulian Grajkowski 	{
50978ee8d1cSJulian Grajkowski 		LAC_SYM_STAT_INC(numSessionErrors, instanceHandle);
51078ee8d1cSJulian Grajkowski 	}
51178ee8d1cSJulian Grajkowski 
51278ee8d1cSJulian Grajkowski 	return status;
51378ee8d1cSJulian Grajkowski }
51478ee8d1cSJulian Grajkowski 
51578ee8d1cSJulian Grajkowski CpaStatus
cpaCySymSessionInUse(CpaCySymSessionCtx pSessionCtx,CpaBoolean * pSessionInUse)51678ee8d1cSJulian Grajkowski cpaCySymSessionInUse(CpaCySymSessionCtx pSessionCtx, CpaBoolean *pSessionInUse)
51778ee8d1cSJulian Grajkowski {
51878ee8d1cSJulian Grajkowski 	CpaStatus status = CPA_STATUS_SUCCESS;
51978ee8d1cSJulian Grajkowski 	lac_session_desc_t *pSessionDesc = NULL;
52078ee8d1cSJulian Grajkowski 
52178ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSessionInUse);
52278ee8d1cSJulian Grajkowski 	LAC_CHECK_INSTANCE_HANDLE(pSessionCtx);
52378ee8d1cSJulian Grajkowski 
52478ee8d1cSJulian Grajkowski 	*pSessionInUse = CPA_FALSE;
52578ee8d1cSJulian Grajkowski 
52678ee8d1cSJulian Grajkowski 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx);
52778ee8d1cSJulian Grajkowski 
52878ee8d1cSJulian Grajkowski 	/* If there are pending requests */
52978ee8d1cSJulian Grajkowski 	if (pSessionDesc->isDPSession) {
53078ee8d1cSJulian Grajkowski 		if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount)))
53178ee8d1cSJulian Grajkowski 			*pSessionInUse = CPA_TRUE;
53278ee8d1cSJulian Grajkowski 	} else {
53378ee8d1cSJulian Grajkowski 		if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount)))
53478ee8d1cSJulian Grajkowski 			*pSessionInUse = CPA_TRUE;
53578ee8d1cSJulian Grajkowski 	}
53678ee8d1cSJulian Grajkowski 
53778ee8d1cSJulian Grajkowski 	return status;
53878ee8d1cSJulian Grajkowski }
53978ee8d1cSJulian Grajkowski 
54078ee8d1cSJulian Grajkowski CpaStatus
LacSym_InitSession(const CpaInstanceHandle instanceHandle,const CpaCySymCbFunc pSymCb,const CpaCySymSessionSetupData * pSessionSetupData,const CpaBoolean isDPSession,CpaCySymSessionCtx pSessionCtx)54178ee8d1cSJulian Grajkowski LacSym_InitSession(const CpaInstanceHandle instanceHandle,
54278ee8d1cSJulian Grajkowski 		   const CpaCySymCbFunc pSymCb,
54378ee8d1cSJulian Grajkowski 		   const CpaCySymSessionSetupData *pSessionSetupData,
54478ee8d1cSJulian Grajkowski 		   const CpaBoolean isDPSession,
54578ee8d1cSJulian Grajkowski 		   CpaCySymSessionCtx pSessionCtx)
54678ee8d1cSJulian Grajkowski {
54778ee8d1cSJulian Grajkowski 	CpaStatus status = CPA_STATUS_SUCCESS;
54878ee8d1cSJulian Grajkowski 	lac_session_desc_t *pSessionDesc = NULL;
54978ee8d1cSJulian Grajkowski 	Cpa32U sessionCtxSizeInBytes = 0;
55078ee8d1cSJulian Grajkowski 	CpaPhysicalAddr physAddress = 0;
55178ee8d1cSJulian Grajkowski 	CpaPhysicalAddr physAddressAligned = 0;
55278ee8d1cSJulian Grajkowski 	sal_service_t *pService = NULL;
55378ee8d1cSJulian Grajkowski 	const CpaCySymCipherSetupData *pCipherSetupData = NULL;
55478ee8d1cSJulian Grajkowski 	const CpaCySymHashSetupData *pHashSetupData = NULL;
55578ee8d1cSJulian Grajkowski 
55678ee8d1cSJulian Grajkowski 	/* Instance param checking done by calling function */
55778ee8d1cSJulian Grajkowski 
55878ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSessionSetupData);
55978ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSessionCtx);
56078ee8d1cSJulian Grajkowski 	status = LacSymSession_ParamCheck(instanceHandle, pSessionSetupData);
56178ee8d1cSJulian Grajkowski 	LAC_CHECK_STATUS(status);
56278ee8d1cSJulian Grajkowski 
56378ee8d1cSJulian Grajkowski 	/* set the session priority for QAT AL*/
56478ee8d1cSJulian Grajkowski 	if ((CPA_CY_PRIORITY_HIGH == pSessionSetupData->sessionPriority) ||
56578ee8d1cSJulian Grajkowski 	    (CPA_CY_PRIORITY_NORMAL == pSessionSetupData->sessionPriority)) {
56678ee8d1cSJulian Grajkowski 		// do nothing - clean up this code. use RANGE macro
56778ee8d1cSJulian Grajkowski 	} else {
56878ee8d1cSJulian Grajkowski 		LAC_INVALID_PARAM_LOG("sessionPriority");
56978ee8d1cSJulian Grajkowski 		return CPA_STATUS_INVALID_PARAM;
57078ee8d1cSJulian Grajkowski 	}
57178ee8d1cSJulian Grajkowski 
57278ee8d1cSJulian Grajkowski 
57378ee8d1cSJulian Grajkowski 	pCipherSetupData = &pSessionSetupData->cipherSetupData;
57478ee8d1cSJulian Grajkowski 	pHashSetupData = &pSessionSetupData->hashSetupData;
57578ee8d1cSJulian Grajkowski 
57678ee8d1cSJulian Grajkowski 	pService = (sal_service_t *)instanceHandle;
57778ee8d1cSJulian Grajkowski 
57878ee8d1cSJulian Grajkowski 	/* Re-align the session structure to 64 byte alignment */
57978ee8d1cSJulian Grajkowski 	physAddress =
58078ee8d1cSJulian Grajkowski 	    LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService),
58178ee8d1cSJulian Grajkowski 					 (Cpa8U *)pSessionCtx + sizeof(void *));
58278ee8d1cSJulian Grajkowski 
58378ee8d1cSJulian Grajkowski 	if (0 == physAddress) {
58478ee8d1cSJulian Grajkowski 		LAC_LOG_ERROR(
585a977168cSMichal Gulbicki 		    "Unable to get the physical address of the session\n");
58678ee8d1cSJulian Grajkowski 		return CPA_STATUS_FAIL;
58778ee8d1cSJulian Grajkowski 	}
58878ee8d1cSJulian Grajkowski 
58978ee8d1cSJulian Grajkowski 	physAddressAligned =
59078ee8d1cSJulian Grajkowski 	    LAC_ALIGN_POW2_ROUNDUP(physAddress, LAC_64BYTE_ALIGNMENT);
59178ee8d1cSJulian Grajkowski 
59278ee8d1cSJulian Grajkowski 	pSessionDesc = (lac_session_desc_t *)
59378ee8d1cSJulian Grajkowski 	    /* Move the session pointer by the physical offset
59478ee8d1cSJulian Grajkowski 	    between aligned and unaligned memory */
59578ee8d1cSJulian Grajkowski 	    ((Cpa8U *)pSessionCtx + sizeof(void *) +
59678ee8d1cSJulian Grajkowski 	     (physAddressAligned - physAddress));
59778ee8d1cSJulian Grajkowski 
59878ee8d1cSJulian Grajkowski 	/* save the aligned pointer in the first bytes (size of unsigned long)
59978ee8d1cSJulian Grajkowski 	 * of the session memory */
60078ee8d1cSJulian Grajkowski 	*((LAC_ARCH_UINT *)pSessionCtx) = (LAC_ARCH_UINT)pSessionDesc;
60178ee8d1cSJulian Grajkowski 
60278ee8d1cSJulian Grajkowski 	/* start off with a clean session */
60378ee8d1cSJulian Grajkowski 	/* Choose Session Context size */
60478ee8d1cSJulian Grajkowski 	getCtxSize(pSessionSetupData, &sessionCtxSizeInBytes);
60578ee8d1cSJulian Grajkowski 	switch (sessionCtxSizeInBytes) {
60678ee8d1cSJulian Grajkowski 	case LAC_SYM_SESSION_D1_SIZE:
60778ee8d1cSJulian Grajkowski 		memset(pSessionDesc, 0, sizeof(lac_session_desc_d1_t));
60878ee8d1cSJulian Grajkowski 		break;
60978ee8d1cSJulian Grajkowski 	case LAC_SYM_SESSION_D2_SIZE:
61078ee8d1cSJulian Grajkowski 		memset(pSessionDesc, 0, sizeof(lac_session_desc_d2_t));
61178ee8d1cSJulian Grajkowski 		break;
61278ee8d1cSJulian Grajkowski 	default:
61378ee8d1cSJulian Grajkowski 		memset(pSessionDesc, 0, sizeof(lac_session_desc_t));
61478ee8d1cSJulian Grajkowski 		break;
61578ee8d1cSJulian Grajkowski 	}
61678ee8d1cSJulian Grajkowski 
61778ee8d1cSJulian Grajkowski 	/* Setup content descriptor info structure
61878ee8d1cSJulian Grajkowski 	 * assumption that content descriptor is the first field in
61978ee8d1cSJulian Grajkowski 	 * in the session descriptor */
62078ee8d1cSJulian Grajkowski 	pSessionDesc->contentDescInfo.pData = (Cpa8U *)pSessionDesc;
62178ee8d1cSJulian Grajkowski 	pSessionDesc->contentDescInfo.hardwareSetupBlockPhys =
62278ee8d1cSJulian Grajkowski 	    physAddressAligned;
62378ee8d1cSJulian Grajkowski 
62478ee8d1cSJulian Grajkowski 	pSessionDesc->contentDescOptimisedInfo.pData =
62578ee8d1cSJulian Grajkowski 	    ((Cpa8U *)pSessionDesc + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE);
62678ee8d1cSJulian Grajkowski 	pSessionDesc->contentDescOptimisedInfo.hardwareSetupBlockPhys =
62778ee8d1cSJulian Grajkowski 	    (physAddressAligned + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE);
62878ee8d1cSJulian Grajkowski 
62978ee8d1cSJulian Grajkowski 	/* Set the Common Session Information */
63078ee8d1cSJulian Grajkowski 	pSessionDesc->symOperation = pSessionSetupData->symOperation;
63178ee8d1cSJulian Grajkowski 
63278ee8d1cSJulian Grajkowski 	if (CPA_FALSE == isDPSession) {
63378ee8d1cSJulian Grajkowski 		/* For asynchronous - use the user supplied callback
63478ee8d1cSJulian Grajkowski 		 * for synchronous - use the internal synchronous callback */
63578ee8d1cSJulian Grajkowski 		pSessionDesc->pSymCb = ((void *)NULL != (void *)pSymCb) ?
63678ee8d1cSJulian Grajkowski 			  pSymCb :
63778ee8d1cSJulian Grajkowski 			  LacSync_GenBufListVerifyCb;
63878ee8d1cSJulian Grajkowski 	}
63978ee8d1cSJulian Grajkowski 
64078ee8d1cSJulian Grajkowski 	pSessionDesc->isDPSession = isDPSession;
64178ee8d1cSJulian Grajkowski 	if ((CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm) ||
64278ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) ||
64378ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_HASH_AES_CCM == pHashSetupData->hashAlgorithm) ||
64478ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_CIPHER_CHACHA == pCipherSetupData->cipherAlgorithm) ||
64578ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_CIPHER_ARC4 == pCipherSetupData->cipherAlgorithm)) {
64678ee8d1cSJulian Grajkowski 		pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgFull;
64778ee8d1cSJulian Grajkowski 	} else {
64878ee8d1cSJulian Grajkowski 		pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgOpt;
64978ee8d1cSJulian Grajkowski 	}
65078ee8d1cSJulian Grajkowski 
65178ee8d1cSJulian Grajkowski 	if (CPA_STATUS_SUCCESS == status) {
65278ee8d1cSJulian Grajkowski 		/* Session set up via API call (not internal one) */
65378ee8d1cSJulian Grajkowski 		/* Services such as DRBG call the crypto api as part of their
654a977168cSMichal Gulbicki 		 * service hence the need to for the flag, it is needed to
655a977168cSMichal Gulbicki 		 * distinguish between an internal and external session.
65678ee8d1cSJulian Grajkowski 		 */
65778ee8d1cSJulian Grajkowski 		pSessionDesc->internalSession = CPA_FALSE;
65878ee8d1cSJulian Grajkowski 
65978ee8d1cSJulian Grajkowski 		status = LacAlgChain_SessionInit(instanceHandle,
66078ee8d1cSJulian Grajkowski 						 pSessionSetupData,
66178ee8d1cSJulian Grajkowski 						 pSessionDesc);
66278ee8d1cSJulian Grajkowski 	}
66378ee8d1cSJulian Grajkowski 	return status;
66478ee8d1cSJulian Grajkowski }
66578ee8d1cSJulian Grajkowski 
66678ee8d1cSJulian Grajkowski /** @ingroup LacSym */
66778ee8d1cSJulian Grajkowski CpaStatus
cpaCySymRemoveSession(const CpaInstanceHandle instanceHandle_in,CpaCySymSessionCtx pSessionCtx)66878ee8d1cSJulian Grajkowski cpaCySymRemoveSession(const CpaInstanceHandle instanceHandle_in,
66978ee8d1cSJulian Grajkowski 		      CpaCySymSessionCtx pSessionCtx)
67078ee8d1cSJulian Grajkowski {
67178ee8d1cSJulian Grajkowski 	lac_session_desc_t *pSessionDesc = NULL;
67278ee8d1cSJulian Grajkowski 	CpaStatus status = CPA_STATUS_SUCCESS;
67378ee8d1cSJulian Grajkowski 	CpaInstanceHandle instanceHandle = NULL;
67478ee8d1cSJulian Grajkowski 	Cpa64U numPendingRequests = 0;
67578ee8d1cSJulian Grajkowski 
67678ee8d1cSJulian Grajkowski 
67778ee8d1cSJulian Grajkowski 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
67878ee8d1cSJulian Grajkowski 		instanceHandle =
67978ee8d1cSJulian Grajkowski 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
68078ee8d1cSJulian Grajkowski 	} else {
68178ee8d1cSJulian Grajkowski 		instanceHandle = instanceHandle_in;
68278ee8d1cSJulian Grajkowski 	}
68378ee8d1cSJulian Grajkowski 
68478ee8d1cSJulian Grajkowski 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
68578ee8d1cSJulian Grajkowski 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
68678ee8d1cSJulian Grajkowski 				(SAL_SERVICE_TYPE_CRYPTO |
68778ee8d1cSJulian Grajkowski 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
68878ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSessionCtx);
68978ee8d1cSJulian Grajkowski 
69078ee8d1cSJulian Grajkowski 	/* check crypto service is running otherwise return an error */
69178ee8d1cSJulian Grajkowski 	SAL_RUNNING_CHECK(instanceHandle);
69278ee8d1cSJulian Grajkowski 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx);
69378ee8d1cSJulian Grajkowski 
69478ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSessionDesc);
69578ee8d1cSJulian Grajkowski 
69678ee8d1cSJulian Grajkowski 	if (CPA_TRUE == pSessionDesc->isDPSession) {
69778ee8d1cSJulian Grajkowski 		/*
69878ee8d1cSJulian Grajkowski 		 * Based on one instance, we can initialize multiple sessions.
69978ee8d1cSJulian Grajkowski 		 * For example, we can initialize the session "X" and session
700a977168cSMichal Gulbicki 		 * "Y" with the same instance "A". If there is no operation
701a977168cSMichal Gulbicki 		 * pending for session "X", we can remove the session "X".
70278ee8d1cSJulian Grajkowski 		 *
70378ee8d1cSJulian Grajkowski 		 * Now we only check the @pSessionDesc->pendingDpCbCount, if it
704a977168cSMichal Gulbicki 		 * becomes zero, we can remove the session.
70578ee8d1cSJulian Grajkowski 		 *
70678ee8d1cSJulian Grajkowski 		 * Why?
70778ee8d1cSJulian Grajkowski 		 *   (1) We increase it in the cpaCySymDpEnqueueOp/
70878ee8d1cSJulian Grajkowski 		 *       cpaCySymDpEnqueueOpBatch.
70978ee8d1cSJulian Grajkowski 		 *   (2) We decrease it in the LacSymCb_ProcessCallback.
71078ee8d1cSJulian Grajkowski 		 *
71178ee8d1cSJulian Grajkowski 		 * If the @pSessionDesc->pendingDpCbCount becomes zero, it means
71278ee8d1cSJulian Grajkowski 		 * there is no operation pending for the session "X" anymore, so
713a977168cSMichal Gulbicki 		 * we can remove this session. Maybe there is still some
714a977168cSMichal Gulbicki 		 * requests left in the instance's ring
715a977168cSMichal Gulbicki 		 * (icp_adf_queueDataToSend() returns true), but the request
716a977168cSMichal Gulbicki 		 * does not belong to "X", it belongs to session "Y".
71778ee8d1cSJulian Grajkowski 		 */
71878ee8d1cSJulian Grajkowski 		numPendingRequests =
71978ee8d1cSJulian Grajkowski 		    qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount));
72078ee8d1cSJulian Grajkowski 	} else {
72178ee8d1cSJulian Grajkowski 		numPendingRequests =
72278ee8d1cSJulian Grajkowski 		    qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount));
72378ee8d1cSJulian Grajkowski 	}
72478ee8d1cSJulian Grajkowski 
72578ee8d1cSJulian Grajkowski 	/* If there are pending requests */
72678ee8d1cSJulian Grajkowski 	if (0 != numPendingRequests) {
72778ee8d1cSJulian Grajkowski 		QAT_UTILS_LOG("There are %llu requests pending\n",
72878ee8d1cSJulian Grajkowski 			      (unsigned long long)numPendingRequests);
72978ee8d1cSJulian Grajkowski 		status = CPA_STATUS_RETRY;
73078ee8d1cSJulian Grajkowski 		if (CPA_TRUE == pSessionDesc->isDPSession) {
73178ee8d1cSJulian Grajkowski 			/* Need to update tail if messages queue on tx hi ring
732a977168cSMichal Gulbicki 			 for data plane api */
73378ee8d1cSJulian Grajkowski 			icp_comms_trans_handle trans_handle =
73478ee8d1cSJulian Grajkowski 			    ((sal_crypto_service_t *)instanceHandle)
73578ee8d1cSJulian Grajkowski 				->trans_handle_sym_tx;
73678ee8d1cSJulian Grajkowski 
73778ee8d1cSJulian Grajkowski 			if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
73878ee8d1cSJulian Grajkowski 				/* process the remaining messages in the ring */
73978ee8d1cSJulian Grajkowski 				QAT_UTILS_LOG("Submitting enqueued requests\n");
74078ee8d1cSJulian Grajkowski 				/*
74178ee8d1cSJulian Grajkowski 				 * SalQatMsg_updateQueueTail
74278ee8d1cSJulian Grajkowski 				 */
74378ee8d1cSJulian Grajkowski 				SalQatMsg_updateQueueTail(trans_handle);
74478ee8d1cSJulian Grajkowski 				return status;
74578ee8d1cSJulian Grajkowski 			}
74678ee8d1cSJulian Grajkowski 		}
74778ee8d1cSJulian Grajkowski 	}
74878ee8d1cSJulian Grajkowski 	if (CPA_STATUS_SUCCESS == status) {
749a977168cSMichal Gulbicki 		LAC_SPINLOCK_DESTROY(&pSessionDesc->requestQueueLock);
75078ee8d1cSJulian Grajkowski 		if (CPA_FALSE == pSessionDesc->isDPSession) {
75178ee8d1cSJulian Grajkowski 			LAC_SYM_STAT_INC(numSessionsRemoved, instanceHandle);
75278ee8d1cSJulian Grajkowski 		}
75378ee8d1cSJulian Grajkowski 	} else if (CPA_FALSE == pSessionDesc->isDPSession) {
75478ee8d1cSJulian Grajkowski 		LAC_SYM_STAT_INC(numSessionErrors, instanceHandle);
75578ee8d1cSJulian Grajkowski 	}
75678ee8d1cSJulian Grajkowski 	return status;
75778ee8d1cSJulian Grajkowski }
75878ee8d1cSJulian Grajkowski 
75978ee8d1cSJulian Grajkowski /** @ingroup LacSym */
76078ee8d1cSJulian Grajkowski static CpaStatus
LacSym_Perform(const CpaInstanceHandle instanceHandle,void * callbackTag,const CpaCySymOpData * pOpData,const CpaBufferList * pSrcBuffer,CpaBufferList * pDstBuffer,CpaBoolean * pVerifyResult,CpaBoolean isAsyncMode)76178ee8d1cSJulian Grajkowski LacSym_Perform(const CpaInstanceHandle instanceHandle,
76278ee8d1cSJulian Grajkowski 	       void *callbackTag,
76378ee8d1cSJulian Grajkowski 	       const CpaCySymOpData *pOpData,
76478ee8d1cSJulian Grajkowski 	       const CpaBufferList *pSrcBuffer,
76578ee8d1cSJulian Grajkowski 	       CpaBufferList *pDstBuffer,
76678ee8d1cSJulian Grajkowski 	       CpaBoolean *pVerifyResult,
76778ee8d1cSJulian Grajkowski 	       CpaBoolean isAsyncMode)
76878ee8d1cSJulian Grajkowski {
76978ee8d1cSJulian Grajkowski 	lac_session_desc_t *pSessionDesc = NULL;
77078ee8d1cSJulian Grajkowski 	CpaStatus status = CPA_STATUS_SUCCESS;
77178ee8d1cSJulian Grajkowski 
77278ee8d1cSJulian Grajkowski 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
77378ee8d1cSJulian Grajkowski 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
77478ee8d1cSJulian Grajkowski 				(SAL_SERVICE_TYPE_CRYPTO |
77578ee8d1cSJulian Grajkowski 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
77678ee8d1cSJulian Grajkowski 	/* check crypto service is running otherwise return an error */
77778ee8d1cSJulian Grajkowski 	SAL_RUNNING_CHECK(instanceHandle);
77878ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pOpData);
77978ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pOpData->sessionCtx);
78078ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSrcBuffer);
78178ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pDstBuffer);
78278ee8d1cSJulian Grajkowski 
78378ee8d1cSJulian Grajkowski 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pOpData->sessionCtx);
78478ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSessionDesc);
78578ee8d1cSJulian Grajkowski 
78678ee8d1cSJulian Grajkowski 	/*check whether Payload size is zero for CHACHA-POLY*/
78778ee8d1cSJulian Grajkowski 	if ((CPA_CY_SYM_CIPHER_CHACHA == pSessionDesc->cipherAlgorithm) &&
78878ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_HASH_POLY == pSessionDesc->hashAlgorithm) &&
78978ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
79078ee8d1cSJulian Grajkowski 		if (!pOpData->messageLenToCipherInBytes) {
79178ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
79278ee8d1cSJulian Grajkowski 			    "Invalid messageLenToCipherInBytes for CHACHA-POLY");
79378ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
79478ee8d1cSJulian Grajkowski 		}
79578ee8d1cSJulian Grajkowski 	}
79678ee8d1cSJulian Grajkowski 
79778ee8d1cSJulian Grajkowski 
79878ee8d1cSJulian Grajkowski 	/* If synchronous Operation - Callback function stored in the session
79978ee8d1cSJulian Grajkowski 	 * descriptor so a flag is set in the perform to indicate that
80078ee8d1cSJulian Grajkowski 	 * the perform is being re-called for the synchronous operation */
80178ee8d1cSJulian Grajkowski 	if ((LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb) &&
80278ee8d1cSJulian Grajkowski 	    isAsyncMode == CPA_TRUE) {
80378ee8d1cSJulian Grajkowski 		CpaBoolean opResult = CPA_FALSE;
80478ee8d1cSJulian Grajkowski 		lac_sync_op_data_t *pSyncCallbackData = NULL;
80578ee8d1cSJulian Grajkowski 
80678ee8d1cSJulian Grajkowski 		status = LacSync_CreateSyncCookie(&pSyncCallbackData);
80778ee8d1cSJulian Grajkowski 
80878ee8d1cSJulian Grajkowski 		if (CPA_STATUS_SUCCESS == status) {
80978ee8d1cSJulian Grajkowski 			status = LacSym_Perform(instanceHandle,
81078ee8d1cSJulian Grajkowski 						pSyncCallbackData,
81178ee8d1cSJulian Grajkowski 						pOpData,
81278ee8d1cSJulian Grajkowski 						pSrcBuffer,
81378ee8d1cSJulian Grajkowski 						pDstBuffer,
81478ee8d1cSJulian Grajkowski 						pVerifyResult,
81578ee8d1cSJulian Grajkowski 						CPA_FALSE);
81678ee8d1cSJulian Grajkowski 		} else {
81778ee8d1cSJulian Grajkowski 			/* Failure allocating sync cookie */
81878ee8d1cSJulian Grajkowski 			LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle);
81978ee8d1cSJulian Grajkowski 			return status;
82078ee8d1cSJulian Grajkowski 		}
82178ee8d1cSJulian Grajkowski 
82278ee8d1cSJulian Grajkowski 		if (CPA_STATUS_SUCCESS == status) {
82378ee8d1cSJulian Grajkowski 			CpaStatus syncStatus = CPA_STATUS_SUCCESS;
82478ee8d1cSJulian Grajkowski 			syncStatus = LacSync_WaitForCallback(
82578ee8d1cSJulian Grajkowski 			    pSyncCallbackData,
82678ee8d1cSJulian Grajkowski 			    LAC_SYM_SYNC_CALLBACK_TIMEOUT,
82778ee8d1cSJulian Grajkowski 			    &status,
82878ee8d1cSJulian Grajkowski 			    &opResult);
82978ee8d1cSJulian Grajkowski 			/* If callback doesn't come back */
83078ee8d1cSJulian Grajkowski 			if (CPA_STATUS_SUCCESS != syncStatus) {
83178ee8d1cSJulian Grajkowski 				LAC_SYM_STAT_INC(numSymOpCompletedErrors,
83278ee8d1cSJulian Grajkowski 						 instanceHandle);
83378ee8d1cSJulian Grajkowski 				LAC_LOG_ERROR("Callback timed out");
83478ee8d1cSJulian Grajkowski 				status = syncStatus;
83578ee8d1cSJulian Grajkowski 			}
83678ee8d1cSJulian Grajkowski 		} else {
83778ee8d1cSJulian Grajkowski 			/* As the Request was not sent the Callback will never
83878ee8d1cSJulian Grajkowski 			 * be called, so need to indicate that we're finished
83978ee8d1cSJulian Grajkowski 			 * with cookie so it can be destroyed. */
84078ee8d1cSJulian Grajkowski 			LacSync_SetSyncCookieComplete(pSyncCallbackData);
84178ee8d1cSJulian Grajkowski 		}
84278ee8d1cSJulian Grajkowski 
84378ee8d1cSJulian Grajkowski 		if (CPA_STATUS_SUCCESS == status) {
84478ee8d1cSJulian Grajkowski 			if (NULL != pVerifyResult) {
84578ee8d1cSJulian Grajkowski 				*pVerifyResult = opResult;
84678ee8d1cSJulian Grajkowski 			}
84778ee8d1cSJulian Grajkowski 		}
84878ee8d1cSJulian Grajkowski 
84978ee8d1cSJulian Grajkowski 		LacSync_DestroySyncCookie(&pSyncCallbackData);
85078ee8d1cSJulian Grajkowski 		return status;
85178ee8d1cSJulian Grajkowski 	}
85278ee8d1cSJulian Grajkowski 
85378ee8d1cSJulian Grajkowski 	status =
85478ee8d1cSJulian Grajkowski 	    LacSymPerform_BufferParamCheck((const CpaBufferList *)pSrcBuffer,
85578ee8d1cSJulian Grajkowski 					   pDstBuffer,
85678ee8d1cSJulian Grajkowski 					   pSessionDesc,
85778ee8d1cSJulian Grajkowski 					   pOpData);
85878ee8d1cSJulian Grajkowski 	LAC_CHECK_STATUS(status);
85978ee8d1cSJulian Grajkowski 
86078ee8d1cSJulian Grajkowski 	if ((!pSessionDesc->digestIsAppended) &&
86178ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
86278ee8d1cSJulian Grajkowski 		/* Check that pDigestResult is not NULL */
86378ee8d1cSJulian Grajkowski 		LAC_CHECK_NULL_PARAM(pOpData->pDigestResult);
86478ee8d1cSJulian Grajkowski 	}
86578ee8d1cSJulian Grajkowski 
86678ee8d1cSJulian Grajkowski 	status = LacAlgChain_Perform(instanceHandle,
86778ee8d1cSJulian Grajkowski 				     pSessionDesc,
86878ee8d1cSJulian Grajkowski 				     callbackTag,
86978ee8d1cSJulian Grajkowski 				     pOpData,
87078ee8d1cSJulian Grajkowski 				     pSrcBuffer,
87178ee8d1cSJulian Grajkowski 				     pDstBuffer,
87278ee8d1cSJulian Grajkowski 				     pVerifyResult);
87378ee8d1cSJulian Grajkowski 
87478ee8d1cSJulian Grajkowski 	if (CPA_STATUS_SUCCESS == status) {
87578ee8d1cSJulian Grajkowski 		/* check for partial packet suport for the session operation */
87678ee8d1cSJulian Grajkowski 		if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) {
87778ee8d1cSJulian Grajkowski 			LacSym_PartialPacketStateUpdate(
87878ee8d1cSJulian Grajkowski 			    pOpData->packetType, &pSessionDesc->partialState);
87978ee8d1cSJulian Grajkowski 		}
88078ee8d1cSJulian Grajkowski 		/* increment #requests stat */
88178ee8d1cSJulian Grajkowski 		LAC_SYM_STAT_INC(numSymOpRequests, instanceHandle);
88278ee8d1cSJulian Grajkowski 	}
88378ee8d1cSJulian Grajkowski 	/* Retry also results in the errors stat been incremented */
88478ee8d1cSJulian Grajkowski 	else {
88578ee8d1cSJulian Grajkowski 		/* increment #errors stat */
88678ee8d1cSJulian Grajkowski 		LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle);
88778ee8d1cSJulian Grajkowski 	}
88878ee8d1cSJulian Grajkowski 	return status;
88978ee8d1cSJulian Grajkowski }
89078ee8d1cSJulian Grajkowski 
89178ee8d1cSJulian Grajkowski /** @ingroup LacSym */
89278ee8d1cSJulian Grajkowski CpaStatus
cpaCySymPerformOp(const CpaInstanceHandle instanceHandle_in,void * callbackTag,const CpaCySymOpData * pOpData,const CpaBufferList * pSrcBuffer,CpaBufferList * pDstBuffer,CpaBoolean * pVerifyResult)89378ee8d1cSJulian Grajkowski cpaCySymPerformOp(const CpaInstanceHandle instanceHandle_in,
89478ee8d1cSJulian Grajkowski 		  void *callbackTag,
89578ee8d1cSJulian Grajkowski 		  const CpaCySymOpData *pOpData,
89678ee8d1cSJulian Grajkowski 		  const CpaBufferList *pSrcBuffer,
89778ee8d1cSJulian Grajkowski 		  CpaBufferList *pDstBuffer,
89878ee8d1cSJulian Grajkowski 		  CpaBoolean *pVerifyResult)
89978ee8d1cSJulian Grajkowski {
90078ee8d1cSJulian Grajkowski 	CpaInstanceHandle instanceHandle = NULL;
90178ee8d1cSJulian Grajkowski 
90278ee8d1cSJulian Grajkowski 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
90378ee8d1cSJulian Grajkowski 		instanceHandle =
90478ee8d1cSJulian Grajkowski 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
90578ee8d1cSJulian Grajkowski 	} else {
90678ee8d1cSJulian Grajkowski 		instanceHandle = instanceHandle_in;
90778ee8d1cSJulian Grajkowski 	}
90878ee8d1cSJulian Grajkowski 
90978ee8d1cSJulian Grajkowski 	return LacSym_Perform(instanceHandle,
91078ee8d1cSJulian Grajkowski 			      callbackTag,
91178ee8d1cSJulian Grajkowski 			      pOpData,
91278ee8d1cSJulian Grajkowski 			      pSrcBuffer,
91378ee8d1cSJulian Grajkowski 			      pDstBuffer,
91478ee8d1cSJulian Grajkowski 			      pVerifyResult,
91578ee8d1cSJulian Grajkowski 			      CPA_TRUE);
91678ee8d1cSJulian Grajkowski }
91778ee8d1cSJulian Grajkowski 
91878ee8d1cSJulian Grajkowski /** @ingroup LacSym */
91978ee8d1cSJulian Grajkowski CpaStatus
cpaCySymQueryStats(const CpaInstanceHandle instanceHandle_in,struct _CpaCySymStats * pSymStats)92078ee8d1cSJulian Grajkowski cpaCySymQueryStats(const CpaInstanceHandle instanceHandle_in,
92178ee8d1cSJulian Grajkowski 		   struct _CpaCySymStats *pSymStats)
92278ee8d1cSJulian Grajkowski {
92378ee8d1cSJulian Grajkowski 
92478ee8d1cSJulian Grajkowski 	CpaInstanceHandle instanceHandle = NULL;
92578ee8d1cSJulian Grajkowski 
92678ee8d1cSJulian Grajkowski 
92778ee8d1cSJulian Grajkowski 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
92878ee8d1cSJulian Grajkowski 		instanceHandle =
92978ee8d1cSJulian Grajkowski 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
93078ee8d1cSJulian Grajkowski 	} else {
93178ee8d1cSJulian Grajkowski 		instanceHandle = instanceHandle_in;
93278ee8d1cSJulian Grajkowski 	}
93378ee8d1cSJulian Grajkowski 
93478ee8d1cSJulian Grajkowski 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
93578ee8d1cSJulian Grajkowski 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
93678ee8d1cSJulian Grajkowski 				(SAL_SERVICE_TYPE_CRYPTO |
93778ee8d1cSJulian Grajkowski 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
93878ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSymStats);
93978ee8d1cSJulian Grajkowski 
94078ee8d1cSJulian Grajkowski 	/* check if crypto service is running
94178ee8d1cSJulian Grajkowski 	 * otherwise return an error */
94278ee8d1cSJulian Grajkowski 	SAL_RUNNING_CHECK(instanceHandle);
94378ee8d1cSJulian Grajkowski 
94478ee8d1cSJulian Grajkowski 	/* copy the fields from the internal structure into the api defined
94578ee8d1cSJulian Grajkowski 	 * structure */
94678ee8d1cSJulian Grajkowski 	LacSym_Stats32CopyGet(instanceHandle, pSymStats);
94778ee8d1cSJulian Grajkowski 	return CPA_STATUS_SUCCESS;
94878ee8d1cSJulian Grajkowski }
94978ee8d1cSJulian Grajkowski 
95078ee8d1cSJulian Grajkowski /** @ingroup LacSym */
95178ee8d1cSJulian Grajkowski CpaStatus
cpaCySymQueryStats64(const CpaInstanceHandle instanceHandle_in,CpaCySymStats64 * pSymStats)95278ee8d1cSJulian Grajkowski cpaCySymQueryStats64(const CpaInstanceHandle instanceHandle_in,
95378ee8d1cSJulian Grajkowski 		     CpaCySymStats64 *pSymStats)
95478ee8d1cSJulian Grajkowski {
95578ee8d1cSJulian Grajkowski 
95678ee8d1cSJulian Grajkowski 	CpaInstanceHandle instanceHandle = NULL;
95778ee8d1cSJulian Grajkowski 
95878ee8d1cSJulian Grajkowski 
95978ee8d1cSJulian Grajkowski 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
96078ee8d1cSJulian Grajkowski 		instanceHandle =
96178ee8d1cSJulian Grajkowski 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
96278ee8d1cSJulian Grajkowski 	} else {
96378ee8d1cSJulian Grajkowski 		instanceHandle = instanceHandle_in;
96478ee8d1cSJulian Grajkowski 	}
96578ee8d1cSJulian Grajkowski 
96678ee8d1cSJulian Grajkowski 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
96778ee8d1cSJulian Grajkowski 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
96878ee8d1cSJulian Grajkowski 				(SAL_SERVICE_TYPE_CRYPTO |
96978ee8d1cSJulian Grajkowski 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
97078ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSymStats);
97178ee8d1cSJulian Grajkowski 
97278ee8d1cSJulian Grajkowski 	/* check if crypto service is running
97378ee8d1cSJulian Grajkowski 	 * otherwise return an error */
97478ee8d1cSJulian Grajkowski 	SAL_RUNNING_CHECK(instanceHandle);
97578ee8d1cSJulian Grajkowski 
97678ee8d1cSJulian Grajkowski 	/* copy the fields from the internal structure into the api defined
97778ee8d1cSJulian Grajkowski 	 * structure */
97878ee8d1cSJulian Grajkowski 	LacSym_Stats64CopyGet(instanceHandle, pSymStats);
97978ee8d1cSJulian Grajkowski 
98078ee8d1cSJulian Grajkowski 	return CPA_STATUS_SUCCESS;
98178ee8d1cSJulian Grajkowski }
98278ee8d1cSJulian Grajkowski 
98378ee8d1cSJulian Grajkowski /** @ingroup LacSym */
98478ee8d1cSJulian Grajkowski CpaStatus
cpaCySymSessionCtxGetSize(const CpaInstanceHandle instanceHandle_in,const CpaCySymSessionSetupData * pSessionSetupData,Cpa32U * pSessionCtxSizeInBytes)98578ee8d1cSJulian Grajkowski cpaCySymSessionCtxGetSize(const CpaInstanceHandle instanceHandle_in,
98678ee8d1cSJulian Grajkowski 			  const CpaCySymSessionSetupData *pSessionSetupData,
98778ee8d1cSJulian Grajkowski 			  Cpa32U *pSessionCtxSizeInBytes)
98878ee8d1cSJulian Grajkowski {
98978ee8d1cSJulian Grajkowski 	CpaInstanceHandle instanceHandle = NULL;
99078ee8d1cSJulian Grajkowski 
99178ee8d1cSJulian Grajkowski 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
99278ee8d1cSJulian Grajkowski 		instanceHandle =
99378ee8d1cSJulian Grajkowski 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
99478ee8d1cSJulian Grajkowski 	} else {
99578ee8d1cSJulian Grajkowski 		instanceHandle = instanceHandle_in;
99678ee8d1cSJulian Grajkowski 	}
99778ee8d1cSJulian Grajkowski 
99878ee8d1cSJulian Grajkowski 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
99978ee8d1cSJulian Grajkowski 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
100078ee8d1cSJulian Grajkowski 				(SAL_SERVICE_TYPE_CRYPTO |
100178ee8d1cSJulian Grajkowski 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
100278ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSessionSetupData);
100378ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
100478ee8d1cSJulian Grajkowski 
100578ee8d1cSJulian Grajkowski 	/* check crypto service is running otherwise return an error */
100678ee8d1cSJulian Grajkowski 	SAL_RUNNING_CHECK(instanceHandle);
100778ee8d1cSJulian Grajkowski 	*pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE;
100878ee8d1cSJulian Grajkowski 
100978ee8d1cSJulian Grajkowski 	return CPA_STATUS_SUCCESS;
101078ee8d1cSJulian Grajkowski }
101178ee8d1cSJulian Grajkowski 
101278ee8d1cSJulian Grajkowski /** @ingroup LacSym */
101378ee8d1cSJulian Grajkowski CpaStatus
cpaCySymSessionCtxGetDynamicSize(const CpaInstanceHandle instanceHandle_in,const CpaCySymSessionSetupData * pSessionSetupData,Cpa32U * pSessionCtxSizeInBytes)101478ee8d1cSJulian Grajkowski cpaCySymSessionCtxGetDynamicSize(
101578ee8d1cSJulian Grajkowski     const CpaInstanceHandle instanceHandle_in,
101678ee8d1cSJulian Grajkowski     const CpaCySymSessionSetupData *pSessionSetupData,
101778ee8d1cSJulian Grajkowski     Cpa32U *pSessionCtxSizeInBytes)
101878ee8d1cSJulian Grajkowski {
101978ee8d1cSJulian Grajkowski 	CpaInstanceHandle instanceHandle = NULL;
102078ee8d1cSJulian Grajkowski 
102178ee8d1cSJulian Grajkowski 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
102278ee8d1cSJulian Grajkowski 		instanceHandle =
102378ee8d1cSJulian Grajkowski 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
102478ee8d1cSJulian Grajkowski 	} else {
102578ee8d1cSJulian Grajkowski 		instanceHandle = instanceHandle_in;
102678ee8d1cSJulian Grajkowski 	}
102778ee8d1cSJulian Grajkowski 
102878ee8d1cSJulian Grajkowski 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
102978ee8d1cSJulian Grajkowski 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
103078ee8d1cSJulian Grajkowski 				(SAL_SERVICE_TYPE_CRYPTO |
103178ee8d1cSJulian Grajkowski 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
103278ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSessionSetupData);
103378ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
103478ee8d1cSJulian Grajkowski 
103578ee8d1cSJulian Grajkowski 	/* check crypto service is running otherwise return an error */
103678ee8d1cSJulian Grajkowski 	SAL_RUNNING_CHECK(instanceHandle);
103778ee8d1cSJulian Grajkowski 	/* Choose Session Context size */
103878ee8d1cSJulian Grajkowski 	getCtxSize(pSessionSetupData, pSessionCtxSizeInBytes);
103978ee8d1cSJulian Grajkowski 
104078ee8d1cSJulian Grajkowski 
104178ee8d1cSJulian Grajkowski 	return CPA_STATUS_SUCCESS;
104278ee8d1cSJulian Grajkowski }
104378ee8d1cSJulian Grajkowski 
104478ee8d1cSJulian Grajkowski void
getCtxSize(const CpaCySymSessionSetupData * pSessionSetupData,Cpa32U * pSessionCtxSizeInBytes)104578ee8d1cSJulian Grajkowski getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData,
104678ee8d1cSJulian Grajkowski 	   Cpa32U *pSessionCtxSizeInBytes)
104778ee8d1cSJulian Grajkowski {
104878ee8d1cSJulian Grajkowski 	/* using lac_session_desc_d1_t */
104978ee8d1cSJulian Grajkowski 	if ((pSessionSetupData->cipherSetupData.cipherAlgorithm !=
105078ee8d1cSJulian Grajkowski 	     CPA_CY_SYM_CIPHER_ARC4) &&
105178ee8d1cSJulian Grajkowski 	    (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
105278ee8d1cSJulian Grajkowski 	     CPA_CY_SYM_CIPHER_SNOW3G_UEA2) &&
105378ee8d1cSJulian Grajkowski 	    (pSessionSetupData->hashSetupData.hashAlgorithm !=
105478ee8d1cSJulian Grajkowski 	     CPA_CY_SYM_HASH_SNOW3G_UIA2) &&
105578ee8d1cSJulian Grajkowski 	    (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
105678ee8d1cSJulian Grajkowski 	     CPA_CY_SYM_CIPHER_AES_CCM) &&
105778ee8d1cSJulian Grajkowski 	    (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
105878ee8d1cSJulian Grajkowski 	     CPA_CY_SYM_CIPHER_AES_GCM) &&
105978ee8d1cSJulian Grajkowski 	    (pSessionSetupData->hashSetupData.hashMode !=
106078ee8d1cSJulian Grajkowski 	     CPA_CY_SYM_HASH_MODE_AUTH) &&
106178ee8d1cSJulian Grajkowski 	    (pSessionSetupData->hashSetupData.hashMode !=
106278ee8d1cSJulian Grajkowski 	     CPA_CY_SYM_HASH_MODE_NESTED) &&
106378ee8d1cSJulian Grajkowski 	    (pSessionSetupData->partialsNotRequired == CPA_TRUE)) {
106478ee8d1cSJulian Grajkowski 		*pSessionCtxSizeInBytes = LAC_SYM_SESSION_D1_SIZE;
106578ee8d1cSJulian Grajkowski 	}
106678ee8d1cSJulian Grajkowski 	/* using lac_session_desc_d2_t */
106778ee8d1cSJulian Grajkowski 	else if (((pSessionSetupData->cipherSetupData.cipherAlgorithm ==
106878ee8d1cSJulian Grajkowski 		   CPA_CY_SYM_CIPHER_AES_CCM) ||
106978ee8d1cSJulian Grajkowski 		  (pSessionSetupData->cipherSetupData.cipherAlgorithm ==
107078ee8d1cSJulian Grajkowski 		   CPA_CY_SYM_CIPHER_AES_GCM)) &&
107178ee8d1cSJulian Grajkowski 		 (pSessionSetupData->partialsNotRequired == CPA_TRUE)) {
107278ee8d1cSJulian Grajkowski 		*pSessionCtxSizeInBytes = LAC_SYM_SESSION_D2_SIZE;
107378ee8d1cSJulian Grajkowski 	}
107478ee8d1cSJulian Grajkowski 	/* using lac_session_desc_t */
107578ee8d1cSJulian Grajkowski 	else {
107678ee8d1cSJulian Grajkowski 		*pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE;
107778ee8d1cSJulian Grajkowski 	}
107878ee8d1cSJulian Grajkowski }
107978ee8d1cSJulian Grajkowski 
108078ee8d1cSJulian Grajkowski /**
108178ee8d1cSJulian Grajkowski  ******************************************************************************
108278ee8d1cSJulian Grajkowski  * @ingroup LacSym
108378ee8d1cSJulian Grajkowski  *****************************************************************************/
108478ee8d1cSJulian Grajkowski CpaStatus
cpaCyBufferListGetMetaSize(const CpaInstanceHandle instanceHandle_in,Cpa32U numBuffers,Cpa32U * pSizeInBytes)108578ee8d1cSJulian Grajkowski cpaCyBufferListGetMetaSize(const CpaInstanceHandle instanceHandle_in,
108678ee8d1cSJulian Grajkowski 			   Cpa32U numBuffers,
108778ee8d1cSJulian Grajkowski 			   Cpa32U *pSizeInBytes)
108878ee8d1cSJulian Grajkowski {
108978ee8d1cSJulian Grajkowski 
109078ee8d1cSJulian Grajkowski 	CpaInstanceHandle instanceHandle = NULL;
109178ee8d1cSJulian Grajkowski 
109278ee8d1cSJulian Grajkowski 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
109378ee8d1cSJulian Grajkowski 		instanceHandle =
109478ee8d1cSJulian Grajkowski 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
109578ee8d1cSJulian Grajkowski 	} else {
109678ee8d1cSJulian Grajkowski 		instanceHandle = instanceHandle_in;
109778ee8d1cSJulian Grajkowski 	}
109878ee8d1cSJulian Grajkowski 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
109978ee8d1cSJulian Grajkowski 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
110078ee8d1cSJulian Grajkowski 				(SAL_SERVICE_TYPE_CRYPTO |
110178ee8d1cSJulian Grajkowski 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
110278ee8d1cSJulian Grajkowski 	LAC_CHECK_NULL_PARAM(pSizeInBytes);
110378ee8d1cSJulian Grajkowski 
110478ee8d1cSJulian Grajkowski 	/* In the case of zero buffers we still need to allocate one
110578ee8d1cSJulian Grajkowski 	 * descriptor to pass to the firmware */
110678ee8d1cSJulian Grajkowski 	if (0 == numBuffers) {
110778ee8d1cSJulian Grajkowski 		numBuffers = 1;
110878ee8d1cSJulian Grajkowski 	}
110978ee8d1cSJulian Grajkowski 
111078ee8d1cSJulian Grajkowski 	/* Note: icp_buffer_list_desc_t is 8 bytes in size and
111178ee8d1cSJulian Grajkowski 	 * icp_flat_buffer_desc_t is 16 bytes in size. Therefore if
111278ee8d1cSJulian Grajkowski 	 * icp_buffer_list_desc_t is aligned
111378ee8d1cSJulian Grajkowski 	 * so will each icp_flat_buffer_desc_t structure */
111478ee8d1cSJulian Grajkowski 
111578ee8d1cSJulian Grajkowski 	*pSizeInBytes = sizeof(icp_buffer_list_desc_t) +
111678ee8d1cSJulian Grajkowski 	    (sizeof(icp_flat_buffer_desc_t) * numBuffers) +
111778ee8d1cSJulian Grajkowski 	    ICP_DESCRIPTOR_ALIGNMENT_BYTES;
111878ee8d1cSJulian Grajkowski 
111978ee8d1cSJulian Grajkowski 
112078ee8d1cSJulian Grajkowski 	return CPA_STATUS_SUCCESS;
112178ee8d1cSJulian Grajkowski }
1122