xref: /freebsd/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_api.c (revision 25f09d4a9c358c5452435d299e00c1a1bdafff87)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2025 Intel Corporation */
3 
4 /**
5  ***************************************************************************
6  * @file lac_sym_api.c      Implementation of the symmetric API
7  *
8  * @ingroup LacSym
9  *
10  ***************************************************************************/
11 
12 /*
13 *******************************************************************************
14 * Include public/global header files
15 *******************************************************************************
16 */
17 
18 #include "cpa.h"
19 #include "cpa_cy_sym.h"
20 #include "cpa_cy_im.h"
21 
22 #include "icp_adf_init.h"
23 #include "icp_adf_transport.h"
24 #include "icp_adf_transport_dp.h"
25 #include "icp_accel_devices.h"
26 #include "icp_adf_debug.h"
27 #include "icp_qat_fw_la.h"
28 
29 /*
30  ******************************************************************************
31  * Include private header files
32  ******************************************************************************
33  */
34 #include "lac_common.h"
35 #include "lac_log.h"
36 #include "lac_mem.h"
37 #include "lac_mem_pools.h"
38 #include "lac_list.h"
39 #include "lac_sym.h"
40 #include "lac_sym_qat.h"
41 #include "lac_sal.h"
42 #include "lac_sal_ctrl.h"
43 #include "lac_session.h"
44 #include "lac_sym_cipher.h"
45 #include "lac_sym_hash.h"
46 #include "lac_sym_alg_chain.h"
47 #include "lac_sym_stats.h"
48 #include "lac_sym_partial.h"
49 #include "lac_sym_qat_hash_defs_lookup.h"
50 #include "lac_sym_cb.h"
51 #include "lac_buffer_desc.h"
52 #include "lac_sync.h"
53 #include "lac_hooks.h"
54 #include "lac_sal_types_crypto.h"
55 #include "sal_service_state.h"
56 
57 #define IS_EXT_ALG_CHAIN_UNSUPPORTED(cipherAlgorithm,                          \
58 				     hashAlgorithm,                            \
59 				     extAlgchainSupported)                     \
60 	((((CPA_CY_SYM_CIPHER_ZUC_EEA3 == cipherAlgorithm ||                   \
61 	    CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == cipherAlgorithm) &&               \
62 	   CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) ||                       \
63 	  ((CPA_CY_SYM_CIPHER_NULL == cipherAlgorithm ||                       \
64 	    CPA_CY_SYM_CIPHER_AES_CTR == cipherAlgorithm ||                    \
65 	    CPA_CY_SYM_CIPHER_ZUC_EEA3 == cipherAlgorithm) &&                  \
66 	   CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) ||                    \
67 	  ((CPA_CY_SYM_CIPHER_NULL == cipherAlgorithm ||                       \
68 	    CPA_CY_SYM_CIPHER_AES_CTR == cipherAlgorithm ||                    \
69 	    CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == cipherAlgorithm) &&               \
70 	   CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm)) &&                      \
71 	 !extAlgchainSupported)
72 
73 /*** Local functions definitions ***/
74 static CpaStatus
75 LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer,
76 			       const CpaBufferList *const pDstBuffer,
77 			       const lac_session_desc_t *const pSessionDesc,
78 			       const CpaCySymOpData *const pOpData);
79 
80 void LacDp_WriteRingMsgFull(CpaCySymDpOpData *pRequest,
81 			    icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
82 void LacDp_WriteRingMsgOpt(CpaCySymDpOpData *pRequest,
83 			   icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
84 void getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData,
85 		Cpa32U *pSessionCtxSizeInBytes);
86 
87 /**
88  *****************************************************************************
89  * @ingroup LacSym
90  *      Generic bufferList callback function.
91  * @description
92  *      This function is used when the API is called in synchronous mode.
93  *      It's assumed the callbackTag holds a lac_sync_op_data_t type
94  *      and when the callback is received, this callback shall set the
95  *      status and opResult element of that cookie structure and
96  *      kick the sid.
97  *      This function may be used directly as a callback function.
98  *
99  * @param[in]  callbackTag       Callback Tag
100  * @param[in]  status            Status of callback
101  * @param[in]  operationType     Operation Type
102  * @param[in]  pOpData           Pointer to the Op Data
103  * @param[out] pDstBuffer        Pointer to destination buffer list
104  * @param[out] opResult          Boolean to indicate the result of the operation
105  *
106  * @return void
107  *
108  *****************************************************************************/
109 void
LacSync_GenBufListVerifyCb(void * pCallbackTag,CpaStatus status,CpaCySymOp operationType,void * pOpData,CpaBufferList * pDstBuffer,CpaBoolean opResult)110 LacSync_GenBufListVerifyCb(void *pCallbackTag,
111 			   CpaStatus status,
112 			   CpaCySymOp operationType,
113 			   void *pOpData,
114 			   CpaBufferList *pDstBuffer,
115 			   CpaBoolean opResult)
116 {
117 	LacSync_GenVerifyWakeupSyncCaller(pCallbackTag, status, opResult);
118 }
119 
120 /*
121 *******************************************************************************
122 * Define static function definitions
123 *******************************************************************************
124 */
125 /**
126  * @ingroup LacSym
127  * Function which perform parameter checks on session setup data
128  *
129  * @param[in] CpaInstanceHandle     Instance Handle
130  * @param[in] pSessionSetupData     Pointer to session setup data
131  *
132  * @retval CPA_STATUS_SUCCESS        The operation succeeded
133  * @retval CPA_STATUS_INVALID_PARAM  An invalid parameter value was found
134  */
135 static CpaStatus
LacSymSession_ParamCheck(const CpaInstanceHandle instanceHandle,const CpaCySymSessionSetupData * pSessionSetupData)136 LacSymSession_ParamCheck(const CpaInstanceHandle instanceHandle,
137 			 const CpaCySymSessionSetupData *pSessionSetupData)
138 {
139 	/* initialize convenient pointers to cipher and hash contexts */
140 	const CpaCySymCipherSetupData *const pCipherSetupData =
141 	    (const CpaCySymCipherSetupData *)&pSessionSetupData
142 		->cipherSetupData;
143 	const CpaCySymHashSetupData *const pHashSetupData =
144 	    &pSessionSetupData->hashSetupData;
145 
146 	CpaCySymCapabilitiesInfo capInfo;
147 	CpaCyCapabilitiesInfo cyCapInfo;
148 	cpaCySymQueryCapabilities(instanceHandle, &capInfo);
149 	SalCtrl_CyQueryCapabilities(instanceHandle, &cyCapInfo);
150 
151 	/* Ensure cipher algorithm is correct and supported */
152 	if ((CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
153 	     pSessionSetupData->symOperation) ||
154 	    (CPA_CY_SYM_OP_CIPHER == pSessionSetupData->symOperation)) {
155 		/* Protect against value of cipher outside the bitmap
156 		 * and check if cipher algorithm is correct
157 		 */
158 		if (pCipherSetupData->cipherAlgorithm >=
159 		    CPA_CY_SYM_CIPHER_CAP_BITMAP_SIZE) {
160 			LAC_INVALID_PARAM_LOG("cipherAlgorithm");
161 			return CPA_STATUS_INVALID_PARAM;
162 		}
163 		if (!CPA_BITMAP_BIT_TEST(capInfo.ciphers,
164 					 pCipherSetupData->cipherAlgorithm)) {
165 			LAC_UNSUPPORTED_PARAM_LOG(
166 			    "UnSupported cipherAlgorithm");
167 			return CPA_STATUS_UNSUPPORTED;
168 		}
169 	}
170 
171 	/* Ensure hash algorithm is correct and supported */
172 	if ((CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
173 	     pSessionSetupData->symOperation) ||
174 	    (CPA_CY_SYM_OP_HASH == pSessionSetupData->symOperation)) {
175 		/* Protect against value of hash outside the bitmap
176 		 * and check if hash algorithm is correct
177 		 */
178 		if (pHashSetupData->hashAlgorithm >=
179 		    CPA_CY_SYM_HASH_CAP_BITMAP_SIZE) {
180 			LAC_INVALID_PARAM_LOG("hashAlgorithm");
181 			return CPA_STATUS_INVALID_PARAM;
182 		}
183 		if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
184 					 pHashSetupData->hashAlgorithm)) {
185 			LAC_UNSUPPORTED_PARAM_LOG("UnSupported hashAlgorithm");
186 			return CPA_STATUS_UNSUPPORTED;
187 		}
188 	}
189 
190 	/* ensure CCM, GCM, Kasumi, Snow3G and ZUC cipher and hash algorithms
191 	 * are selected together for Algorithm Chaining */
192 	if (CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
193 	    pSessionSetupData->symOperation) {
194 		/* ensure both hash and cipher algorithms are POLY and CHACHA */
195 		if (((CPA_CY_SYM_CIPHER_CHACHA ==
196 		      pCipherSetupData->cipherAlgorithm) &&
197 		     (CPA_CY_SYM_HASH_POLY != pHashSetupData->hashAlgorithm)) ||
198 		    ((CPA_CY_SYM_HASH_POLY == pHashSetupData->hashAlgorithm) &&
199 		     (CPA_CY_SYM_CIPHER_CHACHA !=
200 		      pCipherSetupData->cipherAlgorithm))) {
201 			LAC_INVALID_PARAM_LOG(
202 			    "Invalid combination of Cipher/Hash "
203 			    "Algorithms for CHACHA/POLY");
204 			return CPA_STATUS_INVALID_PARAM;
205 		}
206 
207 		/* ensure both hash and cipher algorithms are CCM */
208 		if (((CPA_CY_SYM_CIPHER_AES_CCM ==
209 		      pCipherSetupData->cipherAlgorithm) &&
210 		     (CPA_CY_SYM_HASH_AES_CCM !=
211 		      pHashSetupData->hashAlgorithm)) ||
212 		    ((CPA_CY_SYM_HASH_AES_CCM ==
213 		      pHashSetupData->hashAlgorithm) &&
214 		     (CPA_CY_SYM_CIPHER_AES_CCM !=
215 		      pCipherSetupData->cipherAlgorithm))) {
216 			LAC_INVALID_PARAM_LOG(
217 			    "Invalid combination of Cipher/Hash Algorithms for CCM");
218 			return CPA_STATUS_INVALID_PARAM;
219 		}
220 
221 		/* ensure both hash and cipher algorithms are GCM/GMAC */
222 		if ((CPA_CY_SYM_CIPHER_AES_GCM ==
223 			 pCipherSetupData->cipherAlgorithm &&
224 		     (CPA_CY_SYM_HASH_AES_GCM !=
225 			  pHashSetupData->hashAlgorithm &&
226 		      CPA_CY_SYM_HASH_AES_GMAC !=
227 			  pHashSetupData->hashAlgorithm)) ||
228 		    ((CPA_CY_SYM_HASH_AES_GCM ==
229 			  pHashSetupData->hashAlgorithm ||
230 		      CPA_CY_SYM_HASH_AES_GMAC ==
231 			  pHashSetupData->hashAlgorithm) &&
232 		     CPA_CY_SYM_CIPHER_AES_GCM !=
233 			 pCipherSetupData->cipherAlgorithm)) {
234 			LAC_INVALID_PARAM_LOG(
235 			    "Invalid combination of Cipher/Hash Algorithms for GCM");
236 			return CPA_STATUS_INVALID_PARAM;
237 		}
238 
239 		/* ensure both hash and cipher algorithms are Kasumi */
240 		if (((CPA_CY_SYM_CIPHER_KASUMI_F8 ==
241 		      pCipherSetupData->cipherAlgorithm) &&
242 		     (CPA_CY_SYM_HASH_KASUMI_F9 !=
243 		      pHashSetupData->hashAlgorithm)) ||
244 		    ((CPA_CY_SYM_HASH_KASUMI_F9 ==
245 		      pHashSetupData->hashAlgorithm) &&
246 		     (CPA_CY_SYM_CIPHER_KASUMI_F8 !=
247 		      pCipherSetupData->cipherAlgorithm))) {
248 			LAC_INVALID_PARAM_LOG(
249 			    "Invalid combination of Cipher/Hash Algorithms for Kasumi");
250 			return CPA_STATUS_INVALID_PARAM;
251 		}
252 
253 		if (IS_EXT_ALG_CHAIN_UNSUPPORTED(
254 			pCipherSetupData->cipherAlgorithm,
255 			pHashSetupData->hashAlgorithm,
256 			cyCapInfo.extAlgchainSupported)) {
257 			LAC_UNSUPPORTED_PARAM_LOG(
258 			    "ExtAlgChain feature not supported");
259 			return CPA_STATUS_UNSUPPORTED;
260 		}
261 
262 		/* ensure both hash and cipher algorithms are Snow3G */
263 		if (((CPA_CY_SYM_CIPHER_SNOW3G_UEA2 ==
264 		      pCipherSetupData->cipherAlgorithm) &&
265 		     (CPA_CY_SYM_HASH_SNOW3G_UIA2 !=
266 		      pHashSetupData->hashAlgorithm)) ||
267 		    ((CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
268 		      pHashSetupData->hashAlgorithm) &&
269 		     (CPA_CY_SYM_CIPHER_SNOW3G_UEA2 !=
270 		      pCipherSetupData->cipherAlgorithm))) {
271 			LAC_INVALID_PARAM_LOG(
272 			    "Invalid combination of Cipher/Hash Algorithms for Snow3G");
273 			return CPA_STATUS_INVALID_PARAM;
274 		}
275 
276 		/* ensure both hash and cipher algorithms are ZUC */
277 		if (((CPA_CY_SYM_CIPHER_ZUC_EEA3 ==
278 		      pCipherSetupData->cipherAlgorithm) &&
279 		     (CPA_CY_SYM_HASH_ZUC_EIA3 !=
280 		      pHashSetupData->hashAlgorithm)) ||
281 		    ((CPA_CY_SYM_HASH_ZUC_EIA3 ==
282 		      pHashSetupData->hashAlgorithm) &&
283 		     (CPA_CY_SYM_CIPHER_ZUC_EEA3 !=
284 		      pCipherSetupData->cipherAlgorithm))) {
285 			LAC_INVALID_PARAM_LOG(
286 			    "Invalid combination of Cipher/Hash Algorithms for ZUC");
287 			return CPA_STATUS_INVALID_PARAM;
288 		}
289 	}
290 	/* not Algorithm Chaining so prevent CCM/GCM being selected */
291 	else if (CPA_CY_SYM_OP_CIPHER == pSessionSetupData->symOperation) {
292 		/* ensure cipher algorithm is not CCM or GCM */
293 		if ((CPA_CY_SYM_CIPHER_AES_CCM ==
294 		     pCipherSetupData->cipherAlgorithm) ||
295 		    (CPA_CY_SYM_CIPHER_AES_GCM ==
296 		     pCipherSetupData->cipherAlgorithm) ||
297 		    (CPA_CY_SYM_CIPHER_CHACHA ==
298 		     pCipherSetupData->cipherAlgorithm)) {
299 			LAC_INVALID_PARAM_LOG(
300 			    "Invalid Cipher Algorithm for non-Algorithm "
301 			    "Chaining operation");
302 			return CPA_STATUS_INVALID_PARAM;
303 		}
304 	} else if (CPA_CY_SYM_OP_HASH == pSessionSetupData->symOperation) {
305 		/* ensure hash algorithm is not CCM or GCM/GMAC */
306 		if ((CPA_CY_SYM_HASH_AES_CCM ==
307 		     pHashSetupData->hashAlgorithm) ||
308 		    (CPA_CY_SYM_HASH_AES_GCM ==
309 		     pHashSetupData->hashAlgorithm) ||
310 		    (CPA_CY_SYM_HASH_AES_GMAC ==
311 		     pHashSetupData->hashAlgorithm) ||
312 		    (CPA_CY_SYM_HASH_POLY == pHashSetupData->hashAlgorithm)) {
313 			LAC_INVALID_PARAM_LOG(
314 			    "Invalid Hash Algorithm for non-Algorithm Chaining operation");
315 			return CPA_STATUS_INVALID_PARAM;
316 		}
317 	}
318 	/* Unsupported operation. Return error */
319 	else {
320 		LAC_INVALID_PARAM_LOG("symOperation");
321 		return CPA_STATUS_INVALID_PARAM;
322 	}
323 
324 	/* ensure that cipher direction param is
325 	 * valid for cipher and algchain ops */
326 	if (CPA_CY_SYM_OP_HASH != pSessionSetupData->symOperation) {
327 		if ((pCipherSetupData->cipherDirection !=
328 		     CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) &&
329 		    (pCipherSetupData->cipherDirection !=
330 		     CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT)) {
331 			LAC_INVALID_PARAM_LOG("Invalid Cipher Direction");
332 			return CPA_STATUS_INVALID_PARAM;
333 		}
334 	}
335 
336 	return CPA_STATUS_SUCCESS;
337 }
338 
339 /**
340  * @ingroup LacSym
341  * Function which perform parameter checks on data buffers for symmetric
342  * crypto operations
343  *
344  * @param[in] pSrcBuffer          Pointer to source buffer list
345  * @param[in] pDstBuffer          Pointer to destination buffer list
346  * @param[in] pSessionDesc        Pointer to session descriptor
347  * @param[in] pOpData             Pointer to CryptoSymOpData.
348  *
349  * @retval CPA_STATUS_SUCCESS        The operation succeeded
350  * @retval CPA_STATUS_INVALID_PARAM  An invalid parameter value was found
351  */
352 
353 static CpaStatus
LacSymPerform_BufferParamCheck(const CpaBufferList * const pSrcBuffer,const CpaBufferList * const pDstBuffer,const lac_session_desc_t * const pSessionDesc,const CpaCySymOpData * const pOpData)354 LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer,
355 			       const CpaBufferList *const pDstBuffer,
356 			       const lac_session_desc_t *const pSessionDesc,
357 			       const CpaCySymOpData *const pOpData)
358 {
359 	Cpa64U srcBufferLen = 0, dstBufferLen = 0;
360 	CpaStatus status = CPA_STATUS_SUCCESS;
361 
362 	/* verify packet type is in correct range */
363 	switch (pOpData->packetType) {
364 	case CPA_CY_SYM_PACKET_TYPE_FULL:
365 	case CPA_CY_SYM_PACKET_TYPE_PARTIAL:
366 	case CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL:
367 		break;
368 	default: {
369 		LAC_INVALID_PARAM_LOG("packetType");
370 		return CPA_STATUS_INVALID_PARAM;
371 	}
372 	}
373 
374 	if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation &&
375 	       CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) &&
376 	      (0 == pOpData->messageLenToHashInBytes))) {
377 		if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(
378 			pSessionDesc->cipherAlgorithm,
379 			pSessionDesc->hashAlgorithm)) {
380 			status = LacBuffDesc_BufferListVerifyNull(
381 			    pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT);
382 		} else {
383 			status = LacBuffDesc_BufferListVerify(
384 			    pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT);
385 		}
386 		if (CPA_STATUS_SUCCESS != status) {
387 			LAC_INVALID_PARAM_LOG("Source buffer invalid");
388 			return CPA_STATUS_INVALID_PARAM;
389 		}
390 	} else {
391 		/* check MetaData !NULL */
392 		if (NULL == pSrcBuffer->pPrivateMetaData) {
393 			LAC_INVALID_PARAM_LOG(
394 			    "Source buffer MetaData cannot be NULL");
395 			return CPA_STATUS_INVALID_PARAM;
396 		}
397 	}
398 
399 	/* out of place checks */
400 	if (pSrcBuffer != pDstBuffer) {
401 		/* exception for this check is zero length hash requests to
402 		 * allow */
403 		/* for srcBufflen=DstBufferLen=0 */
404 		if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation &&
405 		       CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) &&
406 		      (0 == pOpData->messageLenToHashInBytes))) {
407 			/* Verify buffer(s) for dest packet & return packet
408 			 * length */
409 			if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(
410 				pSessionDesc->cipherAlgorithm,
411 				pSessionDesc->hashAlgorithm)) {
412 				status = LacBuffDesc_BufferListVerifyNull(
413 				    pDstBuffer,
414 				    &dstBufferLen,
415 				    LAC_NO_ALIGNMENT_SHIFT);
416 			} else {
417 				status = LacBuffDesc_BufferListVerify(
418 				    pDstBuffer,
419 				    &dstBufferLen,
420 				    LAC_NO_ALIGNMENT_SHIFT);
421 			}
422 			if (CPA_STATUS_SUCCESS != status) {
423 				LAC_INVALID_PARAM_LOG(
424 				    "Destination buffer invalid");
425 				return CPA_STATUS_INVALID_PARAM;
426 			}
427 		} else {
428 			/* check MetaData !NULL */
429 			if (NULL == pDstBuffer->pPrivateMetaData) {
430 				LAC_INVALID_PARAM_LOG(
431 				    "Dest buffer MetaData cannot be NULL");
432 				return CPA_STATUS_INVALID_PARAM;
433 			}
434 		}
435 		/* Check that src Buffer and dst Buffer Lengths are equal */
436 		/* CCM output needs to be longer than input buffer for appending
437 		 * tag*/
438 		if (srcBufferLen != dstBufferLen &&
439 		    pSessionDesc->cipherAlgorithm !=
440 			CPA_CY_SYM_CIPHER_AES_CCM) {
441 			LAC_INVALID_PARAM_LOG(
442 			    "Source and Dest buffer lengths need to be equal ");
443 			return CPA_STATUS_INVALID_PARAM;
444 		}
445 	}
446 
447 	/* check for partial packet support for the session operation */
448 	if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) {
449 		if (CPA_FALSE == pSessionDesc->isPartialSupported) {
450 			/* return out here to simplify cleanup */
451 			LAC_INVALID_PARAM_LOG(
452 			    "Partial packets not supported for operation");
453 			return CPA_STATUS_INVALID_PARAM;
454 		} else {
455 			/* This function checks to see if the partial packet
456 			 * sequence is correct */
457 			if (CPA_STATUS_SUCCESS !=
458 			    LacSym_PartialPacketStateCheck(
459 				pOpData->packetType,
460 				pSessionDesc->partialState)) {
461 				LAC_INVALID_PARAM_LOG("Partial packet Type");
462 				return CPA_STATUS_INVALID_PARAM;
463 			}
464 		}
465 	}
466 	return CPA_STATUS_SUCCESS;
467 }
468 
469 /** @ingroup LacSym */
470 CpaStatus
cpaCySymInitSession(const CpaInstanceHandle instanceHandle_in,const CpaCySymCbFunc pSymCb,const CpaCySymSessionSetupData * pSessionSetupData,CpaCySymSessionCtx pSessionCtx)471 cpaCySymInitSession(const CpaInstanceHandle instanceHandle_in,
472 		    const CpaCySymCbFunc pSymCb,
473 		    const CpaCySymSessionSetupData *pSessionSetupData,
474 		    CpaCySymSessionCtx pSessionCtx)
475 {
476 	CpaStatus status = CPA_STATUS_SUCCESS;
477 	CpaInstanceHandle instanceHandle = NULL;
478 	sal_service_t *pService = NULL;
479 
480 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
481 		instanceHandle =
482 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
483 	} else {
484 		instanceHandle = instanceHandle_in;
485 	}
486 
487 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
488 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
489 				(SAL_SERVICE_TYPE_CRYPTO |
490 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
491 
492 	pService = (sal_service_t *)instanceHandle;
493 
494 	/* check crypto service is running otherwise return an error */
495 	SAL_RUNNING_CHECK(pService);
496 
497 	status = LacSym_InitSession(instanceHandle,
498 				    pSymCb,
499 				    pSessionSetupData,
500 				    CPA_FALSE, /* isDPSession */
501 				    pSessionCtx);
502 
503 	if (CPA_STATUS_SUCCESS == status) {
504 		/* Increment the stats for a session registered successfully */
505 		LAC_SYM_STAT_INC(numSessionsInitialized, instanceHandle);
506 	} else /* if there was an error */
507 	{
508 		LAC_SYM_STAT_INC(numSessionErrors, instanceHandle);
509 	}
510 
511 	return status;
512 }
513 
514 CpaStatus
cpaCySymSessionInUse(CpaCySymSessionCtx pSessionCtx,CpaBoolean * pSessionInUse)515 cpaCySymSessionInUse(CpaCySymSessionCtx pSessionCtx, CpaBoolean *pSessionInUse)
516 {
517 	CpaStatus status = CPA_STATUS_SUCCESS;
518 	lac_session_desc_t *pSessionDesc = NULL;
519 
520 	LAC_CHECK_NULL_PARAM(pSessionInUse);
521 	LAC_CHECK_INSTANCE_HANDLE(pSessionCtx);
522 
523 	*pSessionInUse = CPA_FALSE;
524 
525 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx);
526 
527 	/* If there are pending requests */
528 	if (pSessionDesc->isDPSession) {
529 		if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount)))
530 			*pSessionInUse = CPA_TRUE;
531 	} else {
532 		if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount)))
533 			*pSessionInUse = CPA_TRUE;
534 	}
535 
536 	return status;
537 }
538 
539 CpaStatus
LacSym_InitSession(const CpaInstanceHandle instanceHandle,const CpaCySymCbFunc pSymCb,const CpaCySymSessionSetupData * pSessionSetupData,const CpaBoolean isDPSession,CpaCySymSessionCtx pSessionCtx)540 LacSym_InitSession(const CpaInstanceHandle instanceHandle,
541 		   const CpaCySymCbFunc pSymCb,
542 		   const CpaCySymSessionSetupData *pSessionSetupData,
543 		   const CpaBoolean isDPSession,
544 		   CpaCySymSessionCtx pSessionCtx)
545 {
546 	CpaStatus status = CPA_STATUS_SUCCESS;
547 	lac_session_desc_t *pSessionDesc = NULL;
548 	Cpa32U sessionCtxSizeInBytes = 0;
549 	CpaPhysicalAddr physAddress = 0;
550 	CpaPhysicalAddr physAddressAligned = 0;
551 	sal_service_t *pService = NULL;
552 	const CpaCySymCipherSetupData *pCipherSetupData = NULL;
553 	const CpaCySymHashSetupData *pHashSetupData = NULL;
554 
555 	/* Instance param checking done by calling function */
556 
557 	LAC_CHECK_NULL_PARAM(pSessionSetupData);
558 	LAC_CHECK_NULL_PARAM(pSessionCtx);
559 	status = LacSymSession_ParamCheck(instanceHandle, pSessionSetupData);
560 	LAC_CHECK_STATUS(status);
561 
562 	/* set the session priority for QAT AL*/
563 	if ((CPA_CY_PRIORITY_HIGH == pSessionSetupData->sessionPriority) ||
564 	    (CPA_CY_PRIORITY_NORMAL == pSessionSetupData->sessionPriority)) {
565 		// do nothing - clean up this code. use RANGE macro
566 	} else {
567 		LAC_INVALID_PARAM_LOG("sessionPriority");
568 		return CPA_STATUS_INVALID_PARAM;
569 	}
570 
571 	pCipherSetupData = &pSessionSetupData->cipherSetupData;
572 	pHashSetupData = &pSessionSetupData->hashSetupData;
573 
574 	pService = (sal_service_t *)instanceHandle;
575 
576 	/* Re-align the session structure to 64 byte alignment */
577 	physAddress =
578 	    LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService),
579 					 (Cpa8U *)pSessionCtx + sizeof(void *));
580 
581 	if (0 == physAddress) {
582 		LAC_LOG_ERROR(
583 		    "Unable to get the physical address of the session\n");
584 		return CPA_STATUS_FAIL;
585 	}
586 
587 	physAddressAligned =
588 	    LAC_ALIGN_POW2_ROUNDUP(physAddress, LAC_64BYTE_ALIGNMENT);
589 
590 	pSessionDesc = (lac_session_desc_t *)
591 	    /* Move the session pointer by the physical offset
592 	    between aligned and unaligned memory */
593 	    ((Cpa8U *)pSessionCtx + sizeof(void *) +
594 	     (physAddressAligned - physAddress));
595 
596 	/* save the aligned pointer in the first bytes (size of unsigned long)
597 	 * of the session memory */
598 	*((LAC_ARCH_UINT *)pSessionCtx) = (LAC_ARCH_UINT)pSessionDesc;
599 
600 	/* start off with a clean session */
601 	/* Choose Session Context size */
602 	getCtxSize(pSessionSetupData, &sessionCtxSizeInBytes);
603 	switch (sessionCtxSizeInBytes) {
604 	case LAC_SYM_SESSION_D1_SIZE:
605 		memset(pSessionDesc, 0, sizeof(lac_session_desc_d1_t));
606 		break;
607 	case LAC_SYM_SESSION_D2_SIZE:
608 		memset(pSessionDesc, 0, sizeof(lac_session_desc_d2_t));
609 		break;
610 	default:
611 		memset(pSessionDesc, 0, sizeof(lac_session_desc_t));
612 		break;
613 	}
614 
615 	/* Setup content descriptor info structure
616 	 * assumption that content descriptor is the first field in
617 	 * in the session descriptor */
618 	pSessionDesc->contentDescInfo.pData = (Cpa8U *)pSessionDesc;
619 	pSessionDesc->contentDescInfo.hardwareSetupBlockPhys =
620 	    physAddressAligned;
621 
622 	pSessionDesc->contentDescOptimisedInfo.pData =
623 	    ((Cpa8U *)pSessionDesc + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE);
624 	pSessionDesc->contentDescOptimisedInfo.hardwareSetupBlockPhys =
625 	    (physAddressAligned + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE);
626 
627 	/* Set the Common Session Information */
628 	pSessionDesc->symOperation = pSessionSetupData->symOperation;
629 
630 	if (CPA_FALSE == isDPSession) {
631 		/* For asynchronous - use the user supplied callback
632 		 * for synchronous - use the internal synchronous callback */
633 		pSessionDesc->pSymCb = ((void *)NULL != (void *)pSymCb) ?
634 			  pSymCb :
635 			  LacSync_GenBufListVerifyCb;
636 	}
637 
638 	pSessionDesc->isDPSession = isDPSession;
639 	if ((CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm) ||
640 	    (CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) ||
641 	    (CPA_CY_SYM_HASH_AES_CCM == pHashSetupData->hashAlgorithm) ||
642 	    (CPA_CY_SYM_CIPHER_CHACHA == pCipherSetupData->cipherAlgorithm) ||
643 	    (CPA_CY_SYM_CIPHER_ARC4 == pCipherSetupData->cipherAlgorithm)) {
644 		pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgFull;
645 	} else {
646 		pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgOpt;
647 	}
648 
649 	if (CPA_STATUS_SUCCESS == status) {
650 		/* Session set up via API call (not internal one) */
651 		/* Services such as DRBG call the crypto api as part of their
652 		 * service hence the need to for the flag, it is needed to
653 		 * distinguish between an internal and external session.
654 		 */
655 		pSessionDesc->internalSession = CPA_FALSE;
656 
657 		status = LacAlgChain_SessionInit(instanceHandle,
658 						 pSessionSetupData,
659 						 pSessionDesc);
660 	}
661 	return status;
662 }
663 
664 /** @ingroup LacSym */
665 CpaStatus
cpaCySymRemoveSession(const CpaInstanceHandle instanceHandle_in,CpaCySymSessionCtx pSessionCtx)666 cpaCySymRemoveSession(const CpaInstanceHandle instanceHandle_in,
667 		      CpaCySymSessionCtx pSessionCtx)
668 {
669 	lac_session_desc_t *pSessionDesc = NULL;
670 	CpaStatus status = CPA_STATUS_SUCCESS;
671 	CpaInstanceHandle instanceHandle = NULL;
672 	Cpa64U numPendingRequests = 0;
673 
674 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
675 		instanceHandle =
676 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
677 	} else {
678 		instanceHandle = instanceHandle_in;
679 	}
680 
681 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
682 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
683 				(SAL_SERVICE_TYPE_CRYPTO |
684 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
685 	LAC_CHECK_NULL_PARAM(pSessionCtx);
686 
687 	/* check crypto service is running otherwise return an error */
688 	SAL_RUNNING_CHECK(instanceHandle);
689 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx);
690 
691 	LAC_CHECK_NULL_PARAM(pSessionDesc);
692 
693 	if (CPA_TRUE == pSessionDesc->isDPSession) {
694 		/*
695 		 * Based on one instance, we can initialize multiple sessions.
696 		 * For example, we can initialize the session "X" and session
697 		 * "Y" with the same instance "A". If there is no operation
698 		 * pending for session "X", we can remove the session "X".
699 		 *
700 		 * Now we only check the @pSessionDesc->pendingDpCbCount, if it
701 		 * becomes zero, we can remove the session.
702 		 *
703 		 * Why?
704 		 *   (1) We increase it in the cpaCySymDpEnqueueOp/
705 		 *       cpaCySymDpEnqueueOpBatch.
706 		 *   (2) We decrease it in the LacSymCb_ProcessCallback.
707 		 *
708 		 * If the @pSessionDesc->pendingDpCbCount becomes zero, it means
709 		 * there is no operation pending for the session "X" anymore, so
710 		 * we can remove this session. Maybe there is still some
711 		 * requests left in the instance's ring
712 		 * (icp_adf_queueDataToSend() returns true), but the request
713 		 * does not belong to "X", it belongs to session "Y".
714 		 */
715 		numPendingRequests =
716 		    qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount));
717 	} else {
718 		numPendingRequests =
719 		    qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount));
720 	}
721 
722 	/* If there are pending requests */
723 	if (0 != numPendingRequests) {
724 		QAT_UTILS_LOG("There are %llu requests pending\n",
725 			      (unsigned long long)numPendingRequests);
726 		status = CPA_STATUS_RETRY;
727 		if (CPA_TRUE == pSessionDesc->isDPSession) {
728 			/* Need to update tail if messages queue on tx hi ring
729 			 for data plane api */
730 			icp_comms_trans_handle trans_handle =
731 			    ((sal_crypto_service_t *)instanceHandle)
732 				->trans_handle_sym_tx;
733 
734 			if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
735 				/* process the remaining messages in the ring */
736 				QAT_UTILS_LOG("Submitting enqueued requests\n");
737 				/*
738 				 * SalQatMsg_updateQueueTail
739 				 */
740 				SalQatMsg_updateQueueTail(trans_handle);
741 				return status;
742 			}
743 		}
744 	}
745 	if (CPA_STATUS_SUCCESS == status) {
746 		LAC_SPINLOCK_DESTROY(&pSessionDesc->requestQueueLock);
747 		if (CPA_FALSE == pSessionDesc->isDPSession) {
748 			LAC_SYM_STAT_INC(numSessionsRemoved, instanceHandle);
749 		}
750 	} else if (CPA_FALSE == pSessionDesc->isDPSession) {
751 		LAC_SYM_STAT_INC(numSessionErrors, instanceHandle);
752 	}
753 	return status;
754 }
755 
756 /** @ingroup LacSym */
757 static CpaStatus
LacSym_Perform(const CpaInstanceHandle instanceHandle,void * callbackTag,const CpaCySymOpData * pOpData,const CpaBufferList * pSrcBuffer,CpaBufferList * pDstBuffer,CpaBoolean * pVerifyResult,CpaBoolean isAsyncMode)758 LacSym_Perform(const CpaInstanceHandle instanceHandle,
759 	       void *callbackTag,
760 	       const CpaCySymOpData *pOpData,
761 	       const CpaBufferList *pSrcBuffer,
762 	       CpaBufferList *pDstBuffer,
763 	       CpaBoolean *pVerifyResult,
764 	       CpaBoolean isAsyncMode)
765 {
766 	lac_session_desc_t *pSessionDesc = NULL;
767 	CpaStatus status = CPA_STATUS_SUCCESS;
768 
769 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
770 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
771 				(SAL_SERVICE_TYPE_CRYPTO |
772 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
773 	/* check crypto service is running otherwise return an error */
774 	SAL_RUNNING_CHECK(instanceHandle);
775 	LAC_CHECK_NULL_PARAM(pOpData);
776 	LAC_CHECK_NULL_PARAM(pOpData->sessionCtx);
777 	LAC_CHECK_NULL_PARAM(pSrcBuffer);
778 	LAC_CHECK_NULL_PARAM(pDstBuffer);
779 
780 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pOpData->sessionCtx);
781 	LAC_CHECK_NULL_PARAM(pSessionDesc);
782 
783 	/*check whether Payload size is zero for CHACHA-POLY*/
784 	if ((CPA_CY_SYM_CIPHER_CHACHA == pSessionDesc->cipherAlgorithm) &&
785 	    (CPA_CY_SYM_HASH_POLY == pSessionDesc->hashAlgorithm) &&
786 	    (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
787 		if (!pOpData->messageLenToCipherInBytes) {
788 			LAC_INVALID_PARAM_LOG(
789 			    "Invalid messageLenToCipherInBytes for CHACHA-POLY");
790 			return CPA_STATUS_INVALID_PARAM;
791 		}
792 	}
793 
794 	/* If synchronous Operation - Callback function stored in the session
795 	 * descriptor so a flag is set in the perform to indicate that
796 	 * the perform is being re-called for the synchronous operation */
797 	if ((LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb) &&
798 	    isAsyncMode == CPA_TRUE) {
799 		CpaBoolean opResult = CPA_FALSE;
800 		lac_sync_op_data_t *pSyncCallbackData = NULL;
801 
802 		status = LacSync_CreateSyncCookie(&pSyncCallbackData);
803 
804 		if (CPA_STATUS_SUCCESS == status) {
805 			status = LacSym_Perform(instanceHandle,
806 						pSyncCallbackData,
807 						pOpData,
808 						pSrcBuffer,
809 						pDstBuffer,
810 						pVerifyResult,
811 						CPA_FALSE);
812 		} else {
813 			/* Failure allocating sync cookie */
814 			LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle);
815 			return status;
816 		}
817 
818 		if (CPA_STATUS_SUCCESS == status) {
819 			CpaStatus syncStatus = CPA_STATUS_SUCCESS;
820 			syncStatus = LacSync_WaitForCallback(
821 			    pSyncCallbackData,
822 			    LAC_SYM_SYNC_CALLBACK_TIMEOUT,
823 			    &status,
824 			    &opResult);
825 			/* If callback doesn't come back */
826 			if (CPA_STATUS_SUCCESS != syncStatus) {
827 				LAC_SYM_STAT_INC(numSymOpCompletedErrors,
828 						 instanceHandle);
829 				LAC_LOG_ERROR("Callback timed out");
830 				status = syncStatus;
831 			}
832 		} else {
833 			/* As the Request was not sent the Callback will never
834 			 * be called, so need to indicate that we're finished
835 			 * with cookie so it can be destroyed. */
836 			LacSync_SetSyncCookieComplete(pSyncCallbackData);
837 		}
838 
839 		if (CPA_STATUS_SUCCESS == status) {
840 			if (NULL != pVerifyResult) {
841 				*pVerifyResult = opResult;
842 			}
843 		}
844 
845 		LacSync_DestroySyncCookie(&pSyncCallbackData);
846 		return status;
847 	}
848 
849 	status =
850 	    LacSymPerform_BufferParamCheck((const CpaBufferList *)pSrcBuffer,
851 					   pDstBuffer,
852 					   pSessionDesc,
853 					   pOpData);
854 	LAC_CHECK_STATUS(status);
855 
856 	if ((!pSessionDesc->digestIsAppended) &&
857 	    (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
858 		/* Check that pDigestResult is not NULL */
859 		LAC_CHECK_NULL_PARAM(pOpData->pDigestResult);
860 	}
861 
862 	status = LacAlgChain_Perform(instanceHandle,
863 				     pSessionDesc,
864 				     callbackTag,
865 				     pOpData,
866 				     pSrcBuffer,
867 				     pDstBuffer,
868 				     pVerifyResult);
869 
870 	if (CPA_STATUS_SUCCESS == status) {
871 		/* check for partial packet support for the session operation */
872 		if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) {
873 			LacSym_PartialPacketStateUpdate(
874 			    pOpData->packetType, &pSessionDesc->partialState);
875 		}
876 		/* increment #requests stat */
877 		LAC_SYM_STAT_INC(numSymOpRequests, instanceHandle);
878 	}
879 	/* Retry also results in the errors stat been incremented */
880 	else {
881 		/* increment #errors stat */
882 		LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle);
883 	}
884 	return status;
885 }
886 
887 /** @ingroup LacSym */
888 CpaStatus
cpaCySymPerformOp(const CpaInstanceHandle instanceHandle_in,void * callbackTag,const CpaCySymOpData * pOpData,const CpaBufferList * pSrcBuffer,CpaBufferList * pDstBuffer,CpaBoolean * pVerifyResult)889 cpaCySymPerformOp(const CpaInstanceHandle instanceHandle_in,
890 		  void *callbackTag,
891 		  const CpaCySymOpData *pOpData,
892 		  const CpaBufferList *pSrcBuffer,
893 		  CpaBufferList *pDstBuffer,
894 		  CpaBoolean *pVerifyResult)
895 {
896 	CpaInstanceHandle instanceHandle = NULL;
897 
898 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
899 		instanceHandle =
900 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
901 	} else {
902 		instanceHandle = instanceHandle_in;
903 	}
904 
905 	return LacSym_Perform(instanceHandle,
906 			      callbackTag,
907 			      pOpData,
908 			      pSrcBuffer,
909 			      pDstBuffer,
910 			      pVerifyResult,
911 			      CPA_TRUE);
912 }
913 
914 /** @ingroup LacSym */
915 CpaStatus
cpaCySymQueryStats(const CpaInstanceHandle instanceHandle_in,struct _CpaCySymStats * pSymStats)916 cpaCySymQueryStats(const CpaInstanceHandle instanceHandle_in,
917 		   struct _CpaCySymStats *pSymStats)
918 {
919 
920 	CpaInstanceHandle instanceHandle = NULL;
921 
922 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
923 		instanceHandle =
924 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
925 	} else {
926 		instanceHandle = instanceHandle_in;
927 	}
928 
929 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
930 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
931 				(SAL_SERVICE_TYPE_CRYPTO |
932 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
933 	LAC_CHECK_NULL_PARAM(pSymStats);
934 
935 	/* check if crypto service is running
936 	 * otherwise return an error */
937 	SAL_RUNNING_CHECK(instanceHandle);
938 
939 	/* copy the fields from the internal structure into the api defined
940 	 * structure */
941 	LacSym_Stats32CopyGet(instanceHandle, pSymStats);
942 	return CPA_STATUS_SUCCESS;
943 }
944 
945 /** @ingroup LacSym */
946 CpaStatus
cpaCySymQueryStats64(const CpaInstanceHandle instanceHandle_in,CpaCySymStats64 * pSymStats)947 cpaCySymQueryStats64(const CpaInstanceHandle instanceHandle_in,
948 		     CpaCySymStats64 *pSymStats)
949 {
950 
951 	CpaInstanceHandle instanceHandle = NULL;
952 
953 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
954 		instanceHandle =
955 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
956 	} else {
957 		instanceHandle = instanceHandle_in;
958 	}
959 
960 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
961 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
962 				(SAL_SERVICE_TYPE_CRYPTO |
963 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
964 	LAC_CHECK_NULL_PARAM(pSymStats);
965 
966 	/* check if crypto service is running
967 	 * otherwise return an error */
968 	SAL_RUNNING_CHECK(instanceHandle);
969 
970 	/* copy the fields from the internal structure into the api defined
971 	 * structure */
972 	LacSym_Stats64CopyGet(instanceHandle, pSymStats);
973 
974 	return CPA_STATUS_SUCCESS;
975 }
976 
977 /** @ingroup LacSym */
978 CpaStatus
cpaCySymSessionCtxGetSize(const CpaInstanceHandle instanceHandle_in,const CpaCySymSessionSetupData * pSessionSetupData,Cpa32U * pSessionCtxSizeInBytes)979 cpaCySymSessionCtxGetSize(const CpaInstanceHandle instanceHandle_in,
980 			  const CpaCySymSessionSetupData *pSessionSetupData,
981 			  Cpa32U *pSessionCtxSizeInBytes)
982 {
983 	CpaInstanceHandle instanceHandle = NULL;
984 
985 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
986 		instanceHandle =
987 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
988 	} else {
989 		instanceHandle = instanceHandle_in;
990 	}
991 
992 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
993 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
994 				(SAL_SERVICE_TYPE_CRYPTO |
995 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
996 	LAC_CHECK_NULL_PARAM(pSessionSetupData);
997 	LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
998 
999 	/* check crypto service is running otherwise return an error */
1000 	SAL_RUNNING_CHECK(instanceHandle);
1001 	*pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE;
1002 
1003 	return CPA_STATUS_SUCCESS;
1004 }
1005 
1006 /** @ingroup LacSym */
1007 CpaStatus
cpaCySymSessionCtxGetDynamicSize(const CpaInstanceHandle instanceHandle_in,const CpaCySymSessionSetupData * pSessionSetupData,Cpa32U * pSessionCtxSizeInBytes)1008 cpaCySymSessionCtxGetDynamicSize(
1009     const CpaInstanceHandle instanceHandle_in,
1010     const CpaCySymSessionSetupData *pSessionSetupData,
1011     Cpa32U *pSessionCtxSizeInBytes)
1012 {
1013 	CpaInstanceHandle instanceHandle = NULL;
1014 
1015 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
1016 		instanceHandle =
1017 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
1018 	} else {
1019 		instanceHandle = instanceHandle_in;
1020 	}
1021 
1022 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
1023 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
1024 				(SAL_SERVICE_TYPE_CRYPTO |
1025 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
1026 	LAC_CHECK_NULL_PARAM(pSessionSetupData);
1027 	LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
1028 
1029 	/* check crypto service is running otherwise return an error */
1030 	SAL_RUNNING_CHECK(instanceHandle);
1031 	/* Choose Session Context size */
1032 	getCtxSize(pSessionSetupData, pSessionCtxSizeInBytes);
1033 
1034 	return CPA_STATUS_SUCCESS;
1035 }
1036 
1037 void
getCtxSize(const CpaCySymSessionSetupData * pSessionSetupData,Cpa32U * pSessionCtxSizeInBytes)1038 getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData,
1039 	   Cpa32U *pSessionCtxSizeInBytes)
1040 {
1041 	/* using lac_session_desc_d1_t */
1042 	if ((pSessionSetupData->cipherSetupData.cipherAlgorithm !=
1043 	     CPA_CY_SYM_CIPHER_ARC4) &&
1044 	    (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
1045 	     CPA_CY_SYM_CIPHER_SNOW3G_UEA2) &&
1046 	    (pSessionSetupData->hashSetupData.hashAlgorithm !=
1047 	     CPA_CY_SYM_HASH_SNOW3G_UIA2) &&
1048 	    (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
1049 	     CPA_CY_SYM_CIPHER_AES_CCM) &&
1050 	    (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
1051 	     CPA_CY_SYM_CIPHER_AES_GCM) &&
1052 	    (pSessionSetupData->hashSetupData.hashMode !=
1053 	     CPA_CY_SYM_HASH_MODE_AUTH) &&
1054 	    (pSessionSetupData->hashSetupData.hashMode !=
1055 	     CPA_CY_SYM_HASH_MODE_NESTED) &&
1056 	    (pSessionSetupData->partialsNotRequired == CPA_TRUE)) {
1057 		*pSessionCtxSizeInBytes = LAC_SYM_SESSION_D1_SIZE;
1058 	}
1059 	/* using lac_session_desc_d2_t */
1060 	else if (((pSessionSetupData->cipherSetupData.cipherAlgorithm ==
1061 		   CPA_CY_SYM_CIPHER_AES_CCM) ||
1062 		  (pSessionSetupData->cipherSetupData.cipherAlgorithm ==
1063 		   CPA_CY_SYM_CIPHER_AES_GCM)) &&
1064 		 (pSessionSetupData->partialsNotRequired == CPA_TRUE)) {
1065 		*pSessionCtxSizeInBytes = LAC_SYM_SESSION_D2_SIZE;
1066 	}
1067 	/* using lac_session_desc_t */
1068 	else {
1069 		*pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE;
1070 	}
1071 }
1072 
1073 /**
1074  ******************************************************************************
1075  * @ingroup LacSym
1076  *****************************************************************************/
1077 CpaStatus
cpaCyBufferListGetMetaSize(const CpaInstanceHandle instanceHandle_in,Cpa32U numBuffers,Cpa32U * pSizeInBytes)1078 cpaCyBufferListGetMetaSize(const CpaInstanceHandle instanceHandle_in,
1079 			   Cpa32U numBuffers,
1080 			   Cpa32U *pSizeInBytes)
1081 {
1082 
1083 	CpaInstanceHandle instanceHandle = NULL;
1084 
1085 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
1086 		instanceHandle =
1087 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
1088 	} else {
1089 		instanceHandle = instanceHandle_in;
1090 	}
1091 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
1092 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
1093 				(SAL_SERVICE_TYPE_CRYPTO |
1094 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
1095 	LAC_CHECK_NULL_PARAM(pSizeInBytes);
1096 
1097 	/* In the case of zero buffers we still need to allocate one
1098 	 * descriptor to pass to the firmware */
1099 	if (0 == numBuffers) {
1100 		numBuffers = 1;
1101 	}
1102 
1103 	/* Note: icp_buffer_list_desc_t is 8 bytes in size and
1104 	 * icp_flat_buffer_desc_t is 16 bytes in size. Therefore if
1105 	 * icp_buffer_list_desc_t is aligned
1106 	 * so will each icp_flat_buffer_desc_t structure */
1107 
1108 	*pSizeInBytes = sizeof(icp_buffer_list_desc_t) +
1109 	    (sizeof(icp_flat_buffer_desc_t) * numBuffers) +
1110 	    ICP_DESCRIPTOR_ALIGNMENT_BYTES;
1111 
1112 	return CPA_STATUS_SUCCESS;
1113 }
1114