1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 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 /**
341  * @ingroup LacSym
342  * Function which perform parameter checks on data buffers for symmetric
343  * crypto operations
344  *
345  * @param[in] pSrcBuffer          Pointer to source buffer list
346  * @param[in] pDstBuffer          Pointer to destination buffer list
347  * @param[in] pSessionDesc        Pointer to session descriptor
348  * @param[in] pOpData             Pointer to CryptoSymOpData.
349  *
350  * @retval CPA_STATUS_SUCCESS        The operation succeeded
351  * @retval CPA_STATUS_INVALID_PARAM  An invalid parameter value was found
352  */
353 
354 static CpaStatus
LacSymPerform_BufferParamCheck(const CpaBufferList * const pSrcBuffer,const CpaBufferList * const pDstBuffer,const lac_session_desc_t * const pSessionDesc,const CpaCySymOpData * const pOpData)355 LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer,
356 			       const CpaBufferList *const pDstBuffer,
357 			       const lac_session_desc_t *const pSessionDesc,
358 			       const CpaCySymOpData *const pOpData)
359 {
360 	Cpa64U srcBufferLen = 0, dstBufferLen = 0;
361 	CpaStatus status = CPA_STATUS_SUCCESS;
362 
363 	/* verify packet type is in correct range */
364 	switch (pOpData->packetType) {
365 	case CPA_CY_SYM_PACKET_TYPE_FULL:
366 	case CPA_CY_SYM_PACKET_TYPE_PARTIAL:
367 	case CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL:
368 		break;
369 	default: {
370 		LAC_INVALID_PARAM_LOG("packetType");
371 		return CPA_STATUS_INVALID_PARAM;
372 	}
373 	}
374 
375 	if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation &&
376 	       CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) &&
377 	      (0 == pOpData->messageLenToHashInBytes))) {
378 		if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(
379 			pSessionDesc->cipherAlgorithm,
380 			pSessionDesc->hashAlgorithm)) {
381 			status = LacBuffDesc_BufferListVerifyNull(
382 			    pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT);
383 		} else {
384 			status = LacBuffDesc_BufferListVerify(
385 			    pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT);
386 		}
387 		if (CPA_STATUS_SUCCESS != status) {
388 			LAC_INVALID_PARAM_LOG("Source buffer invalid");
389 			return CPA_STATUS_INVALID_PARAM;
390 		}
391 	} else {
392 		/* check MetaData !NULL */
393 		if (NULL == pSrcBuffer->pPrivateMetaData) {
394 			LAC_INVALID_PARAM_LOG(
395 			    "Source buffer MetaData cannot be NULL");
396 			return CPA_STATUS_INVALID_PARAM;
397 		}
398 	}
399 
400 	/* out of place checks */
401 	if (pSrcBuffer != pDstBuffer) {
402 		/* exception for this check is zero length hash requests to
403 		 * allow */
404 		/* for srcBufflen=DstBufferLen=0 */
405 		if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation &&
406 		       CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) &&
407 		      (0 == pOpData->messageLenToHashInBytes))) {
408 			/* Verify buffer(s) for dest packet & return packet
409 			 * length */
410 			if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(
411 				pSessionDesc->cipherAlgorithm,
412 				pSessionDesc->hashAlgorithm)) {
413 				status = LacBuffDesc_BufferListVerifyNull(
414 				    pDstBuffer,
415 				    &dstBufferLen,
416 				    LAC_NO_ALIGNMENT_SHIFT);
417 			} else {
418 				status = LacBuffDesc_BufferListVerify(
419 				    pDstBuffer,
420 				    &dstBufferLen,
421 				    LAC_NO_ALIGNMENT_SHIFT);
422 			}
423 			if (CPA_STATUS_SUCCESS != status) {
424 				LAC_INVALID_PARAM_LOG(
425 				    "Destination buffer invalid");
426 				return CPA_STATUS_INVALID_PARAM;
427 			}
428 		} else {
429 			/* check MetaData !NULL */
430 			if (NULL == pDstBuffer->pPrivateMetaData) {
431 				LAC_INVALID_PARAM_LOG(
432 				    "Dest buffer MetaData cannot be NULL");
433 				return CPA_STATUS_INVALID_PARAM;
434 			}
435 		}
436 		/* Check that src Buffer and dst Buffer Lengths are equal */
437 		/* CCM output needs to be longer than input buffer for appending
438 		 * tag*/
439 		if (srcBufferLen != dstBufferLen &&
440 		    pSessionDesc->cipherAlgorithm !=
441 			CPA_CY_SYM_CIPHER_AES_CCM) {
442 			LAC_INVALID_PARAM_LOG(
443 			    "Source and Dest buffer lengths need to be equal ");
444 			return CPA_STATUS_INVALID_PARAM;
445 		}
446 	}
447 
448 	/* check for partial packet suport for the session operation */
449 	if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) {
450 		if (CPA_FALSE == pSessionDesc->isPartialSupported) {
451 			/* return out here to simplify cleanup */
452 			LAC_INVALID_PARAM_LOG(
453 			    "Partial packets not supported for operation");
454 			return CPA_STATUS_INVALID_PARAM;
455 		} else {
456 			/* This function checks to see if the partial packet
457 			 * sequence is correct */
458 			if (CPA_STATUS_SUCCESS !=
459 			    LacSym_PartialPacketStateCheck(
460 				pOpData->packetType,
461 				pSessionDesc->partialState)) {
462 				LAC_INVALID_PARAM_LOG("Partial packet Type");
463 				return CPA_STATUS_INVALID_PARAM;
464 			}
465 		}
466 	}
467 	return CPA_STATUS_SUCCESS;
468 }
469 
470 /** @ingroup LacSym */
471 CpaStatus
cpaCySymInitSession(const CpaInstanceHandle instanceHandle_in,const CpaCySymCbFunc pSymCb,const CpaCySymSessionSetupData * pSessionSetupData,CpaCySymSessionCtx pSessionCtx)472 cpaCySymInitSession(const CpaInstanceHandle instanceHandle_in,
473 		    const CpaCySymCbFunc pSymCb,
474 		    const CpaCySymSessionSetupData *pSessionSetupData,
475 		    CpaCySymSessionCtx pSessionCtx)
476 {
477 	CpaStatus status = CPA_STATUS_SUCCESS;
478 	CpaInstanceHandle instanceHandle = NULL;
479 	sal_service_t *pService = NULL;
480 
481 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
482 		instanceHandle =
483 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
484 	} else {
485 		instanceHandle = instanceHandle_in;
486 	}
487 
488 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
489 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
490 				(SAL_SERVICE_TYPE_CRYPTO |
491 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
492 
493 	pService = (sal_service_t *)instanceHandle;
494 
495 	/* check crypto service is running otherwise return an error */
496 	SAL_RUNNING_CHECK(pService);
497 
498 	status = LacSym_InitSession(instanceHandle,
499 				    pSymCb,
500 				    pSessionSetupData,
501 				    CPA_FALSE, /* isDPSession */
502 				    pSessionCtx);
503 
504 	if (CPA_STATUS_SUCCESS == status) {
505 		/* Increment the stats for a session registered successfully */
506 		LAC_SYM_STAT_INC(numSessionsInitialized, instanceHandle);
507 	} else /* if there was an error */
508 	{
509 		LAC_SYM_STAT_INC(numSessionErrors, instanceHandle);
510 	}
511 
512 	return status;
513 }
514 
515 CpaStatus
cpaCySymSessionInUse(CpaCySymSessionCtx pSessionCtx,CpaBoolean * pSessionInUse)516 cpaCySymSessionInUse(CpaCySymSessionCtx pSessionCtx, CpaBoolean *pSessionInUse)
517 {
518 	CpaStatus status = CPA_STATUS_SUCCESS;
519 	lac_session_desc_t *pSessionDesc = NULL;
520 
521 	LAC_CHECK_NULL_PARAM(pSessionInUse);
522 	LAC_CHECK_INSTANCE_HANDLE(pSessionCtx);
523 
524 	*pSessionInUse = CPA_FALSE;
525 
526 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx);
527 
528 	/* If there are pending requests */
529 	if (pSessionDesc->isDPSession) {
530 		if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount)))
531 			*pSessionInUse = CPA_TRUE;
532 	} else {
533 		if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount)))
534 			*pSessionInUse = CPA_TRUE;
535 	}
536 
537 	return status;
538 }
539 
540 CpaStatus
LacSym_InitSession(const CpaInstanceHandle instanceHandle,const CpaCySymCbFunc pSymCb,const CpaCySymSessionSetupData * pSessionSetupData,const CpaBoolean isDPSession,CpaCySymSessionCtx pSessionCtx)541 LacSym_InitSession(const CpaInstanceHandle instanceHandle,
542 		   const CpaCySymCbFunc pSymCb,
543 		   const CpaCySymSessionSetupData *pSessionSetupData,
544 		   const CpaBoolean isDPSession,
545 		   CpaCySymSessionCtx pSessionCtx)
546 {
547 	CpaStatus status = CPA_STATUS_SUCCESS;
548 	lac_session_desc_t *pSessionDesc = NULL;
549 	Cpa32U sessionCtxSizeInBytes = 0;
550 	CpaPhysicalAddr physAddress = 0;
551 	CpaPhysicalAddr physAddressAligned = 0;
552 	sal_service_t *pService = NULL;
553 	const CpaCySymCipherSetupData *pCipherSetupData = NULL;
554 	const CpaCySymHashSetupData *pHashSetupData = NULL;
555 
556 	/* Instance param checking done by calling function */
557 
558 	LAC_CHECK_NULL_PARAM(pSessionSetupData);
559 	LAC_CHECK_NULL_PARAM(pSessionCtx);
560 	status = LacSymSession_ParamCheck(instanceHandle, pSessionSetupData);
561 	LAC_CHECK_STATUS(status);
562 
563 	/* set the session priority for QAT AL*/
564 	if ((CPA_CY_PRIORITY_HIGH == pSessionSetupData->sessionPriority) ||
565 	    (CPA_CY_PRIORITY_NORMAL == pSessionSetupData->sessionPriority)) {
566 		// do nothing - clean up this code. use RANGE macro
567 	} else {
568 		LAC_INVALID_PARAM_LOG("sessionPriority");
569 		return CPA_STATUS_INVALID_PARAM;
570 	}
571 
572 
573 	pCipherSetupData = &pSessionSetupData->cipherSetupData;
574 	pHashSetupData = &pSessionSetupData->hashSetupData;
575 
576 	pService = (sal_service_t *)instanceHandle;
577 
578 	/* Re-align the session structure to 64 byte alignment */
579 	physAddress =
580 	    LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService),
581 					 (Cpa8U *)pSessionCtx + sizeof(void *));
582 
583 	if (0 == physAddress) {
584 		LAC_LOG_ERROR(
585 		    "Unable to get the physical address of the session\n");
586 		return CPA_STATUS_FAIL;
587 	}
588 
589 	physAddressAligned =
590 	    LAC_ALIGN_POW2_ROUNDUP(physAddress, LAC_64BYTE_ALIGNMENT);
591 
592 	pSessionDesc = (lac_session_desc_t *)
593 	    /* Move the session pointer by the physical offset
594 	    between aligned and unaligned memory */
595 	    ((Cpa8U *)pSessionCtx + sizeof(void *) +
596 	     (physAddressAligned - physAddress));
597 
598 	/* save the aligned pointer in the first bytes (size of unsigned long)
599 	 * of the session memory */
600 	*((LAC_ARCH_UINT *)pSessionCtx) = (LAC_ARCH_UINT)pSessionDesc;
601 
602 	/* start off with a clean session */
603 	/* Choose Session Context size */
604 	getCtxSize(pSessionSetupData, &sessionCtxSizeInBytes);
605 	switch (sessionCtxSizeInBytes) {
606 	case LAC_SYM_SESSION_D1_SIZE:
607 		memset(pSessionDesc, 0, sizeof(lac_session_desc_d1_t));
608 		break;
609 	case LAC_SYM_SESSION_D2_SIZE:
610 		memset(pSessionDesc, 0, sizeof(lac_session_desc_d2_t));
611 		break;
612 	default:
613 		memset(pSessionDesc, 0, sizeof(lac_session_desc_t));
614 		break;
615 	}
616 
617 	/* Setup content descriptor info structure
618 	 * assumption that content descriptor is the first field in
619 	 * in the session descriptor */
620 	pSessionDesc->contentDescInfo.pData = (Cpa8U *)pSessionDesc;
621 	pSessionDesc->contentDescInfo.hardwareSetupBlockPhys =
622 	    physAddressAligned;
623 
624 	pSessionDesc->contentDescOptimisedInfo.pData =
625 	    ((Cpa8U *)pSessionDesc + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE);
626 	pSessionDesc->contentDescOptimisedInfo.hardwareSetupBlockPhys =
627 	    (physAddressAligned + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE);
628 
629 	/* Set the Common Session Information */
630 	pSessionDesc->symOperation = pSessionSetupData->symOperation;
631 
632 	if (CPA_FALSE == isDPSession) {
633 		/* For asynchronous - use the user supplied callback
634 		 * for synchronous - use the internal synchronous callback */
635 		pSessionDesc->pSymCb = ((void *)NULL != (void *)pSymCb) ?
636 			  pSymCb :
637 			  LacSync_GenBufListVerifyCb;
638 	}
639 
640 	pSessionDesc->isDPSession = isDPSession;
641 	if ((CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm) ||
642 	    (CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) ||
643 	    (CPA_CY_SYM_HASH_AES_CCM == pHashSetupData->hashAlgorithm) ||
644 	    (CPA_CY_SYM_CIPHER_CHACHA == pCipherSetupData->cipherAlgorithm) ||
645 	    (CPA_CY_SYM_CIPHER_ARC4 == pCipherSetupData->cipherAlgorithm)) {
646 		pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgFull;
647 	} else {
648 		pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgOpt;
649 	}
650 
651 	if (CPA_STATUS_SUCCESS == status) {
652 		/* Session set up via API call (not internal one) */
653 		/* Services such as DRBG call the crypto api as part of their
654 		 * service hence the need to for the flag, it is needed to
655 		 * distinguish between an internal and external session.
656 		 */
657 		pSessionDesc->internalSession = CPA_FALSE;
658 
659 		status = LacAlgChain_SessionInit(instanceHandle,
660 						 pSessionSetupData,
661 						 pSessionDesc);
662 	}
663 	return status;
664 }
665 
666 /** @ingroup LacSym */
667 CpaStatus
cpaCySymRemoveSession(const CpaInstanceHandle instanceHandle_in,CpaCySymSessionCtx pSessionCtx)668 cpaCySymRemoveSession(const CpaInstanceHandle instanceHandle_in,
669 		      CpaCySymSessionCtx pSessionCtx)
670 {
671 	lac_session_desc_t *pSessionDesc = NULL;
672 	CpaStatus status = CPA_STATUS_SUCCESS;
673 	CpaInstanceHandle instanceHandle = NULL;
674 	Cpa64U numPendingRequests = 0;
675 
676 
677 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
678 		instanceHandle =
679 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
680 	} else {
681 		instanceHandle = instanceHandle_in;
682 	}
683 
684 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
685 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
686 				(SAL_SERVICE_TYPE_CRYPTO |
687 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
688 	LAC_CHECK_NULL_PARAM(pSessionCtx);
689 
690 	/* check crypto service is running otherwise return an error */
691 	SAL_RUNNING_CHECK(instanceHandle);
692 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx);
693 
694 	LAC_CHECK_NULL_PARAM(pSessionDesc);
695 
696 	if (CPA_TRUE == pSessionDesc->isDPSession) {
697 		/*
698 		 * Based on one instance, we can initialize multiple sessions.
699 		 * For example, we can initialize the session "X" and session
700 		 * "Y" with the same instance "A". If there is no operation
701 		 * pending for session "X", we can remove the session "X".
702 		 *
703 		 * Now we only check the @pSessionDesc->pendingDpCbCount, if it
704 		 * becomes zero, we can remove the session.
705 		 *
706 		 * Why?
707 		 *   (1) We increase it in the cpaCySymDpEnqueueOp/
708 		 *       cpaCySymDpEnqueueOpBatch.
709 		 *   (2) We decrease it in the LacSymCb_ProcessCallback.
710 		 *
711 		 * If the @pSessionDesc->pendingDpCbCount becomes zero, it means
712 		 * there is no operation pending for the session "X" anymore, so
713 		 * we can remove this session. Maybe there is still some
714 		 * requests left in the instance's ring
715 		 * (icp_adf_queueDataToSend() returns true), but the request
716 		 * does not belong to "X", it belongs to session "Y".
717 		 */
718 		numPendingRequests =
719 		    qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount));
720 	} else {
721 		numPendingRequests =
722 		    qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount));
723 	}
724 
725 	/* If there are pending requests */
726 	if (0 != numPendingRequests) {
727 		QAT_UTILS_LOG("There are %llu requests pending\n",
728 			      (unsigned long long)numPendingRequests);
729 		status = CPA_STATUS_RETRY;
730 		if (CPA_TRUE == pSessionDesc->isDPSession) {
731 			/* Need to update tail if messages queue on tx hi ring
732 			 for data plane api */
733 			icp_comms_trans_handle trans_handle =
734 			    ((sal_crypto_service_t *)instanceHandle)
735 				->trans_handle_sym_tx;
736 
737 			if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
738 				/* process the remaining messages in the ring */
739 				QAT_UTILS_LOG("Submitting enqueued requests\n");
740 				/*
741 				 * SalQatMsg_updateQueueTail
742 				 */
743 				SalQatMsg_updateQueueTail(trans_handle);
744 				return status;
745 			}
746 		}
747 	}
748 	if (CPA_STATUS_SUCCESS == status) {
749 		LAC_SPINLOCK_DESTROY(&pSessionDesc->requestQueueLock);
750 		if (CPA_FALSE == pSessionDesc->isDPSession) {
751 			LAC_SYM_STAT_INC(numSessionsRemoved, instanceHandle);
752 		}
753 	} else if (CPA_FALSE == pSessionDesc->isDPSession) {
754 		LAC_SYM_STAT_INC(numSessionErrors, instanceHandle);
755 	}
756 	return status;
757 }
758 
759 /** @ingroup LacSym */
760 static CpaStatus
LacSym_Perform(const CpaInstanceHandle instanceHandle,void * callbackTag,const CpaCySymOpData * pOpData,const CpaBufferList * pSrcBuffer,CpaBufferList * pDstBuffer,CpaBoolean * pVerifyResult,CpaBoolean isAsyncMode)761 LacSym_Perform(const CpaInstanceHandle instanceHandle,
762 	       void *callbackTag,
763 	       const CpaCySymOpData *pOpData,
764 	       const CpaBufferList *pSrcBuffer,
765 	       CpaBufferList *pDstBuffer,
766 	       CpaBoolean *pVerifyResult,
767 	       CpaBoolean isAsyncMode)
768 {
769 	lac_session_desc_t *pSessionDesc = NULL;
770 	CpaStatus status = CPA_STATUS_SUCCESS;
771 
772 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
773 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
774 				(SAL_SERVICE_TYPE_CRYPTO |
775 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
776 	/* check crypto service is running otherwise return an error */
777 	SAL_RUNNING_CHECK(instanceHandle);
778 	LAC_CHECK_NULL_PARAM(pOpData);
779 	LAC_CHECK_NULL_PARAM(pOpData->sessionCtx);
780 	LAC_CHECK_NULL_PARAM(pSrcBuffer);
781 	LAC_CHECK_NULL_PARAM(pDstBuffer);
782 
783 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pOpData->sessionCtx);
784 	LAC_CHECK_NULL_PARAM(pSessionDesc);
785 
786 	/*check whether Payload size is zero for CHACHA-POLY*/
787 	if ((CPA_CY_SYM_CIPHER_CHACHA == pSessionDesc->cipherAlgorithm) &&
788 	    (CPA_CY_SYM_HASH_POLY == pSessionDesc->hashAlgorithm) &&
789 	    (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
790 		if (!pOpData->messageLenToCipherInBytes) {
791 			LAC_INVALID_PARAM_LOG(
792 			    "Invalid messageLenToCipherInBytes for CHACHA-POLY");
793 			return CPA_STATUS_INVALID_PARAM;
794 		}
795 	}
796 
797 
798 	/* If synchronous Operation - Callback function stored in the session
799 	 * descriptor so a flag is set in the perform to indicate that
800 	 * the perform is being re-called for the synchronous operation */
801 	if ((LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb) &&
802 	    isAsyncMode == CPA_TRUE) {
803 		CpaBoolean opResult = CPA_FALSE;
804 		lac_sync_op_data_t *pSyncCallbackData = NULL;
805 
806 		status = LacSync_CreateSyncCookie(&pSyncCallbackData);
807 
808 		if (CPA_STATUS_SUCCESS == status) {
809 			status = LacSym_Perform(instanceHandle,
810 						pSyncCallbackData,
811 						pOpData,
812 						pSrcBuffer,
813 						pDstBuffer,
814 						pVerifyResult,
815 						CPA_FALSE);
816 		} else {
817 			/* Failure allocating sync cookie */
818 			LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle);
819 			return status;
820 		}
821 
822 		if (CPA_STATUS_SUCCESS == status) {
823 			CpaStatus syncStatus = CPA_STATUS_SUCCESS;
824 			syncStatus = LacSync_WaitForCallback(
825 			    pSyncCallbackData,
826 			    LAC_SYM_SYNC_CALLBACK_TIMEOUT,
827 			    &status,
828 			    &opResult);
829 			/* If callback doesn't come back */
830 			if (CPA_STATUS_SUCCESS != syncStatus) {
831 				LAC_SYM_STAT_INC(numSymOpCompletedErrors,
832 						 instanceHandle);
833 				LAC_LOG_ERROR("Callback timed out");
834 				status = syncStatus;
835 			}
836 		} else {
837 			/* As the Request was not sent the Callback will never
838 			 * be called, so need to indicate that we're finished
839 			 * with cookie so it can be destroyed. */
840 			LacSync_SetSyncCookieComplete(pSyncCallbackData);
841 		}
842 
843 		if (CPA_STATUS_SUCCESS == status) {
844 			if (NULL != pVerifyResult) {
845 				*pVerifyResult = opResult;
846 			}
847 		}
848 
849 		LacSync_DestroySyncCookie(&pSyncCallbackData);
850 		return status;
851 	}
852 
853 	status =
854 	    LacSymPerform_BufferParamCheck((const CpaBufferList *)pSrcBuffer,
855 					   pDstBuffer,
856 					   pSessionDesc,
857 					   pOpData);
858 	LAC_CHECK_STATUS(status);
859 
860 	if ((!pSessionDesc->digestIsAppended) &&
861 	    (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
862 		/* Check that pDigestResult is not NULL */
863 		LAC_CHECK_NULL_PARAM(pOpData->pDigestResult);
864 	}
865 
866 	status = LacAlgChain_Perform(instanceHandle,
867 				     pSessionDesc,
868 				     callbackTag,
869 				     pOpData,
870 				     pSrcBuffer,
871 				     pDstBuffer,
872 				     pVerifyResult);
873 
874 	if (CPA_STATUS_SUCCESS == status) {
875 		/* check for partial packet suport for the session operation */
876 		if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) {
877 			LacSym_PartialPacketStateUpdate(
878 			    pOpData->packetType, &pSessionDesc->partialState);
879 		}
880 		/* increment #requests stat */
881 		LAC_SYM_STAT_INC(numSymOpRequests, instanceHandle);
882 	}
883 	/* Retry also results in the errors stat been incremented */
884 	else {
885 		/* increment #errors stat */
886 		LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle);
887 	}
888 	return status;
889 }
890 
891 /** @ingroup LacSym */
892 CpaStatus
cpaCySymPerformOp(const CpaInstanceHandle instanceHandle_in,void * callbackTag,const CpaCySymOpData * pOpData,const CpaBufferList * pSrcBuffer,CpaBufferList * pDstBuffer,CpaBoolean * pVerifyResult)893 cpaCySymPerformOp(const CpaInstanceHandle instanceHandle_in,
894 		  void *callbackTag,
895 		  const CpaCySymOpData *pOpData,
896 		  const CpaBufferList *pSrcBuffer,
897 		  CpaBufferList *pDstBuffer,
898 		  CpaBoolean *pVerifyResult)
899 {
900 	CpaInstanceHandle instanceHandle = NULL;
901 
902 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
903 		instanceHandle =
904 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
905 	} else {
906 		instanceHandle = instanceHandle_in;
907 	}
908 
909 	return LacSym_Perform(instanceHandle,
910 			      callbackTag,
911 			      pOpData,
912 			      pSrcBuffer,
913 			      pDstBuffer,
914 			      pVerifyResult,
915 			      CPA_TRUE);
916 }
917 
918 /** @ingroup LacSym */
919 CpaStatus
cpaCySymQueryStats(const CpaInstanceHandle instanceHandle_in,struct _CpaCySymStats * pSymStats)920 cpaCySymQueryStats(const CpaInstanceHandle instanceHandle_in,
921 		   struct _CpaCySymStats *pSymStats)
922 {
923 
924 	CpaInstanceHandle instanceHandle = NULL;
925 
926 
927 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
928 		instanceHandle =
929 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
930 	} else {
931 		instanceHandle = instanceHandle_in;
932 	}
933 
934 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
935 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
936 				(SAL_SERVICE_TYPE_CRYPTO |
937 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
938 	LAC_CHECK_NULL_PARAM(pSymStats);
939 
940 	/* check if crypto service is running
941 	 * otherwise return an error */
942 	SAL_RUNNING_CHECK(instanceHandle);
943 
944 	/* copy the fields from the internal structure into the api defined
945 	 * structure */
946 	LacSym_Stats32CopyGet(instanceHandle, pSymStats);
947 	return CPA_STATUS_SUCCESS;
948 }
949 
950 /** @ingroup LacSym */
951 CpaStatus
cpaCySymQueryStats64(const CpaInstanceHandle instanceHandle_in,CpaCySymStats64 * pSymStats)952 cpaCySymQueryStats64(const CpaInstanceHandle instanceHandle_in,
953 		     CpaCySymStats64 *pSymStats)
954 {
955 
956 	CpaInstanceHandle instanceHandle = NULL;
957 
958 
959 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
960 		instanceHandle =
961 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
962 	} else {
963 		instanceHandle = instanceHandle_in;
964 	}
965 
966 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
967 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
968 				(SAL_SERVICE_TYPE_CRYPTO |
969 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
970 	LAC_CHECK_NULL_PARAM(pSymStats);
971 
972 	/* check if crypto service is running
973 	 * otherwise return an error */
974 	SAL_RUNNING_CHECK(instanceHandle);
975 
976 	/* copy the fields from the internal structure into the api defined
977 	 * structure */
978 	LacSym_Stats64CopyGet(instanceHandle, pSymStats);
979 
980 	return CPA_STATUS_SUCCESS;
981 }
982 
983 /** @ingroup LacSym */
984 CpaStatus
cpaCySymSessionCtxGetSize(const CpaInstanceHandle instanceHandle_in,const CpaCySymSessionSetupData * pSessionSetupData,Cpa32U * pSessionCtxSizeInBytes)985 cpaCySymSessionCtxGetSize(const CpaInstanceHandle instanceHandle_in,
986 			  const CpaCySymSessionSetupData *pSessionSetupData,
987 			  Cpa32U *pSessionCtxSizeInBytes)
988 {
989 	CpaInstanceHandle instanceHandle = NULL;
990 
991 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
992 		instanceHandle =
993 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
994 	} else {
995 		instanceHandle = instanceHandle_in;
996 	}
997 
998 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
999 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
1000 				(SAL_SERVICE_TYPE_CRYPTO |
1001 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
1002 	LAC_CHECK_NULL_PARAM(pSessionSetupData);
1003 	LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
1004 
1005 	/* check crypto service is running otherwise return an error */
1006 	SAL_RUNNING_CHECK(instanceHandle);
1007 	*pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE;
1008 
1009 	return CPA_STATUS_SUCCESS;
1010 }
1011 
1012 /** @ingroup LacSym */
1013 CpaStatus
cpaCySymSessionCtxGetDynamicSize(const CpaInstanceHandle instanceHandle_in,const CpaCySymSessionSetupData * pSessionSetupData,Cpa32U * pSessionCtxSizeInBytes)1014 cpaCySymSessionCtxGetDynamicSize(
1015     const CpaInstanceHandle instanceHandle_in,
1016     const CpaCySymSessionSetupData *pSessionSetupData,
1017     Cpa32U *pSessionCtxSizeInBytes)
1018 {
1019 	CpaInstanceHandle instanceHandle = NULL;
1020 
1021 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
1022 		instanceHandle =
1023 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
1024 	} else {
1025 		instanceHandle = instanceHandle_in;
1026 	}
1027 
1028 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
1029 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
1030 				(SAL_SERVICE_TYPE_CRYPTO |
1031 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
1032 	LAC_CHECK_NULL_PARAM(pSessionSetupData);
1033 	LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
1034 
1035 	/* check crypto service is running otherwise return an error */
1036 	SAL_RUNNING_CHECK(instanceHandle);
1037 	/* Choose Session Context size */
1038 	getCtxSize(pSessionSetupData, pSessionCtxSizeInBytes);
1039 
1040 
1041 	return CPA_STATUS_SUCCESS;
1042 }
1043 
1044 void
getCtxSize(const CpaCySymSessionSetupData * pSessionSetupData,Cpa32U * pSessionCtxSizeInBytes)1045 getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData,
1046 	   Cpa32U *pSessionCtxSizeInBytes)
1047 {
1048 	/* using lac_session_desc_d1_t */
1049 	if ((pSessionSetupData->cipherSetupData.cipherAlgorithm !=
1050 	     CPA_CY_SYM_CIPHER_ARC4) &&
1051 	    (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
1052 	     CPA_CY_SYM_CIPHER_SNOW3G_UEA2) &&
1053 	    (pSessionSetupData->hashSetupData.hashAlgorithm !=
1054 	     CPA_CY_SYM_HASH_SNOW3G_UIA2) &&
1055 	    (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
1056 	     CPA_CY_SYM_CIPHER_AES_CCM) &&
1057 	    (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
1058 	     CPA_CY_SYM_CIPHER_AES_GCM) &&
1059 	    (pSessionSetupData->hashSetupData.hashMode !=
1060 	     CPA_CY_SYM_HASH_MODE_AUTH) &&
1061 	    (pSessionSetupData->hashSetupData.hashMode !=
1062 	     CPA_CY_SYM_HASH_MODE_NESTED) &&
1063 	    (pSessionSetupData->partialsNotRequired == CPA_TRUE)) {
1064 		*pSessionCtxSizeInBytes = LAC_SYM_SESSION_D1_SIZE;
1065 	}
1066 	/* using lac_session_desc_d2_t */
1067 	else if (((pSessionSetupData->cipherSetupData.cipherAlgorithm ==
1068 		   CPA_CY_SYM_CIPHER_AES_CCM) ||
1069 		  (pSessionSetupData->cipherSetupData.cipherAlgorithm ==
1070 		   CPA_CY_SYM_CIPHER_AES_GCM)) &&
1071 		 (pSessionSetupData->partialsNotRequired == CPA_TRUE)) {
1072 		*pSessionCtxSizeInBytes = LAC_SYM_SESSION_D2_SIZE;
1073 	}
1074 	/* using lac_session_desc_t */
1075 	else {
1076 		*pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE;
1077 	}
1078 }
1079 
1080 /**
1081  ******************************************************************************
1082  * @ingroup LacSym
1083  *****************************************************************************/
1084 CpaStatus
cpaCyBufferListGetMetaSize(const CpaInstanceHandle instanceHandle_in,Cpa32U numBuffers,Cpa32U * pSizeInBytes)1085 cpaCyBufferListGetMetaSize(const CpaInstanceHandle instanceHandle_in,
1086 			   Cpa32U numBuffers,
1087 			   Cpa32U *pSizeInBytes)
1088 {
1089 
1090 	CpaInstanceHandle instanceHandle = NULL;
1091 
1092 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
1093 		instanceHandle =
1094 		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
1095 	} else {
1096 		instanceHandle = instanceHandle_in;
1097 	}
1098 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
1099 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
1100 				(SAL_SERVICE_TYPE_CRYPTO |
1101 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
1102 	LAC_CHECK_NULL_PARAM(pSizeInBytes);
1103 
1104 	/* In the case of zero buffers we still need to allocate one
1105 	 * descriptor to pass to the firmware */
1106 	if (0 == numBuffers) {
1107 		numBuffers = 1;
1108 	}
1109 
1110 	/* Note: icp_buffer_list_desc_t is 8 bytes in size and
1111 	 * icp_flat_buffer_desc_t is 16 bytes in size. Therefore if
1112 	 * icp_buffer_list_desc_t is aligned
1113 	 * so will each icp_flat_buffer_desc_t structure */
1114 
1115 	*pSizeInBytes = sizeof(icp_buffer_list_desc_t) +
1116 	    (sizeof(icp_flat_buffer_desc_t) * numBuffers) +
1117 	    ICP_DESCRIPTOR_ALIGNMENT_BYTES;
1118 
1119 
1120 	return CPA_STATUS_SUCCESS;
1121 }
1122