xref: /freebsd/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_hash.c (revision ded037e65e5239671b1292ec987a2e0894b217b5)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2025 Intel Corporation */
3 
4 /**
5  ***************************************************************************
6  * @file lac_sym_hash.c
7  *
8  * @ingroup LacHash
9  *
10  * Hash specific functionality
11  ***************************************************************************/
12 
13 /*
14 *******************************************************************************
15 * Include public/global header files
16 *******************************************************************************
17 */
18 
19 #include "cpa.h"
20 #include "cpa_cy_sym.h"
21 
22 #include "icp_accel_devices.h"
23 #include "icp_adf_debug.h"
24 
25 /*
26 *******************************************************************************
27 * Include private header files
28 *******************************************************************************
29 */
30 
31 #include "lac_common.h"
32 #include "lac_mem.h"
33 #include "lac_sym.h"
34 #include "lac_session.h"
35 #include "lac_sym_hash.h"
36 #include "lac_log.h"
37 #include "lac_sym_qat_hash.h"
38 #include "lac_sym_qat_hash_defs_lookup.h"
39 #include "lac_sym_cb.h"
40 #include "lac_sync.h"
41 
42 #define LAC_HASH_ALG_MODE_NOT_SUPPORTED(alg, mode)                             \
43 	((((CPA_CY_SYM_HASH_KASUMI_F9 == (alg)) ||                             \
44 	   (CPA_CY_SYM_HASH_SNOW3G_UIA2 == (alg)) ||                           \
45 	   (CPA_CY_SYM_HASH_AES_XCBC == (alg)) ||                              \
46 	   (CPA_CY_SYM_HASH_AES_CCM == (alg)) ||                               \
47 	   (CPA_CY_SYM_HASH_AES_GCM == (alg)) ||                               \
48 	   (CPA_CY_SYM_HASH_AES_GMAC == (alg)) ||                              \
49 	   (CPA_CY_SYM_HASH_AES_CMAC == (alg)) ||                              \
50 	   (CPA_CY_SYM_HASH_ZUC_EIA3 == (alg))) &&                             \
51 	  (CPA_CY_SYM_HASH_MODE_AUTH != (mode))) ||                            \
52 	 ((LAC_HASH_IS_SHA3(alg)) && (CPA_CY_SYM_HASH_MODE_NESTED == (mode))))
53 /**< Macro to check for valid algorithm-mode combination */
54 
55 void LacSync_GenBufListVerifyCb(void *pCallbackTag,
56 				CpaStatus status,
57 				CpaCySymOp operationType,
58 				void *pOpData,
59 				CpaBufferList *pDstBuffer,
60 				CpaBoolean opResult);
61 
62 /**
63  * @ingroup LacHash
64  * This callback function will be invoked whenever a synchronous
65  * hash precompute operation completes.  It will set the wait
66  * queue flag for the synchronous operation.
67  *
68  * @param[in] pCallbackTag  Opaque value provided by user. This will
69  *                         be a pointer to a wait queue flag.
70  *
71  * @retval
72  *     None
73  *
74  */
75 static void
LacHash_SyncPrecomputeDoneCb(void * pCallbackTag)76 LacHash_SyncPrecomputeDoneCb(void *pCallbackTag)
77 {
78 	LacSync_GenWakeupSyncCaller(pCallbackTag, CPA_STATUS_SUCCESS);
79 }
80 
81 /** @ingroup LacHash */
82 CpaStatus
LacHash_StatePrefixAadBufferInit(sal_service_t * pService,const CpaCySymHashSetupData * pHashSetupData,icp_qat_la_bulk_req_ftr_t * pReq,icp_qat_hw_auth_mode_t qatHashMode,Cpa8U * pHashStateBuffer,lac_sym_qat_hash_state_buffer_info_t * pHashStateBufferInfo)83 LacHash_StatePrefixAadBufferInit(
84     sal_service_t *pService,
85     const CpaCySymHashSetupData *pHashSetupData,
86     icp_qat_la_bulk_req_ftr_t *pReq,
87     icp_qat_hw_auth_mode_t qatHashMode,
88     Cpa8U *pHashStateBuffer,
89     lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo)
90 {
91 	/* set up the hash state prefix buffer info structure */
92 	pHashStateBufferInfo->pData = pHashStateBuffer;
93 
94 	pHashStateBufferInfo->pDataPhys = LAC_MEM_CAST_PTR_TO_UINT64(
95 	    LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService), pHashStateBuffer));
96 
97 	if (pHashStateBufferInfo->pDataPhys == 0) {
98 		LAC_LOG_ERROR("Unable to get the physical address of "
99 			      "the hash state buffer\n");
100 		return CPA_STATUS_FAIL;
101 	}
102 
103 	LacSymQat_HashStatePrefixAadBufferSizeGet(pReq, pHashStateBufferInfo);
104 
105 	/* Prefix data gets copied to the hash state buffer for nested mode */
106 	if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
107 		LacSymQat_HashStatePrefixAadBufferPopulate(
108 		    pHashStateBufferInfo,
109 		    pReq,
110 		    pHashSetupData->nestedModeSetupData.pInnerPrefixData,
111 		    (Cpa8U)pHashSetupData->nestedModeSetupData
112 			.innerPrefixLenInBytes,
113 		    pHashSetupData->nestedModeSetupData.pOuterPrefixData,
114 		    (Cpa8U)pHashSetupData->nestedModeSetupData
115 			.outerPrefixLenInBytes);
116 	}
117 	/* For mode2 HMAC the key gets copied into both the inner and
118 	 * outer prefix fields */
119 	else if (IS_HASH_MODE_2_AUTH(qatHashMode, pHashSetupData->hashMode)) {
120 		LacSymQat_HashStatePrefixAadBufferPopulate(
121 		    pHashStateBufferInfo,
122 		    pReq,
123 		    pHashSetupData->authModeSetupData.authKey,
124 		    (Cpa8U)pHashSetupData->authModeSetupData.authKeyLenInBytes,
125 		    pHashSetupData->authModeSetupData.authKey,
126 		    (Cpa8U)pHashSetupData->authModeSetupData.authKeyLenInBytes);
127 	}
128 	/* else do nothing for the other cases */
129 	return CPA_STATUS_SUCCESS;
130 }
131 
132 /** @ingroup LacHash */
133 CpaStatus
LacHash_PrecomputeDataCreate(const CpaInstanceHandle instanceHandle,CpaCySymSessionSetupData * pSessionSetup,lac_hash_precompute_done_cb_t callbackFn,void * pCallbackTag,Cpa8U * pWorkingBuffer,Cpa8U * pState1,Cpa8U * pState2)134 LacHash_PrecomputeDataCreate(const CpaInstanceHandle instanceHandle,
135 			     CpaCySymSessionSetupData *pSessionSetup,
136 			     lac_hash_precompute_done_cb_t callbackFn,
137 			     void *pCallbackTag,
138 			     Cpa8U *pWorkingBuffer,
139 			     Cpa8U *pState1,
140 			     Cpa8U *pState2)
141 {
142 	CpaStatus status = CPA_STATUS_SUCCESS;
143 	Cpa8U *pAuthKey = NULL;
144 	Cpa32U authKeyLenInBytes = 0;
145 	CpaCySymHashAlgorithm hashAlgorithm =
146 	    pSessionSetup->hashSetupData.hashAlgorithm;
147 	CpaCySymHashAuthModeSetupData *pAuthModeSetupData =
148 	    &pSessionSetup->hashSetupData.authModeSetupData;
149 
150 	/* synchronous operation */
151 	if (NULL == callbackFn) {
152 		lac_sync_op_data_t *pSyncCallbackData = NULL;
153 
154 		status = LacSync_CreateSyncCookie(&pSyncCallbackData);
155 
156 		if (CPA_STATUS_SUCCESS == status) {
157 			status = LacHash_PrecomputeDataCreate(
158 			    instanceHandle,
159 			    pSessionSetup,
160 			    LacHash_SyncPrecomputeDoneCb,
161 			    /* wait queue condition from sync cookie */
162 			    pSyncCallbackData,
163 			    pWorkingBuffer,
164 			    pState1,
165 			    pState2);
166 		} else {
167 			return status;
168 		}
169 
170 		if (CPA_STATUS_SUCCESS == status) {
171 			CpaStatus syncStatus = CPA_STATUS_SUCCESS;
172 
173 			syncStatus = LacSync_WaitForCallback(
174 			    pSyncCallbackData,
175 			    LAC_SYM_SYNC_CALLBACK_TIMEOUT,
176 			    &status,
177 			    NULL);
178 
179 			/* If callback doesn't come back */
180 			if (CPA_STATUS_SUCCESS != syncStatus) {
181 				QAT_UTILS_LOG(
182 				    "callback functions for precomputes did not return\n");
183 				status = syncStatus;
184 			}
185 		} else {
186 			/* As the Request was not sent the Callback will never
187 			 * be called, so need to indicate that we're finished
188 			 * with cookie so it can be destroyed. */
189 			LacSync_SetSyncCookieComplete(pSyncCallbackData);
190 		}
191 		LacSync_DestroySyncCookie(&pSyncCallbackData);
192 
193 		return status;
194 	}
195 
196 	/* set up convenience pointers */
197 	pAuthKey = pAuthModeSetupData->authKey;
198 	authKeyLenInBytes = pAuthModeSetupData->authKeyLenInBytes;
199 
200 	/* Pre-compute data state pointers must already be set up
201 	 * by LacSymQat_HashSetupBlockInit()
202 	 */
203 
204 	/* state1 is not allocated for AES XCBC/CCM/GCM/Kasumi/UIA2
205 	 * so for these algorithms set state2 only */
206 	if (CPA_CY_SYM_HASH_AES_XCBC == hashAlgorithm) {
207 		status = LacSymHash_AesECBPreCompute(instanceHandle,
208 						     hashAlgorithm,
209 						     authKeyLenInBytes,
210 						     pAuthKey,
211 						     pWorkingBuffer,
212 						     pState2,
213 						     callbackFn,
214 						     pCallbackTag);
215 	} else if (CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) {
216 		/* First, copy the original key to pState2 */
217 		memcpy(pState2, pAuthKey, authKeyLenInBytes);
218 		/* Then precompute */
219 		status = LacSymHash_AesECBPreCompute(instanceHandle,
220 						     hashAlgorithm,
221 						     authKeyLenInBytes,
222 						     pAuthKey,
223 						     pWorkingBuffer,
224 						     pState2,
225 						     callbackFn,
226 						     pCallbackTag);
227 	} else if (CPA_CY_SYM_HASH_AES_CCM == hashAlgorithm) {
228 		/*
229 		 * The Inner Hash Initial State2 block is 32 bytes long.
230 		 * Therefore, for keys bigger than 128 bits (16 bytes),
231 		 * there is no space for 16 zeroes.
232 		 */
233 		if (pSessionSetup->cipherSetupData.cipherKeyLenInBytes ==
234 		    ICP_QAT_HW_AES_128_KEY_SZ) {
235 			/*
236 			 * The Inner Hash Initial State2 block must contain K
237 			 * (the cipher key) and 16 zeroes which will be replaced
238 			 * with EK(Ctr0) by the QAT-ME.
239 			 */
240 
241 			/* write the auth key which for CCM is equivalent to
242 			 * cipher key
243 			 */
244 			memcpy(
245 			    pState2,
246 			    pSessionSetup->cipherSetupData.pCipherKey,
247 			    pSessionSetup->cipherSetupData.cipherKeyLenInBytes);
248 
249 			/* initialize remaining buffer space to all zeroes */
250 			LAC_OS_BZERO(pState2 +
251 					 pSessionSetup->cipherSetupData
252 					     .cipherKeyLenInBytes,
253 				     ICP_QAT_HW_AES_CCM_CBC_E_CTR0_SZ);
254 		}
255 
256 		/* There is no request sent to the QAT for this operation,
257 		 * so just invoke the user's callback directly to signal
258 		 * completion of the precompute
259 		 */
260 		callbackFn(pCallbackTag);
261 	} else if (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm ||
262 		   CPA_CY_SYM_HASH_AES_GMAC == hashAlgorithm) {
263 		/*
264 		 * The Inner Hash Initial State2 block contains the following
265 		 *      H (the Galois Hash Multiplier)
266 		 *      len(A) (the length of A), (length before padding)
267 		 *      16 zeroes which will be replaced with EK(Ctr0) by the
268 		 * QAT.
269 		 */
270 
271 		/* Memset state2 to 0 */
272 		LAC_OS_BZERO(pState2,
273 			     ICP_QAT_HW_GALOIS_H_SZ +
274 				 ICP_QAT_HW_GALOIS_LEN_A_SZ +
275 				 ICP_QAT_HW_GALOIS_E_CTR0_SZ);
276 
277 		/* write H (the Galois Hash Multiplier) where H = E(K, 0...0)
278 		 * This will only write bytes 0-15 of pState2
279 		 */
280 		status = LacSymHash_AesECBPreCompute(
281 		    instanceHandle,
282 		    hashAlgorithm,
283 		    pSessionSetup->cipherSetupData.cipherKeyLenInBytes,
284 		    pSessionSetup->cipherSetupData.pCipherKey,
285 		    pWorkingBuffer,
286 		    pState2,
287 		    callbackFn,
288 		    pCallbackTag);
289 
290 		if (CPA_STATUS_SUCCESS == status) {
291 			/* write len(A) (the length of A) into bytes 16-19 of
292 			 * pState2 in big-endian format. This field is 8 bytes
293 			 */
294 			*(Cpa32U *)&pState2[ICP_QAT_HW_GALOIS_H_SZ] =
295 			    LAC_MEM_WR_32(pAuthModeSetupData->aadLenInBytes);
296 		}
297 	} else if (CPA_CY_SYM_HASH_KASUMI_F9 == hashAlgorithm) {
298 		Cpa32U wordIndex = 0;
299 		Cpa32U *pTempKey = (Cpa32U *)(pState2 + authKeyLenInBytes);
300 		/*
301 		 * The Inner Hash Initial State2 block must contain IK
302 		 * (Initialisation Key), followed by IK XOR-ed with KM
303 		 * (Key Modifier): IK||(IK^KM).
304 		 */
305 
306 		/* write the auth key */
307 		memcpy(pState2, pAuthKey, authKeyLenInBytes);
308 		/* initialise temp key with auth key */
309 		memcpy(pTempKey, pAuthKey, authKeyLenInBytes);
310 
311 		/* XOR Key with KASUMI F9 key modifier at 4 bytes level */
312 		for (wordIndex = 0;
313 		     wordIndex < LAC_BYTES_TO_LONGWORDS(authKeyLenInBytes);
314 		     wordIndex++) {
315 			pTempKey[wordIndex] ^=
316 			    LAC_HASH_KASUMI_F9_KEY_MODIFIER_4_BYTES;
317 		}
318 		/* There is no request sent to the QAT for this operation,
319 		 * so just invoke the user's callback directly to signal
320 		 * completion of the precompute
321 		 */
322 		callbackFn(pCallbackTag);
323 	} else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) {
324 		/*
325 		 * The Inner Hash Initial State2 should be all zeros
326 		 */
327 		LAC_OS_BZERO(pState2, ICP_QAT_HW_SNOW_3G_UIA2_STATE2_SZ);
328 
329 		/* There is no request sent to the QAT for this operation,
330 		 * so just invoke the user's callback directly to signal
331 		 * completion of the precompute
332 		 */
333 		callbackFn(pCallbackTag);
334 	} else if (CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm) {
335 		/*
336 		 * The Inner Hash Initial State2 should contain the key
337 		 * and zero the rest of the state.
338 		 */
339 		LAC_OS_BZERO(pState2, ICP_QAT_HW_ZUC_3G_EIA3_STATE2_SZ);
340 		memcpy(pState2, pAuthKey, authKeyLenInBytes);
341 
342 		/* There is no request sent to the QAT for this operation,
343 		 * so just invoke the user's callback directly to signal
344 		 * completion of the precompute
345 		 */
346 		callbackFn(pCallbackTag);
347 	} else if (CPA_CY_SYM_HASH_POLY == hashAlgorithm) {
348 		/* There is no request sent to the QAT for this operation,
349 		 * so just invoke the user's callback directly to signal
350 		 * completion of the precompute
351 		 */
352 		callbackFn(pCallbackTag);
353 	} else /* For Hmac Precomputes */
354 	{
355 		status = LacSymHash_HmacPreComputes(instanceHandle,
356 						    hashAlgorithm,
357 						    authKeyLenInBytes,
358 						    pAuthKey,
359 						    pWorkingBuffer,
360 						    pState1,
361 						    pState2,
362 						    callbackFn,
363 						    pCallbackTag);
364 	}
365 
366 	return status;
367 }
368 
369 /** @ingroup LacHash */
370 CpaStatus
LacHash_HashContextCheck(CpaInstanceHandle instanceHandle,const CpaCySymHashSetupData * pHashSetupData)371 LacHash_HashContextCheck(CpaInstanceHandle instanceHandle,
372 			 const CpaCySymHashSetupData *pHashSetupData)
373 {
374 	lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
375 	lac_sym_qat_hash_alg_info_t *pOuterHashAlgInfo = NULL;
376 	CpaCySymCapabilitiesInfo capInfo;
377 
378 	/*Protect against value of hash outside the bitmap*/
379 	if (pHashSetupData->hashAlgorithm >= CPA_CY_SYM_HASH_CAP_BITMAP_SIZE) {
380 		LAC_INVALID_PARAM_LOG("hashAlgorithm");
381 		return CPA_STATUS_INVALID_PARAM;
382 	}
383 
384 	cpaCySymQueryCapabilities(instanceHandle, &capInfo);
385 	if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
386 				 pHashSetupData->hashAlgorithm) &&
387 	    pHashSetupData->hashAlgorithm != CPA_CY_SYM_HASH_AES_CBC_MAC) {
388 		LAC_INVALID_PARAM_LOG("hashAlgorithm");
389 		return CPA_STATUS_INVALID_PARAM;
390 	}
391 
392 	switch (pHashSetupData->hashMode) {
393 	case CPA_CY_SYM_HASH_MODE_PLAIN:
394 	case CPA_CY_SYM_HASH_MODE_AUTH:
395 	case CPA_CY_SYM_HASH_MODE_NESTED:
396 		break;
397 
398 	default: {
399 		LAC_INVALID_PARAM_LOG("hashMode");
400 		return CPA_STATUS_INVALID_PARAM;
401 	}
402 	}
403 
404 	if (LAC_HASH_ALG_MODE_NOT_SUPPORTED(pHashSetupData->hashAlgorithm,
405 					    pHashSetupData->hashMode)) {
406 		LAC_UNSUPPORTED_PARAM_LOG(
407 		    "hashAlgorithm and hashMode combination");
408 		return CPA_STATUS_UNSUPPORTED;
409 	}
410 
411 	LacSymQat_HashAlgLookupGet(instanceHandle,
412 				   pHashSetupData->hashAlgorithm,
413 				   &pHashAlgInfo);
414 
415 	/* note: nested hash mode checks digest length against outer algorithm
416 	 */
417 	if ((CPA_CY_SYM_HASH_MODE_PLAIN == pHashSetupData->hashMode) ||
418 	    (CPA_CY_SYM_HASH_MODE_AUTH == pHashSetupData->hashMode)) {
419 		/* Check Digest Length is permitted by the algorithm  */
420 		if ((0 == pHashSetupData->digestResultLenInBytes) ||
421 		    (pHashSetupData->digestResultLenInBytes >
422 		     pHashAlgInfo->digestLength)) {
423 			LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
424 			return CPA_STATUS_INVALID_PARAM;
425 		}
426 	}
427 
428 	if (CPA_CY_SYM_HASH_MODE_AUTH == pHashSetupData->hashMode) {
429 		if (CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm ||
430 		    CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) {
431 			Cpa32U aadDataSize = 0;
432 
433 			/* RFC 4106: Implementations MUST support a full-length
434 			 * 16-octet ICV, and MAY support 8 or 12 octet ICVs, and
435 			 * MUST NOT support other ICV lengths. */
436 			if ((pHashSetupData->digestResultLenInBytes !=
437 			     LAC_HASH_AES_GCM_ICV_SIZE_8) &&
438 			    (pHashSetupData->digestResultLenInBytes !=
439 			     LAC_HASH_AES_GCM_ICV_SIZE_12) &&
440 			    (pHashSetupData->digestResultLenInBytes !=
441 			     LAC_HASH_AES_GCM_ICV_SIZE_16)) {
442 				LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
443 				return CPA_STATUS_INVALID_PARAM;
444 			}
445 
446 			/* ensure aadLen is within maximum limit imposed by QAT
447 			 */
448 			aadDataSize =
449 			    pHashSetupData->authModeSetupData.aadLenInBytes;
450 
451 			/* round the aad size to the multiple of GCM hash block
452 			 * size. */
453 			aadDataSize =
454 			    LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
455 						   LAC_HASH_AES_GCM_BLOCK_SIZE);
456 
457 			if (aadDataSize > ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX &&
458 			    CPA_CY_SYM_HASH_AES_GMAC !=
459 				pHashSetupData->hashAlgorithm) {
460 				LAC_INVALID_PARAM_LOG("aadLenInBytes");
461 				return CPA_STATUS_INVALID_PARAM;
462 			}
463 		} else if (CPA_CY_SYM_HASH_AES_CCM ==
464 			   pHashSetupData->hashAlgorithm) {
465 			Cpa32U aadDataSize = 0;
466 
467 			/* RFC 3610: Valid values are 4, 6, 8, 10, 12, 14, and
468 			 * 16 octets */
469 			if ((pHashSetupData->digestResultLenInBytes >=
470 			     LAC_HASH_AES_CCM_ICV_SIZE_MIN) &&
471 			    (pHashSetupData->digestResultLenInBytes <=
472 			     LAC_HASH_AES_CCM_ICV_SIZE_MAX)) {
473 				if ((pHashSetupData->digestResultLenInBytes &
474 				     0x01) != 0) {
475 					LAC_INVALID_PARAM_LOG(
476 					    "digestResultLenInBytes must be a multiple of 2");
477 					return CPA_STATUS_INVALID_PARAM;
478 				}
479 			} else {
480 				LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
481 				return CPA_STATUS_INVALID_PARAM;
482 			}
483 
484 			/* ensure aadLen is within maximum limit imposed by QAT
485 			 */
486 			/* at the beginning of the buffer there is B0 block */
487 			aadDataSize = LAC_HASH_AES_CCM_BLOCK_SIZE;
488 
489 			/* then, if there is some 'a' data, the buffer will
490 			 * store encoded length of 'a' and 'a' itself */
491 			if (pHashSetupData->authModeSetupData.aadLenInBytes >
492 			    0) {
493 				/* as the QAT API puts the requirement on the
494 				 * pAdditionalAuthData not to be bigger than 240
495 				 * bytes then we just need 2 bytes to store
496 				 * encoded length of 'a' */
497 				aadDataSize += sizeof(Cpa16U);
498 				aadDataSize += pHashSetupData->authModeSetupData
499 						   .aadLenInBytes;
500 			}
501 
502 			/* round the aad size to the multiple of CCM block
503 			 * size.*/
504 			aadDataSize =
505 			    LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
506 						   LAC_HASH_AES_CCM_BLOCK_SIZE);
507 			if (aadDataSize > ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX) {
508 				LAC_INVALID_PARAM_LOG("aadLenInBytes");
509 				return CPA_STATUS_INVALID_PARAM;
510 			}
511 		} else if (CPA_CY_SYM_HASH_KASUMI_F9 ==
512 			   pHashSetupData->hashAlgorithm) {
513 			/* QAT-FW only supports 128 bit Integrity Key size for
514 			 * Kasumi f9
515 			 *  Ref: 3GPP TS 35.201 version 7.0.0 Release 7 */
516 			if (pHashSetupData->authModeSetupData
517 				.authKeyLenInBytes !=
518 			    ICP_QAT_HW_KASUMI_KEY_SZ) {
519 				LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
520 				return CPA_STATUS_INVALID_PARAM;
521 			}
522 		} else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
523 			   pHashSetupData->hashAlgorithm) {
524 
525 			/* QAT-FW only supports 128 bits Integrity Key size for
526 			 * Snow3g */
527 			if (pHashSetupData->authModeSetupData
528 				.authKeyLenInBytes !=
529 			    ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ) {
530 				LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
531 				return CPA_STATUS_INVALID_PARAM;
532 			}
533 			/* For Snow3g hash aad field contains IV - it needs to
534 			 * be 16 bytes long
535 			 */
536 			if (pHashSetupData->authModeSetupData.aadLenInBytes !=
537 			    ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ) {
538 				LAC_INVALID_PARAM_LOG("aadLenInBytes");
539 				return CPA_STATUS_INVALID_PARAM;
540 			}
541 		} else if (CPA_CY_SYM_HASH_AES_XCBC ==
542 			       pHashSetupData->hashAlgorithm ||
543 			   CPA_CY_SYM_HASH_AES_CMAC ==
544 			       pHashSetupData->hashAlgorithm ||
545 			   CPA_CY_SYM_HASH_AES_CBC_MAC ==
546 			       pHashSetupData->hashAlgorithm) {
547 			/* ensure auth key len is valid (128-bit keys supported)
548 			 */
549 			if ((pHashSetupData->authModeSetupData
550 				 .authKeyLenInBytes !=
551 			     ICP_QAT_HW_AES_128_KEY_SZ)) {
552 				LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
553 				return CPA_STATUS_INVALID_PARAM;
554 			}
555 		} else if (CPA_CY_SYM_HASH_ZUC_EIA3 ==
556 			   pHashSetupData->hashAlgorithm) {
557 
558 			/* QAT-FW only supports 128 bits Integrity Key size for
559 			 * ZUC */
560 			if (pHashSetupData->authModeSetupData
561 				.authKeyLenInBytes !=
562 			    ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) {
563 				LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
564 				return CPA_STATUS_INVALID_PARAM;
565 			}
566 			/* For ZUC EIA3 hash aad field contains IV - it needs to
567 			 * be 16 bytes long
568 			 */
569 			if (pHashSetupData->authModeSetupData.aadLenInBytes !=
570 			    ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ) {
571 				LAC_INVALID_PARAM_LOG("aadLenInBytes");
572 				return CPA_STATUS_INVALID_PARAM;
573 			}
574 		} else if (CPA_CY_SYM_HASH_POLY ==
575 			   pHashSetupData->hashAlgorithm) {
576 			if (pHashSetupData->digestResultLenInBytes !=
577 			    ICP_QAT_HW_SPC_CTR_SZ) {
578 				LAC_INVALID_PARAM_LOG("Digest Length for CCP");
579 				return CPA_STATUS_INVALID_PARAM;
580 			}
581 			if (pHashSetupData->authModeSetupData.aadLenInBytes >
582 			    ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX) {
583 				LAC_INVALID_PARAM_LOG("AAD Length for CCP");
584 				return CPA_STATUS_INVALID_PARAM;
585 			}
586 		} else {
587 			/* The key size must be less than or equal the block
588 			 * length */
589 			if (pHashSetupData->authModeSetupData
590 				.authKeyLenInBytes >
591 			    pHashAlgInfo->blockLength) {
592 				LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
593 				return CPA_STATUS_INVALID_PARAM;
594 			}
595 		}
596 
597 		/* when the key size is greater than 0 check pointer is not null
598 		 */
599 		if (CPA_CY_SYM_HASH_AES_CCM != pHashSetupData->hashAlgorithm &&
600 		    CPA_CY_SYM_HASH_AES_GCM != pHashSetupData->hashAlgorithm &&
601 		    pHashSetupData->authModeSetupData.authKeyLenInBytes > 0) {
602 			LAC_CHECK_NULL_PARAM(
603 			    pHashSetupData->authModeSetupData.authKey);
604 		}
605 	} else if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
606 		if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
607 					 pHashSetupData->nestedModeSetupData
608 					     .outerHashAlgorithm)) {
609 			LAC_INVALID_PARAM_LOG("outerHashAlgorithm");
610 			return CPA_STATUS_INVALID_PARAM;
611 		}
612 
613 		if (LAC_HASH_ALG_MODE_NOT_SUPPORTED(
614 			pHashSetupData->nestedModeSetupData.outerHashAlgorithm,
615 			pHashSetupData->hashMode)) {
616 			LAC_INVALID_PARAM_LOG(
617 			    "outerHashAlgorithm and hashMode combination");
618 			return CPA_STATUS_INVALID_PARAM;
619 		}
620 
621 		LacSymQat_HashAlgLookupGet(
622 		    instanceHandle,
623 		    pHashSetupData->nestedModeSetupData.outerHashAlgorithm,
624 		    &pOuterHashAlgInfo);
625 
626 		/* Check Digest Length is permitted by the algorithm  */
627 		if ((0 == pHashSetupData->digestResultLenInBytes) ||
628 		    (pHashSetupData->digestResultLenInBytes >
629 		     pOuterHashAlgInfo->digestLength)) {
630 			LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
631 			return CPA_STATUS_INVALID_PARAM;
632 		}
633 
634 		if (pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes >
635 		    LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES) {
636 			LAC_INVALID_PARAM_LOG("innerPrefixLenInBytes");
637 			return CPA_STATUS_INVALID_PARAM;
638 		}
639 
640 		if (pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes >
641 		    0) {
642 			LAC_CHECK_NULL_PARAM(pHashSetupData->nestedModeSetupData
643 						 .pInnerPrefixData);
644 		}
645 
646 		if (pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes >
647 		    LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES) {
648 			LAC_INVALID_PARAM_LOG("outerPrefixLenInBytes");
649 			return CPA_STATUS_INVALID_PARAM;
650 		}
651 
652 		if (pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes >
653 		    0) {
654 			LAC_CHECK_NULL_PARAM(pHashSetupData->nestedModeSetupData
655 						 .pOuterPrefixData);
656 		}
657 	}
658 
659 	return CPA_STATUS_SUCCESS;
660 }
661 
662 /** @ingroup LacHash */
663 CpaStatus
LacHash_PerformParamCheck(CpaInstanceHandle instanceHandle,lac_session_desc_t * pSessionDesc,const CpaCySymOpData * pOpData,Cpa64U srcPktSize,const CpaBoolean * pVerifyResult)664 LacHash_PerformParamCheck(CpaInstanceHandle instanceHandle,
665 			  lac_session_desc_t *pSessionDesc,
666 			  const CpaCySymOpData *pOpData,
667 			  Cpa64U srcPktSize,
668 			  const CpaBoolean *pVerifyResult)
669 {
670 	CpaStatus status = CPA_STATUS_SUCCESS;
671 	lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
672 	CpaBoolean digestIsAppended = pSessionDesc->digestIsAppended;
673 	CpaBoolean digestVerify = pSessionDesc->digestVerify;
674 	CpaCySymOp symOperation = pSessionDesc->symOperation;
675 	CpaCySymHashAlgorithm hashAlgorithm = pSessionDesc->hashAlgorithm;
676 
677 	/* digestVerify and digestIsAppended on Hash-Only operation not
678 	 * supported */
679 	if (digestIsAppended && digestVerify &&
680 	    (CPA_CY_SYM_OP_HASH == symOperation)) {
681 		LAC_INVALID_PARAM_LOG(
682 		    "digestVerify and digestIsAppended set "
683 		    "on Hash-Only operation is not supported");
684 		return CPA_STATUS_INVALID_PARAM;
685 	}
686 
687 	/* check the digest result pointer */
688 	if ((CPA_CY_SYM_PACKET_TYPE_PARTIAL != pOpData->packetType) &&
689 	    !digestIsAppended && (NULL == pOpData->pDigestResult)) {
690 		LAC_INVALID_PARAM_LOG("pDigestResult is NULL");
691 		return CPA_STATUS_INVALID_PARAM;
692 	}
693 
694 	/*
695 	 * Check if the pVerifyResult pointer is not null for hash operation
696 	 * when the packet is the last one and user has set verifyDigest flag
697 	 * Also, this is only needed for symchronous operation, so check if the
698 	 * callback pointer is the internal synchronous one rather than a user-
699 	 * supplied one.
700 	 */
701 	if ((CPA_TRUE == digestVerify) &&
702 	    (CPA_CY_SYM_PACKET_TYPE_PARTIAL != pOpData->packetType) &&
703 	    (LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb)) {
704 		if (NULL == pVerifyResult) {
705 			LAC_INVALID_PARAM_LOG(
706 			    "Null pointer pVerifyResult for hash op");
707 			return CPA_STATUS_INVALID_PARAM;
708 		}
709 	}
710 
711 	/* verify start offset + messageLenToDigest is inside the source packet.
712 	 * this also verifies that the start offset is inside the packet
713 	 * Note: digest is specified as a pointer therefore it can be
714 	 * written anywhere so we cannot check for this been inside a buffer
715 	 * CCM/GCM specify the auth region using just the cipher params as this
716 	 * region is the same for auth and cipher. It is not checked here */
717 	if ((CPA_CY_SYM_HASH_AES_CCM == hashAlgorithm) ||
718 	    (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm)) {
719 		/* ensure AAD data pointer is non-NULL if AAD len > 0 */
720 		if ((pSessionDesc->aadLenInBytes > 0) &&
721 		    (NULL == pOpData->pAdditionalAuthData)) {
722 			LAC_INVALID_PARAM_LOG("pAdditionalAuthData is NULL");
723 			return CPA_STATUS_INVALID_PARAM;
724 		}
725 	} else {
726 		if ((pOpData->hashStartSrcOffsetInBytes +
727 		     pOpData->messageLenToHashInBytes) > srcPktSize) {
728 			LAC_INVALID_PARAM_LOG(
729 			    "hashStartSrcOffsetInBytes + "
730 			    "messageLenToHashInBytes > Src Buffer Packet Length");
731 			return CPA_STATUS_INVALID_PARAM;
732 		}
733 	}
734 
735 	/* For Snow3g & ZUC hash pAdditionalAuthData field
736 	 * of OpData should contain IV */
737 	if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) ||
738 	    (CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm)) {
739 		if (NULL == pOpData->pAdditionalAuthData) {
740 			LAC_INVALID_PARAM_LOG("pAdditionalAuthData is NULL");
741 			return CPA_STATUS_INVALID_PARAM;
742 		}
743 	}
744 
745 	/* partial packets need to be multiples of the algorithm block size in
746 	 * hash only mode (except for final partial packet) */
747 	if ((CPA_CY_SYM_PACKET_TYPE_PARTIAL == pOpData->packetType) &&
748 	    (CPA_CY_SYM_OP_HASH == symOperation)) {
749 		LacSymQat_HashAlgLookupGet(instanceHandle,
750 					   hashAlgorithm,
751 					   &pHashAlgInfo);
752 
753 		/* check if the message is a multiple of the block size. */
754 		if (pOpData->messageLenToHashInBytes %
755 			pHashAlgInfo->blockLength !=
756 		    0) {
757 			LAC_INVALID_PARAM_LOG2(
758 			    "message(%d) not block-size(%d) multiple",
759 			    pOpData->messageLenToHashInBytes,
760 			    pHashAlgInfo->blockLength);
761 			return CPA_STATUS_INVALID_PARAM;
762 		}
763 	}
764 
765 	return status;
766 }
767 
768