178ee8d1cSJulian Grajkowski /* SPDX-License-Identifier: BSD-3-Clause */
278ee8d1cSJulian Grajkowski /* Copyright(c) 2007-2022 Intel Corporation */
378ee8d1cSJulian Grajkowski 
478ee8d1cSJulian Grajkowski /**
578ee8d1cSJulian Grajkowski  ***************************************************************************
678ee8d1cSJulian Grajkowski  * @file lac_sym_hash.c
778ee8d1cSJulian Grajkowski  *
878ee8d1cSJulian Grajkowski  * @ingroup LacHash
978ee8d1cSJulian Grajkowski  *
1078ee8d1cSJulian Grajkowski  * Hash specific functionality
1178ee8d1cSJulian Grajkowski  ***************************************************************************/
1278ee8d1cSJulian Grajkowski 
1378ee8d1cSJulian Grajkowski /*
1478ee8d1cSJulian Grajkowski *******************************************************************************
1578ee8d1cSJulian Grajkowski * Include public/global header files
1678ee8d1cSJulian Grajkowski *******************************************************************************
1778ee8d1cSJulian Grajkowski */
1878ee8d1cSJulian Grajkowski 
1978ee8d1cSJulian Grajkowski #include "cpa.h"
2078ee8d1cSJulian Grajkowski #include "cpa_cy_sym.h"
2178ee8d1cSJulian Grajkowski 
2278ee8d1cSJulian Grajkowski #include "icp_accel_devices.h"
2378ee8d1cSJulian Grajkowski #include "icp_adf_debug.h"
2478ee8d1cSJulian Grajkowski 
2578ee8d1cSJulian Grajkowski /*
2678ee8d1cSJulian Grajkowski *******************************************************************************
2778ee8d1cSJulian Grajkowski * Include private header files
2878ee8d1cSJulian Grajkowski *******************************************************************************
2978ee8d1cSJulian Grajkowski */
3078ee8d1cSJulian Grajkowski 
3178ee8d1cSJulian Grajkowski #include "lac_common.h"
3278ee8d1cSJulian Grajkowski #include "lac_mem.h"
3378ee8d1cSJulian Grajkowski #include "lac_sym.h"
3478ee8d1cSJulian Grajkowski #include "lac_session.h"
3578ee8d1cSJulian Grajkowski #include "lac_sym_hash.h"
3678ee8d1cSJulian Grajkowski #include "lac_log.h"
3778ee8d1cSJulian Grajkowski #include "lac_sym_qat_hash.h"
3878ee8d1cSJulian Grajkowski #include "lac_sym_qat_hash_defs_lookup.h"
3978ee8d1cSJulian Grajkowski #include "lac_sym_cb.h"
4078ee8d1cSJulian Grajkowski #include "lac_sync.h"
4178ee8d1cSJulian Grajkowski 
4278ee8d1cSJulian Grajkowski #define LAC_HASH_ALG_MODE_NOT_SUPPORTED(alg, mode)                             \
4378ee8d1cSJulian Grajkowski 	((((CPA_CY_SYM_HASH_KASUMI_F9 == (alg)) ||                             \
4478ee8d1cSJulian Grajkowski 	   (CPA_CY_SYM_HASH_SNOW3G_UIA2 == (alg)) ||                           \
4578ee8d1cSJulian Grajkowski 	   (CPA_CY_SYM_HASH_AES_XCBC == (alg)) ||                              \
4678ee8d1cSJulian Grajkowski 	   (CPA_CY_SYM_HASH_AES_CCM == (alg)) ||                               \
4778ee8d1cSJulian Grajkowski 	   (CPA_CY_SYM_HASH_AES_GCM == (alg)) ||                               \
4878ee8d1cSJulian Grajkowski 	   (CPA_CY_SYM_HASH_AES_GMAC == (alg)) ||                              \
4978ee8d1cSJulian Grajkowski 	   (CPA_CY_SYM_HASH_AES_CMAC == (alg)) ||                              \
5078ee8d1cSJulian Grajkowski 	   (CPA_CY_SYM_HASH_ZUC_EIA3 == (alg))) &&                             \
5178ee8d1cSJulian Grajkowski 	  (CPA_CY_SYM_HASH_MODE_AUTH != (mode))) ||                            \
52a977168cSMichal Gulbicki 	 ((LAC_HASH_IS_SHA3(alg)) && (CPA_CY_SYM_HASH_MODE_NESTED == (mode))))
5378ee8d1cSJulian Grajkowski /**< Macro to check for valid algorithm-mode combination */
5478ee8d1cSJulian Grajkowski 
55a977168cSMichal Gulbicki void LacSync_GenBufListVerifyCb(void *pCallbackTag,
56a977168cSMichal Gulbicki 				CpaStatus status,
57a977168cSMichal Gulbicki 				CpaCySymOp operationType,
58a977168cSMichal Gulbicki 				void *pOpData,
59a977168cSMichal Gulbicki 				CpaBufferList *pDstBuffer,
60a977168cSMichal Gulbicki 				CpaBoolean opResult);
61a977168cSMichal Gulbicki 
6278ee8d1cSJulian Grajkowski /**
6378ee8d1cSJulian Grajkowski  * @ingroup LacHash
6478ee8d1cSJulian Grajkowski  * This callback function will be invoked whenever a synchronous
6578ee8d1cSJulian Grajkowski  * hash precompute operation completes.  It will set the wait
6678ee8d1cSJulian Grajkowski  * queue flag for the synchronous operation.
6778ee8d1cSJulian Grajkowski  *
6878ee8d1cSJulian Grajkowski  * @param[in] pCallbackTag  Opaque value provided by user. This will
6978ee8d1cSJulian Grajkowski  *                         be a pointer to a wait queue flag.
7078ee8d1cSJulian Grajkowski  *
7178ee8d1cSJulian Grajkowski  * @retval
7278ee8d1cSJulian Grajkowski  *     None
7378ee8d1cSJulian Grajkowski  *
7478ee8d1cSJulian Grajkowski  */
7578ee8d1cSJulian Grajkowski static void
LacHash_SyncPrecomputeDoneCb(void * pCallbackTag)7678ee8d1cSJulian Grajkowski LacHash_SyncPrecomputeDoneCb(void *pCallbackTag)
7778ee8d1cSJulian Grajkowski {
7878ee8d1cSJulian Grajkowski 	LacSync_GenWakeupSyncCaller(pCallbackTag, CPA_STATUS_SUCCESS);
7978ee8d1cSJulian Grajkowski }
8078ee8d1cSJulian Grajkowski 
8178ee8d1cSJulian Grajkowski /** @ingroup LacHash */
8278ee8d1cSJulian Grajkowski 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)8378ee8d1cSJulian Grajkowski LacHash_StatePrefixAadBufferInit(
8478ee8d1cSJulian Grajkowski     sal_service_t *pService,
8578ee8d1cSJulian Grajkowski     const CpaCySymHashSetupData *pHashSetupData,
8678ee8d1cSJulian Grajkowski     icp_qat_la_bulk_req_ftr_t *pReq,
8778ee8d1cSJulian Grajkowski     icp_qat_hw_auth_mode_t qatHashMode,
8878ee8d1cSJulian Grajkowski     Cpa8U *pHashStateBuffer,
8978ee8d1cSJulian Grajkowski     lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo)
9078ee8d1cSJulian Grajkowski {
9178ee8d1cSJulian Grajkowski 	/* set up the hash state prefix buffer info structure */
9278ee8d1cSJulian Grajkowski 	pHashStateBufferInfo->pData = pHashStateBuffer;
9378ee8d1cSJulian Grajkowski 
9478ee8d1cSJulian Grajkowski 	pHashStateBufferInfo->pDataPhys = LAC_MEM_CAST_PTR_TO_UINT64(
9578ee8d1cSJulian Grajkowski 	    LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService), pHashStateBuffer));
9678ee8d1cSJulian Grajkowski 
9778ee8d1cSJulian Grajkowski 	if (pHashStateBufferInfo->pDataPhys == 0) {
9878ee8d1cSJulian Grajkowski 		LAC_LOG_ERROR("Unable to get the physical address of "
99a977168cSMichal Gulbicki 			      "the hash state buffer\n");
10078ee8d1cSJulian Grajkowski 		return CPA_STATUS_FAIL;
10178ee8d1cSJulian Grajkowski 	}
10278ee8d1cSJulian Grajkowski 
10378ee8d1cSJulian Grajkowski 	LacSymQat_HashStatePrefixAadBufferSizeGet(pReq, pHashStateBufferInfo);
10478ee8d1cSJulian Grajkowski 
10578ee8d1cSJulian Grajkowski 	/* Prefix data gets copied to the hash state buffer for nested mode */
10678ee8d1cSJulian Grajkowski 	if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
10778ee8d1cSJulian Grajkowski 		LacSymQat_HashStatePrefixAadBufferPopulate(
10878ee8d1cSJulian Grajkowski 		    pHashStateBufferInfo,
10978ee8d1cSJulian Grajkowski 		    pReq,
11078ee8d1cSJulian Grajkowski 		    pHashSetupData->nestedModeSetupData.pInnerPrefixData,
111a977168cSMichal Gulbicki 		    (Cpa8U)pHashSetupData->nestedModeSetupData
112a977168cSMichal Gulbicki 			.innerPrefixLenInBytes,
11378ee8d1cSJulian Grajkowski 		    pHashSetupData->nestedModeSetupData.pOuterPrefixData,
114a977168cSMichal Gulbicki 		    (Cpa8U)pHashSetupData->nestedModeSetupData
115a977168cSMichal Gulbicki 			.outerPrefixLenInBytes);
11678ee8d1cSJulian Grajkowski 	}
11778ee8d1cSJulian Grajkowski 	/* For mode2 HMAC the key gets copied into both the inner and
11878ee8d1cSJulian Grajkowski 	 * outer prefix fields */
11978ee8d1cSJulian Grajkowski 	else if (IS_HASH_MODE_2_AUTH(qatHashMode, pHashSetupData->hashMode)) {
12078ee8d1cSJulian Grajkowski 		LacSymQat_HashStatePrefixAadBufferPopulate(
12178ee8d1cSJulian Grajkowski 		    pHashStateBufferInfo,
12278ee8d1cSJulian Grajkowski 		    pReq,
12378ee8d1cSJulian Grajkowski 		    pHashSetupData->authModeSetupData.authKey,
124a977168cSMichal Gulbicki 		    (Cpa8U)pHashSetupData->authModeSetupData.authKeyLenInBytes,
12578ee8d1cSJulian Grajkowski 		    pHashSetupData->authModeSetupData.authKey,
126a977168cSMichal Gulbicki 		    (Cpa8U)pHashSetupData->authModeSetupData.authKeyLenInBytes);
12778ee8d1cSJulian Grajkowski 	}
12878ee8d1cSJulian Grajkowski 	/* else do nothing for the other cases */
12978ee8d1cSJulian Grajkowski 	return CPA_STATUS_SUCCESS;
13078ee8d1cSJulian Grajkowski }
13178ee8d1cSJulian Grajkowski 
13278ee8d1cSJulian Grajkowski /** @ingroup LacHash */
13378ee8d1cSJulian Grajkowski CpaStatus
LacHash_PrecomputeDataCreate(const CpaInstanceHandle instanceHandle,CpaCySymSessionSetupData * pSessionSetup,lac_hash_precompute_done_cb_t callbackFn,void * pCallbackTag,Cpa8U * pWorkingBuffer,Cpa8U * pState1,Cpa8U * pState2)13478ee8d1cSJulian Grajkowski LacHash_PrecomputeDataCreate(const CpaInstanceHandle instanceHandle,
13578ee8d1cSJulian Grajkowski 			     CpaCySymSessionSetupData *pSessionSetup,
13678ee8d1cSJulian Grajkowski 			     lac_hash_precompute_done_cb_t callbackFn,
13778ee8d1cSJulian Grajkowski 			     void *pCallbackTag,
13878ee8d1cSJulian Grajkowski 			     Cpa8U *pWorkingBuffer,
13978ee8d1cSJulian Grajkowski 			     Cpa8U *pState1,
14078ee8d1cSJulian Grajkowski 			     Cpa8U *pState2)
14178ee8d1cSJulian Grajkowski {
14278ee8d1cSJulian Grajkowski 	CpaStatus status = CPA_STATUS_SUCCESS;
14378ee8d1cSJulian Grajkowski 	Cpa8U *pAuthKey = NULL;
14478ee8d1cSJulian Grajkowski 	Cpa32U authKeyLenInBytes = 0;
14578ee8d1cSJulian Grajkowski 	CpaCySymHashAlgorithm hashAlgorithm =
14678ee8d1cSJulian Grajkowski 	    pSessionSetup->hashSetupData.hashAlgorithm;
14778ee8d1cSJulian Grajkowski 	CpaCySymHashAuthModeSetupData *pAuthModeSetupData =
14878ee8d1cSJulian Grajkowski 	    &pSessionSetup->hashSetupData.authModeSetupData;
14978ee8d1cSJulian Grajkowski 
15078ee8d1cSJulian Grajkowski 	/* synchronous operation */
15178ee8d1cSJulian Grajkowski 	if (NULL == callbackFn) {
15278ee8d1cSJulian Grajkowski 		lac_sync_op_data_t *pSyncCallbackData = NULL;
15378ee8d1cSJulian Grajkowski 
15478ee8d1cSJulian Grajkowski 		status = LacSync_CreateSyncCookie(&pSyncCallbackData);
15578ee8d1cSJulian Grajkowski 
15678ee8d1cSJulian Grajkowski 		if (CPA_STATUS_SUCCESS == status) {
15778ee8d1cSJulian Grajkowski 			status = LacHash_PrecomputeDataCreate(
15878ee8d1cSJulian Grajkowski 			    instanceHandle,
15978ee8d1cSJulian Grajkowski 			    pSessionSetup,
16078ee8d1cSJulian Grajkowski 			    LacHash_SyncPrecomputeDoneCb,
16178ee8d1cSJulian Grajkowski 			    /* wait queue condition from sync cookie */
16278ee8d1cSJulian Grajkowski 			    pSyncCallbackData,
16378ee8d1cSJulian Grajkowski 			    pWorkingBuffer,
16478ee8d1cSJulian Grajkowski 			    pState1,
16578ee8d1cSJulian Grajkowski 			    pState2);
16678ee8d1cSJulian Grajkowski 		} else {
16778ee8d1cSJulian Grajkowski 			return status;
16878ee8d1cSJulian Grajkowski 		}
16978ee8d1cSJulian Grajkowski 
17078ee8d1cSJulian Grajkowski 		if (CPA_STATUS_SUCCESS == status) {
17178ee8d1cSJulian Grajkowski 			CpaStatus syncStatus = CPA_STATUS_SUCCESS;
17278ee8d1cSJulian Grajkowski 
17378ee8d1cSJulian Grajkowski 			syncStatus = LacSync_WaitForCallback(
17478ee8d1cSJulian Grajkowski 			    pSyncCallbackData,
17578ee8d1cSJulian Grajkowski 			    LAC_SYM_SYNC_CALLBACK_TIMEOUT,
17678ee8d1cSJulian Grajkowski 			    &status,
17778ee8d1cSJulian Grajkowski 			    NULL);
17878ee8d1cSJulian Grajkowski 
17978ee8d1cSJulian Grajkowski 			/* If callback doesn't come back */
18078ee8d1cSJulian Grajkowski 			if (CPA_STATUS_SUCCESS != syncStatus) {
18178ee8d1cSJulian Grajkowski 				QAT_UTILS_LOG(
18278ee8d1cSJulian Grajkowski 				    "callback functions for precomputes did not return\n");
18378ee8d1cSJulian Grajkowski 				status = syncStatus;
18478ee8d1cSJulian Grajkowski 			}
18578ee8d1cSJulian Grajkowski 		} else {
18678ee8d1cSJulian Grajkowski 			/* As the Request was not sent the Callback will never
18778ee8d1cSJulian Grajkowski 			 * be called, so need to indicate that we're finished
18878ee8d1cSJulian Grajkowski 			 * with cookie so it can be destroyed. */
18978ee8d1cSJulian Grajkowski 			LacSync_SetSyncCookieComplete(pSyncCallbackData);
19078ee8d1cSJulian Grajkowski 		}
19178ee8d1cSJulian Grajkowski 		LacSync_DestroySyncCookie(&pSyncCallbackData);
19278ee8d1cSJulian Grajkowski 
19378ee8d1cSJulian Grajkowski 		return status;
19478ee8d1cSJulian Grajkowski 	}
19578ee8d1cSJulian Grajkowski 
19678ee8d1cSJulian Grajkowski 	/* set up convenience pointers */
19778ee8d1cSJulian Grajkowski 	pAuthKey = pAuthModeSetupData->authKey;
19878ee8d1cSJulian Grajkowski 	authKeyLenInBytes = pAuthModeSetupData->authKeyLenInBytes;
19978ee8d1cSJulian Grajkowski 
20078ee8d1cSJulian Grajkowski 	/* Pre-compute data state pointers must already be set up
20178ee8d1cSJulian Grajkowski 	 * by LacSymQat_HashSetupBlockInit()
20278ee8d1cSJulian Grajkowski 	 */
20378ee8d1cSJulian Grajkowski 
20478ee8d1cSJulian Grajkowski 	/* state1 is not allocated for AES XCBC/CCM/GCM/Kasumi/UIA2
20578ee8d1cSJulian Grajkowski 	 * so for these algorithms set state2 only */
20678ee8d1cSJulian Grajkowski 	if (CPA_CY_SYM_HASH_AES_XCBC == hashAlgorithm) {
20778ee8d1cSJulian Grajkowski 		status = LacSymHash_AesECBPreCompute(instanceHandle,
20878ee8d1cSJulian Grajkowski 						     hashAlgorithm,
20978ee8d1cSJulian Grajkowski 						     authKeyLenInBytes,
21078ee8d1cSJulian Grajkowski 						     pAuthKey,
21178ee8d1cSJulian Grajkowski 						     pWorkingBuffer,
21278ee8d1cSJulian Grajkowski 						     pState2,
21378ee8d1cSJulian Grajkowski 						     callbackFn,
21478ee8d1cSJulian Grajkowski 						     pCallbackTag);
21578ee8d1cSJulian Grajkowski 	} else if (CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) {
21678ee8d1cSJulian Grajkowski 		/* First, copy the original key to pState2 */
21778ee8d1cSJulian Grajkowski 		memcpy(pState2, pAuthKey, authKeyLenInBytes);
21878ee8d1cSJulian Grajkowski 		/* Then precompute */
21978ee8d1cSJulian Grajkowski 		status = LacSymHash_AesECBPreCompute(instanceHandle,
22078ee8d1cSJulian Grajkowski 						     hashAlgorithm,
22178ee8d1cSJulian Grajkowski 						     authKeyLenInBytes,
22278ee8d1cSJulian Grajkowski 						     pAuthKey,
22378ee8d1cSJulian Grajkowski 						     pWorkingBuffer,
22478ee8d1cSJulian Grajkowski 						     pState2,
22578ee8d1cSJulian Grajkowski 						     callbackFn,
22678ee8d1cSJulian Grajkowski 						     pCallbackTag);
22778ee8d1cSJulian Grajkowski 	} else if (CPA_CY_SYM_HASH_AES_CCM == hashAlgorithm) {
22878ee8d1cSJulian Grajkowski 		/*
229a977168cSMichal Gulbicki 		 * The Inner Hash Initial State2 block is 32 bytes long.
230a977168cSMichal Gulbicki 		 * Therefore, for keys bigger than 128 bits (16 bytes),
231a977168cSMichal Gulbicki 		 * there is no space for 16 zeroes.
232a977168cSMichal Gulbicki 		 */
233a977168cSMichal Gulbicki 		if (pSessionSetup->cipherSetupData.cipherKeyLenInBytes ==
234a977168cSMichal Gulbicki 		    ICP_QAT_HW_AES_128_KEY_SZ) {
235a977168cSMichal Gulbicki 			/*
23678ee8d1cSJulian Grajkowski 			 * The Inner Hash Initial State2 block must contain K
237a977168cSMichal Gulbicki 			 * (the cipher key) and 16 zeroes which will be replaced
238a977168cSMichal Gulbicki 			 * with EK(Ctr0) by the QAT-ME.
23978ee8d1cSJulian Grajkowski 			 */
24078ee8d1cSJulian Grajkowski 
241a977168cSMichal Gulbicki 			/* write the auth key which for CCM is equivalent to
242a977168cSMichal Gulbicki 			 * cipher key
24378ee8d1cSJulian Grajkowski 			 */
244a977168cSMichal Gulbicki 			memcpy(
245a977168cSMichal Gulbicki 			    pState2,
24678ee8d1cSJulian Grajkowski 			    pSessionSetup->cipherSetupData.pCipherKey,
24778ee8d1cSJulian Grajkowski 			    pSessionSetup->cipherSetupData.cipherKeyLenInBytes);
24878ee8d1cSJulian Grajkowski 
24978ee8d1cSJulian Grajkowski 			/* initialize remaining buffer space to all zeroes */
250a977168cSMichal Gulbicki 			LAC_OS_BZERO(pState2 +
251a977168cSMichal Gulbicki 					 pSessionSetup->cipherSetupData
252a977168cSMichal Gulbicki 					     .cipherKeyLenInBytes,
25378ee8d1cSJulian Grajkowski 				     ICP_QAT_HW_AES_CCM_CBC_E_CTR0_SZ);
254a977168cSMichal Gulbicki 		}
25578ee8d1cSJulian Grajkowski 
25678ee8d1cSJulian Grajkowski 		/* There is no request sent to the QAT for this operation,
25778ee8d1cSJulian Grajkowski 		 * so just invoke the user's callback directly to signal
25878ee8d1cSJulian Grajkowski 		 * completion of the precompute
25978ee8d1cSJulian Grajkowski 		 */
26078ee8d1cSJulian Grajkowski 		callbackFn(pCallbackTag);
26178ee8d1cSJulian Grajkowski 	} else if (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm ||
26278ee8d1cSJulian Grajkowski 		   CPA_CY_SYM_HASH_AES_GMAC == hashAlgorithm) {
26378ee8d1cSJulian Grajkowski 		/*
26478ee8d1cSJulian Grajkowski 		 * The Inner Hash Initial State2 block contains the following
26578ee8d1cSJulian Grajkowski 		 *      H (the Galois Hash Multiplier)
26678ee8d1cSJulian Grajkowski 		 *      len(A) (the length of A), (length before padding)
26778ee8d1cSJulian Grajkowski 		 *      16 zeroes which will be replaced with EK(Ctr0) by the
26878ee8d1cSJulian Grajkowski 		 * QAT.
26978ee8d1cSJulian Grajkowski 		 */
27078ee8d1cSJulian Grajkowski 
27178ee8d1cSJulian Grajkowski 		/* Memset state2 to 0 */
27278ee8d1cSJulian Grajkowski 		LAC_OS_BZERO(pState2,
27378ee8d1cSJulian Grajkowski 			     ICP_QAT_HW_GALOIS_H_SZ +
27478ee8d1cSJulian Grajkowski 				 ICP_QAT_HW_GALOIS_LEN_A_SZ +
27578ee8d1cSJulian Grajkowski 				 ICP_QAT_HW_GALOIS_E_CTR0_SZ);
27678ee8d1cSJulian Grajkowski 
27778ee8d1cSJulian Grajkowski 		/* write H (the Galois Hash Multiplier) where H = E(K, 0...0)
27878ee8d1cSJulian Grajkowski 		 * This will only write bytes 0-15 of pState2
27978ee8d1cSJulian Grajkowski 		 */
28078ee8d1cSJulian Grajkowski 		status = LacSymHash_AesECBPreCompute(
28178ee8d1cSJulian Grajkowski 		    instanceHandle,
28278ee8d1cSJulian Grajkowski 		    hashAlgorithm,
28378ee8d1cSJulian Grajkowski 		    pSessionSetup->cipherSetupData.cipherKeyLenInBytes,
28478ee8d1cSJulian Grajkowski 		    pSessionSetup->cipherSetupData.pCipherKey,
28578ee8d1cSJulian Grajkowski 		    pWorkingBuffer,
28678ee8d1cSJulian Grajkowski 		    pState2,
28778ee8d1cSJulian Grajkowski 		    callbackFn,
28878ee8d1cSJulian Grajkowski 		    pCallbackTag);
28978ee8d1cSJulian Grajkowski 
29078ee8d1cSJulian Grajkowski 		if (CPA_STATUS_SUCCESS == status) {
29178ee8d1cSJulian Grajkowski 			/* write len(A) (the length of A) into bytes 16-19 of
292a977168cSMichal Gulbicki 			 * pState2 in big-endian format. This field is 8 bytes
293a977168cSMichal Gulbicki 			 */
29478ee8d1cSJulian Grajkowski 			*(Cpa32U *)&pState2[ICP_QAT_HW_GALOIS_H_SZ] =
29578ee8d1cSJulian Grajkowski 			    LAC_MEM_WR_32(pAuthModeSetupData->aadLenInBytes);
29678ee8d1cSJulian Grajkowski 		}
29778ee8d1cSJulian Grajkowski 	} else if (CPA_CY_SYM_HASH_KASUMI_F9 == hashAlgorithm) {
29878ee8d1cSJulian Grajkowski 		Cpa32U wordIndex = 0;
29978ee8d1cSJulian Grajkowski 		Cpa32U *pTempKey = (Cpa32U *)(pState2 + authKeyLenInBytes);
30078ee8d1cSJulian Grajkowski 		/*
30178ee8d1cSJulian Grajkowski 		 * The Inner Hash Initial State2 block must contain IK
30278ee8d1cSJulian Grajkowski 		 * (Initialisation Key), followed by IK XOR-ed with KM
30378ee8d1cSJulian Grajkowski 		 * (Key Modifier): IK||(IK^KM).
30478ee8d1cSJulian Grajkowski 		 */
30578ee8d1cSJulian Grajkowski 
30678ee8d1cSJulian Grajkowski 		/* write the auth key */
30778ee8d1cSJulian Grajkowski 		memcpy(pState2, pAuthKey, authKeyLenInBytes);
30878ee8d1cSJulian Grajkowski 		/* initialise temp key with auth key */
30978ee8d1cSJulian Grajkowski 		memcpy(pTempKey, pAuthKey, authKeyLenInBytes);
31078ee8d1cSJulian Grajkowski 
31178ee8d1cSJulian Grajkowski 		/* XOR Key with KASUMI F9 key modifier at 4 bytes level */
31278ee8d1cSJulian Grajkowski 		for (wordIndex = 0;
31378ee8d1cSJulian Grajkowski 		     wordIndex < LAC_BYTES_TO_LONGWORDS(authKeyLenInBytes);
31478ee8d1cSJulian Grajkowski 		     wordIndex++) {
31578ee8d1cSJulian Grajkowski 			pTempKey[wordIndex] ^=
31678ee8d1cSJulian Grajkowski 			    LAC_HASH_KASUMI_F9_KEY_MODIFIER_4_BYTES;
31778ee8d1cSJulian Grajkowski 		}
31878ee8d1cSJulian Grajkowski 		/* There is no request sent to the QAT for this operation,
31978ee8d1cSJulian Grajkowski 		 * so just invoke the user's callback directly to signal
32078ee8d1cSJulian Grajkowski 		 * completion of the precompute
32178ee8d1cSJulian Grajkowski 		 */
32278ee8d1cSJulian Grajkowski 		callbackFn(pCallbackTag);
32378ee8d1cSJulian Grajkowski 	} else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) {
32478ee8d1cSJulian Grajkowski 		/*
32578ee8d1cSJulian Grajkowski 		 * The Inner Hash Initial State2 should be all zeros
32678ee8d1cSJulian Grajkowski 		 */
32778ee8d1cSJulian Grajkowski 		LAC_OS_BZERO(pState2, ICP_QAT_HW_SNOW_3G_UIA2_STATE2_SZ);
32878ee8d1cSJulian Grajkowski 
32978ee8d1cSJulian Grajkowski 		/* There is no request sent to the QAT for this operation,
33078ee8d1cSJulian Grajkowski 		 * so just invoke the user's callback directly to signal
33178ee8d1cSJulian Grajkowski 		 * completion of the precompute
33278ee8d1cSJulian Grajkowski 		 */
33378ee8d1cSJulian Grajkowski 		callbackFn(pCallbackTag);
33478ee8d1cSJulian Grajkowski 	} else if (CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm) {
33578ee8d1cSJulian Grajkowski 		/*
33678ee8d1cSJulian Grajkowski 		 * The Inner Hash Initial State2 should contain the key
33778ee8d1cSJulian Grajkowski 		 * and zero the rest of the state.
33878ee8d1cSJulian Grajkowski 		 */
33978ee8d1cSJulian Grajkowski 		LAC_OS_BZERO(pState2, ICP_QAT_HW_ZUC_3G_EIA3_STATE2_SZ);
34078ee8d1cSJulian Grajkowski 		memcpy(pState2, pAuthKey, authKeyLenInBytes);
34178ee8d1cSJulian Grajkowski 
34278ee8d1cSJulian Grajkowski 		/* There is no request sent to the QAT for this operation,
34378ee8d1cSJulian Grajkowski 		 * so just invoke the user's callback directly to signal
34478ee8d1cSJulian Grajkowski 		 * completion of the precompute
34578ee8d1cSJulian Grajkowski 		 */
34678ee8d1cSJulian Grajkowski 		callbackFn(pCallbackTag);
34778ee8d1cSJulian Grajkowski 	} else if (CPA_CY_SYM_HASH_POLY == hashAlgorithm) {
34878ee8d1cSJulian Grajkowski 		/* There is no request sent to the QAT for this operation,
34978ee8d1cSJulian Grajkowski 		 * so just invoke the user's callback directly to signal
35078ee8d1cSJulian Grajkowski 		 * completion of the precompute
35178ee8d1cSJulian Grajkowski 		 */
35278ee8d1cSJulian Grajkowski 		callbackFn(pCallbackTag);
35378ee8d1cSJulian Grajkowski 	} else /* For Hmac Precomputes */
35478ee8d1cSJulian Grajkowski 	{
35578ee8d1cSJulian Grajkowski 		status = LacSymHash_HmacPreComputes(instanceHandle,
35678ee8d1cSJulian Grajkowski 						    hashAlgorithm,
35778ee8d1cSJulian Grajkowski 						    authKeyLenInBytes,
35878ee8d1cSJulian Grajkowski 						    pAuthKey,
35978ee8d1cSJulian Grajkowski 						    pWorkingBuffer,
36078ee8d1cSJulian Grajkowski 						    pState1,
36178ee8d1cSJulian Grajkowski 						    pState2,
36278ee8d1cSJulian Grajkowski 						    callbackFn,
36378ee8d1cSJulian Grajkowski 						    pCallbackTag);
36478ee8d1cSJulian Grajkowski 	}
36578ee8d1cSJulian Grajkowski 
36678ee8d1cSJulian Grajkowski 	return status;
36778ee8d1cSJulian Grajkowski }
36878ee8d1cSJulian Grajkowski 
36978ee8d1cSJulian Grajkowski 
37078ee8d1cSJulian Grajkowski /** @ingroup LacHash */
37178ee8d1cSJulian Grajkowski CpaStatus
LacHash_HashContextCheck(CpaInstanceHandle instanceHandle,const CpaCySymHashSetupData * pHashSetupData)37278ee8d1cSJulian Grajkowski LacHash_HashContextCheck(CpaInstanceHandle instanceHandle,
37378ee8d1cSJulian Grajkowski 			 const CpaCySymHashSetupData *pHashSetupData)
37478ee8d1cSJulian Grajkowski {
37578ee8d1cSJulian Grajkowski 	lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
37678ee8d1cSJulian Grajkowski 	lac_sym_qat_hash_alg_info_t *pOuterHashAlgInfo = NULL;
37778ee8d1cSJulian Grajkowski 	CpaCySymCapabilitiesInfo capInfo;
37878ee8d1cSJulian Grajkowski 
37978ee8d1cSJulian Grajkowski 	/*Protect against value of hash outside the bitmap*/
380a977168cSMichal Gulbicki 	if (pHashSetupData->hashAlgorithm >= CPA_CY_SYM_HASH_CAP_BITMAP_SIZE) {
38178ee8d1cSJulian Grajkowski 		LAC_INVALID_PARAM_LOG("hashAlgorithm");
38278ee8d1cSJulian Grajkowski 		return CPA_STATUS_INVALID_PARAM;
38378ee8d1cSJulian Grajkowski 	}
384a977168cSMichal Gulbicki 
38578ee8d1cSJulian Grajkowski 	cpaCySymQueryCapabilities(instanceHandle, &capInfo);
38678ee8d1cSJulian Grajkowski 	if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
38778ee8d1cSJulian Grajkowski 				 pHashSetupData->hashAlgorithm) &&
38878ee8d1cSJulian Grajkowski 	    pHashSetupData->hashAlgorithm != CPA_CY_SYM_HASH_AES_CBC_MAC) {
38978ee8d1cSJulian Grajkowski 		LAC_INVALID_PARAM_LOG("hashAlgorithm");
39078ee8d1cSJulian Grajkowski 		return CPA_STATUS_INVALID_PARAM;
39178ee8d1cSJulian Grajkowski 	}
39278ee8d1cSJulian Grajkowski 
39378ee8d1cSJulian Grajkowski 	switch (pHashSetupData->hashMode) {
39478ee8d1cSJulian Grajkowski 	case CPA_CY_SYM_HASH_MODE_PLAIN:
39578ee8d1cSJulian Grajkowski 	case CPA_CY_SYM_HASH_MODE_AUTH:
39678ee8d1cSJulian Grajkowski 	case CPA_CY_SYM_HASH_MODE_NESTED:
39778ee8d1cSJulian Grajkowski 		break;
39878ee8d1cSJulian Grajkowski 
39978ee8d1cSJulian Grajkowski 	default: {
40078ee8d1cSJulian Grajkowski 		LAC_INVALID_PARAM_LOG("hashMode");
40178ee8d1cSJulian Grajkowski 		return CPA_STATUS_INVALID_PARAM;
40278ee8d1cSJulian Grajkowski 	}
40378ee8d1cSJulian Grajkowski 	}
40478ee8d1cSJulian Grajkowski 
40578ee8d1cSJulian Grajkowski 	if (LAC_HASH_ALG_MODE_NOT_SUPPORTED(pHashSetupData->hashAlgorithm,
40678ee8d1cSJulian Grajkowski 					    pHashSetupData->hashMode)) {
407a977168cSMichal Gulbicki 		LAC_UNSUPPORTED_PARAM_LOG(
408a977168cSMichal Gulbicki 		    "hashAlgorithm and hashMode combination");
409a977168cSMichal Gulbicki 		return CPA_STATUS_UNSUPPORTED;
41078ee8d1cSJulian Grajkowski 	}
41178ee8d1cSJulian Grajkowski 
41278ee8d1cSJulian Grajkowski 	LacSymQat_HashAlgLookupGet(instanceHandle,
41378ee8d1cSJulian Grajkowski 				   pHashSetupData->hashAlgorithm,
41478ee8d1cSJulian Grajkowski 				   &pHashAlgInfo);
41578ee8d1cSJulian Grajkowski 
41678ee8d1cSJulian Grajkowski 	/* note: nested hash mode checks digest length against outer algorithm
41778ee8d1cSJulian Grajkowski 	 */
41878ee8d1cSJulian Grajkowski 	if ((CPA_CY_SYM_HASH_MODE_PLAIN == pHashSetupData->hashMode) ||
41978ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_HASH_MODE_AUTH == pHashSetupData->hashMode)) {
42078ee8d1cSJulian Grajkowski 		/* Check Digest Length is permitted by the algorithm  */
42178ee8d1cSJulian Grajkowski 		if ((0 == pHashSetupData->digestResultLenInBytes) ||
42278ee8d1cSJulian Grajkowski 		    (pHashSetupData->digestResultLenInBytes >
42378ee8d1cSJulian Grajkowski 		     pHashAlgInfo->digestLength)) {
42478ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
42578ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
42678ee8d1cSJulian Grajkowski 		}
42778ee8d1cSJulian Grajkowski 	}
42878ee8d1cSJulian Grajkowski 
42978ee8d1cSJulian Grajkowski 	if (CPA_CY_SYM_HASH_MODE_AUTH == pHashSetupData->hashMode) {
43078ee8d1cSJulian Grajkowski 		if (CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm ||
43178ee8d1cSJulian Grajkowski 		    CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) {
43278ee8d1cSJulian Grajkowski 			Cpa32U aadDataSize = 0;
43378ee8d1cSJulian Grajkowski 
43478ee8d1cSJulian Grajkowski 			/* RFC 4106: Implementations MUST support a full-length
435a977168cSMichal Gulbicki 			 * 16-octet ICV, and MAY support 8 or 12 octet ICVs, and
436a977168cSMichal Gulbicki 			 * MUST NOT support other ICV lengths. */
43778ee8d1cSJulian Grajkowski 			if ((pHashSetupData->digestResultLenInBytes !=
43878ee8d1cSJulian Grajkowski 			     LAC_HASH_AES_GCM_ICV_SIZE_8) &&
43978ee8d1cSJulian Grajkowski 			    (pHashSetupData->digestResultLenInBytes !=
44078ee8d1cSJulian Grajkowski 			     LAC_HASH_AES_GCM_ICV_SIZE_12) &&
44178ee8d1cSJulian Grajkowski 			    (pHashSetupData->digestResultLenInBytes !=
44278ee8d1cSJulian Grajkowski 			     LAC_HASH_AES_GCM_ICV_SIZE_16)) {
44378ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
44478ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
44578ee8d1cSJulian Grajkowski 			}
44678ee8d1cSJulian Grajkowski 
44778ee8d1cSJulian Grajkowski 			/* ensure aadLen is within maximum limit imposed by QAT
44878ee8d1cSJulian Grajkowski 			 */
44978ee8d1cSJulian Grajkowski 			aadDataSize =
45078ee8d1cSJulian Grajkowski 			    pHashSetupData->authModeSetupData.aadLenInBytes;
45178ee8d1cSJulian Grajkowski 
45278ee8d1cSJulian Grajkowski 			/* round the aad size to the multiple of GCM hash block
45378ee8d1cSJulian Grajkowski 			 * size. */
45478ee8d1cSJulian Grajkowski 			aadDataSize =
45578ee8d1cSJulian Grajkowski 			    LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
45678ee8d1cSJulian Grajkowski 						   LAC_HASH_AES_GCM_BLOCK_SIZE);
45778ee8d1cSJulian Grajkowski 
45878ee8d1cSJulian Grajkowski 			if (aadDataSize > ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX &&
45978ee8d1cSJulian Grajkowski 			    CPA_CY_SYM_HASH_AES_GMAC !=
46078ee8d1cSJulian Grajkowski 				pHashSetupData->hashAlgorithm) {
46178ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("aadLenInBytes");
46278ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
46378ee8d1cSJulian Grajkowski 			}
46478ee8d1cSJulian Grajkowski 		} else if (CPA_CY_SYM_HASH_AES_CCM ==
46578ee8d1cSJulian Grajkowski 			   pHashSetupData->hashAlgorithm) {
46678ee8d1cSJulian Grajkowski 			Cpa32U aadDataSize = 0;
46778ee8d1cSJulian Grajkowski 
46878ee8d1cSJulian Grajkowski 			/* RFC 3610: Valid values are 4, 6, 8, 10, 12, 14, and
46978ee8d1cSJulian Grajkowski 			 * 16 octets */
47078ee8d1cSJulian Grajkowski 			if ((pHashSetupData->digestResultLenInBytes >=
47178ee8d1cSJulian Grajkowski 			     LAC_HASH_AES_CCM_ICV_SIZE_MIN) &&
47278ee8d1cSJulian Grajkowski 			    (pHashSetupData->digestResultLenInBytes <=
47378ee8d1cSJulian Grajkowski 			     LAC_HASH_AES_CCM_ICV_SIZE_MAX)) {
47478ee8d1cSJulian Grajkowski 				if ((pHashSetupData->digestResultLenInBytes &
47578ee8d1cSJulian Grajkowski 				     0x01) != 0) {
47678ee8d1cSJulian Grajkowski 					LAC_INVALID_PARAM_LOG(
47778ee8d1cSJulian Grajkowski 					    "digestResultLenInBytes must be a multiple of 2");
47878ee8d1cSJulian Grajkowski 					return CPA_STATUS_INVALID_PARAM;
47978ee8d1cSJulian Grajkowski 				}
48078ee8d1cSJulian Grajkowski 			} else {
48178ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
48278ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
48378ee8d1cSJulian Grajkowski 			}
48478ee8d1cSJulian Grajkowski 
48578ee8d1cSJulian Grajkowski 			/* ensure aadLen is within maximum limit imposed by QAT
48678ee8d1cSJulian Grajkowski 			 */
48778ee8d1cSJulian Grajkowski 			/* at the beginning of the buffer there is B0 block */
48878ee8d1cSJulian Grajkowski 			aadDataSize = LAC_HASH_AES_CCM_BLOCK_SIZE;
48978ee8d1cSJulian Grajkowski 
49078ee8d1cSJulian Grajkowski 			/* then, if there is some 'a' data, the buffer will
491a977168cSMichal Gulbicki 			 * store encoded length of 'a' and 'a' itself */
49278ee8d1cSJulian Grajkowski 			if (pHashSetupData->authModeSetupData.aadLenInBytes >
49378ee8d1cSJulian Grajkowski 			    0) {
49478ee8d1cSJulian Grajkowski 				/* as the QAT API puts the requirement on the
49578ee8d1cSJulian Grajkowski 				 * pAdditionalAuthData not to be bigger than 240
496a977168cSMichal Gulbicki 				 * bytes then we just need 2 bytes to store
497a977168cSMichal Gulbicki 				 * encoded length of 'a' */
49878ee8d1cSJulian Grajkowski 				aadDataSize += sizeof(Cpa16U);
49978ee8d1cSJulian Grajkowski 				aadDataSize += pHashSetupData->authModeSetupData
50078ee8d1cSJulian Grajkowski 						   .aadLenInBytes;
50178ee8d1cSJulian Grajkowski 			}
50278ee8d1cSJulian Grajkowski 
50378ee8d1cSJulian Grajkowski 			/* round the aad size to the multiple of CCM block
50478ee8d1cSJulian Grajkowski 			 * size.*/
50578ee8d1cSJulian Grajkowski 			aadDataSize =
50678ee8d1cSJulian Grajkowski 			    LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
50778ee8d1cSJulian Grajkowski 						   LAC_HASH_AES_CCM_BLOCK_SIZE);
50878ee8d1cSJulian Grajkowski 			if (aadDataSize > ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX) {
50978ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("aadLenInBytes");
51078ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
51178ee8d1cSJulian Grajkowski 			}
51278ee8d1cSJulian Grajkowski 		} else if (CPA_CY_SYM_HASH_KASUMI_F9 ==
51378ee8d1cSJulian Grajkowski 			   pHashSetupData->hashAlgorithm) {
51478ee8d1cSJulian Grajkowski 			/* QAT-FW only supports 128 bit Integrity Key size for
51578ee8d1cSJulian Grajkowski 			 * Kasumi f9
51678ee8d1cSJulian Grajkowski 			 *  Ref: 3GPP TS 35.201 version 7.0.0 Release 7 */
51778ee8d1cSJulian Grajkowski 			if (pHashSetupData->authModeSetupData
51878ee8d1cSJulian Grajkowski 				.authKeyLenInBytes !=
51978ee8d1cSJulian Grajkowski 			    ICP_QAT_HW_KASUMI_KEY_SZ) {
52078ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
52178ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
52278ee8d1cSJulian Grajkowski 			}
52378ee8d1cSJulian Grajkowski 		} else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
52478ee8d1cSJulian Grajkowski 			   pHashSetupData->hashAlgorithm) {
52578ee8d1cSJulian Grajkowski 
52678ee8d1cSJulian Grajkowski 			/* QAT-FW only supports 128 bits Integrity Key size for
52778ee8d1cSJulian Grajkowski 			 * Snow3g */
52878ee8d1cSJulian Grajkowski 			if (pHashSetupData->authModeSetupData
52978ee8d1cSJulian Grajkowski 				.authKeyLenInBytes !=
53078ee8d1cSJulian Grajkowski 			    ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ) {
53178ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
53278ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
53378ee8d1cSJulian Grajkowski 			}
53478ee8d1cSJulian Grajkowski 			/* For Snow3g hash aad field contains IV - it needs to
535a977168cSMichal Gulbicki 			 * be 16 bytes long
53678ee8d1cSJulian Grajkowski 			 */
53778ee8d1cSJulian Grajkowski 			if (pHashSetupData->authModeSetupData.aadLenInBytes !=
53878ee8d1cSJulian Grajkowski 			    ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ) {
53978ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("aadLenInBytes");
54078ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
54178ee8d1cSJulian Grajkowski 			}
54278ee8d1cSJulian Grajkowski 		} else if (CPA_CY_SYM_HASH_AES_XCBC ==
54378ee8d1cSJulian Grajkowski 			       pHashSetupData->hashAlgorithm ||
54478ee8d1cSJulian Grajkowski 			   CPA_CY_SYM_HASH_AES_CMAC ==
54578ee8d1cSJulian Grajkowski 			       pHashSetupData->hashAlgorithm ||
54678ee8d1cSJulian Grajkowski 			   CPA_CY_SYM_HASH_AES_CBC_MAC ==
54778ee8d1cSJulian Grajkowski 			       pHashSetupData->hashAlgorithm) {
54878ee8d1cSJulian Grajkowski 			/* ensure auth key len is valid (128-bit keys supported)
54978ee8d1cSJulian Grajkowski 			 */
55078ee8d1cSJulian Grajkowski 			if ((pHashSetupData->authModeSetupData
55178ee8d1cSJulian Grajkowski 				 .authKeyLenInBytes !=
55278ee8d1cSJulian Grajkowski 			     ICP_QAT_HW_AES_128_KEY_SZ)) {
55378ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
55478ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
55578ee8d1cSJulian Grajkowski 			}
55678ee8d1cSJulian Grajkowski 		} else if (CPA_CY_SYM_HASH_ZUC_EIA3 ==
55778ee8d1cSJulian Grajkowski 			   pHashSetupData->hashAlgorithm) {
55878ee8d1cSJulian Grajkowski 
55978ee8d1cSJulian Grajkowski 			/* QAT-FW only supports 128 bits Integrity Key size for
56078ee8d1cSJulian Grajkowski 			 * ZUC */
56178ee8d1cSJulian Grajkowski 			if (pHashSetupData->authModeSetupData
56278ee8d1cSJulian Grajkowski 				.authKeyLenInBytes !=
56378ee8d1cSJulian Grajkowski 			    ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) {
56478ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
56578ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
56678ee8d1cSJulian Grajkowski 			}
56778ee8d1cSJulian Grajkowski 			/* For ZUC EIA3 hash aad field contains IV - it needs to
568a977168cSMichal Gulbicki 			 * be 16 bytes long
56978ee8d1cSJulian Grajkowski 			 */
57078ee8d1cSJulian Grajkowski 			if (pHashSetupData->authModeSetupData.aadLenInBytes !=
57178ee8d1cSJulian Grajkowski 			    ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ) {
57278ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("aadLenInBytes");
57378ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
57478ee8d1cSJulian Grajkowski 			}
57578ee8d1cSJulian Grajkowski 		} else if (CPA_CY_SYM_HASH_POLY ==
57678ee8d1cSJulian Grajkowski 			   pHashSetupData->hashAlgorithm) {
57778ee8d1cSJulian Grajkowski 			if (pHashSetupData->digestResultLenInBytes !=
57878ee8d1cSJulian Grajkowski 			    ICP_QAT_HW_SPC_CTR_SZ) {
57978ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("Digest Length for CCP");
58078ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
58178ee8d1cSJulian Grajkowski 			}
58278ee8d1cSJulian Grajkowski 			if (pHashSetupData->authModeSetupData.aadLenInBytes >
58378ee8d1cSJulian Grajkowski 			    ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX) {
58478ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("AAD Length for CCP");
58578ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
58678ee8d1cSJulian Grajkowski 			}
58778ee8d1cSJulian Grajkowski 		} else {
58878ee8d1cSJulian Grajkowski 			/* The key size must be less than or equal the block
58978ee8d1cSJulian Grajkowski 			 * length */
59078ee8d1cSJulian Grajkowski 			if (pHashSetupData->authModeSetupData
59178ee8d1cSJulian Grajkowski 				.authKeyLenInBytes >
59278ee8d1cSJulian Grajkowski 			    pHashAlgInfo->blockLength) {
59378ee8d1cSJulian Grajkowski 				LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
59478ee8d1cSJulian Grajkowski 				return CPA_STATUS_INVALID_PARAM;
59578ee8d1cSJulian Grajkowski 			}
59678ee8d1cSJulian Grajkowski 		}
59778ee8d1cSJulian Grajkowski 
59878ee8d1cSJulian Grajkowski 		/* when the key size is greater than 0 check pointer is not null
59978ee8d1cSJulian Grajkowski 		 */
60078ee8d1cSJulian Grajkowski 		if (CPA_CY_SYM_HASH_AES_CCM != pHashSetupData->hashAlgorithm &&
60178ee8d1cSJulian Grajkowski 		    CPA_CY_SYM_HASH_AES_GCM != pHashSetupData->hashAlgorithm &&
60278ee8d1cSJulian Grajkowski 		    pHashSetupData->authModeSetupData.authKeyLenInBytes > 0) {
60378ee8d1cSJulian Grajkowski 			LAC_CHECK_NULL_PARAM(
60478ee8d1cSJulian Grajkowski 			    pHashSetupData->authModeSetupData.authKey);
60578ee8d1cSJulian Grajkowski 		}
60678ee8d1cSJulian Grajkowski 	} else if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
60778ee8d1cSJulian Grajkowski 		if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
60878ee8d1cSJulian Grajkowski 					 pHashSetupData->nestedModeSetupData
60978ee8d1cSJulian Grajkowski 					     .outerHashAlgorithm)) {
61078ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("outerHashAlgorithm");
61178ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
61278ee8d1cSJulian Grajkowski 		}
61378ee8d1cSJulian Grajkowski 
61478ee8d1cSJulian Grajkowski 		if (LAC_HASH_ALG_MODE_NOT_SUPPORTED(
61578ee8d1cSJulian Grajkowski 			pHashSetupData->nestedModeSetupData.outerHashAlgorithm,
61678ee8d1cSJulian Grajkowski 			pHashSetupData->hashMode)) {
61778ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
61878ee8d1cSJulian Grajkowski 			    "outerHashAlgorithm and hashMode combination");
61978ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
62078ee8d1cSJulian Grajkowski 		}
62178ee8d1cSJulian Grajkowski 
62278ee8d1cSJulian Grajkowski 		LacSymQat_HashAlgLookupGet(
62378ee8d1cSJulian Grajkowski 		    instanceHandle,
62478ee8d1cSJulian Grajkowski 		    pHashSetupData->nestedModeSetupData.outerHashAlgorithm,
62578ee8d1cSJulian Grajkowski 		    &pOuterHashAlgInfo);
62678ee8d1cSJulian Grajkowski 
62778ee8d1cSJulian Grajkowski 		/* Check Digest Length is permitted by the algorithm  */
62878ee8d1cSJulian Grajkowski 		if ((0 == pHashSetupData->digestResultLenInBytes) ||
62978ee8d1cSJulian Grajkowski 		    (pHashSetupData->digestResultLenInBytes >
63078ee8d1cSJulian Grajkowski 		     pOuterHashAlgInfo->digestLength)) {
63178ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
63278ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
63378ee8d1cSJulian Grajkowski 		}
63478ee8d1cSJulian Grajkowski 
63578ee8d1cSJulian Grajkowski 		if (pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes >
63678ee8d1cSJulian Grajkowski 		    LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES) {
63778ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("innerPrefixLenInBytes");
63878ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
63978ee8d1cSJulian Grajkowski 		}
64078ee8d1cSJulian Grajkowski 
64178ee8d1cSJulian Grajkowski 		if (pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes >
64278ee8d1cSJulian Grajkowski 		    0) {
64378ee8d1cSJulian Grajkowski 			LAC_CHECK_NULL_PARAM(pHashSetupData->nestedModeSetupData
64478ee8d1cSJulian Grajkowski 						 .pInnerPrefixData);
64578ee8d1cSJulian Grajkowski 		}
64678ee8d1cSJulian Grajkowski 
64778ee8d1cSJulian Grajkowski 		if (pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes >
64878ee8d1cSJulian Grajkowski 		    LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES) {
64978ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("outerPrefixLenInBytes");
65078ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
65178ee8d1cSJulian Grajkowski 		}
65278ee8d1cSJulian Grajkowski 
65378ee8d1cSJulian Grajkowski 		if (pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes >
65478ee8d1cSJulian Grajkowski 		    0) {
65578ee8d1cSJulian Grajkowski 			LAC_CHECK_NULL_PARAM(pHashSetupData->nestedModeSetupData
65678ee8d1cSJulian Grajkowski 						 .pOuterPrefixData);
65778ee8d1cSJulian Grajkowski 		}
65878ee8d1cSJulian Grajkowski 	}
65978ee8d1cSJulian Grajkowski 
66078ee8d1cSJulian Grajkowski 	return CPA_STATUS_SUCCESS;
66178ee8d1cSJulian Grajkowski }
66278ee8d1cSJulian Grajkowski 
66378ee8d1cSJulian Grajkowski /** @ingroup LacHash */
66478ee8d1cSJulian Grajkowski CpaStatus
LacHash_PerformParamCheck(CpaInstanceHandle instanceHandle,lac_session_desc_t * pSessionDesc,const CpaCySymOpData * pOpData,Cpa64U srcPktSize,const CpaBoolean * pVerifyResult)66578ee8d1cSJulian Grajkowski LacHash_PerformParamCheck(CpaInstanceHandle instanceHandle,
66678ee8d1cSJulian Grajkowski 			  lac_session_desc_t *pSessionDesc,
66778ee8d1cSJulian Grajkowski 			  const CpaCySymOpData *pOpData,
66878ee8d1cSJulian Grajkowski 			  Cpa64U srcPktSize,
66978ee8d1cSJulian Grajkowski 			  const CpaBoolean *pVerifyResult)
67078ee8d1cSJulian Grajkowski {
67178ee8d1cSJulian Grajkowski 	CpaStatus status = CPA_STATUS_SUCCESS;
67278ee8d1cSJulian Grajkowski 	lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
673a977168cSMichal Gulbicki 	CpaBoolean digestIsAppended = pSessionDesc->digestIsAppended;
674a977168cSMichal Gulbicki 	CpaBoolean digestVerify = pSessionDesc->digestVerify;
675a977168cSMichal Gulbicki 	CpaCySymOp symOperation = pSessionDesc->symOperation;
676a977168cSMichal Gulbicki 	CpaCySymHashAlgorithm hashAlgorithm = pSessionDesc->hashAlgorithm;
67778ee8d1cSJulian Grajkowski 
67878ee8d1cSJulian Grajkowski 	/* digestVerify and digestIsAppended on Hash-Only operation not
67978ee8d1cSJulian Grajkowski 	 * supported */
680a977168cSMichal Gulbicki 	if (digestIsAppended && digestVerify &&
681a977168cSMichal Gulbicki 	    (CPA_CY_SYM_OP_HASH == symOperation)) {
68278ee8d1cSJulian Grajkowski 		LAC_INVALID_PARAM_LOG(
68378ee8d1cSJulian Grajkowski 		    "digestVerify and digestIsAppended set "
68478ee8d1cSJulian Grajkowski 		    "on Hash-Only operation is not supported");
68578ee8d1cSJulian Grajkowski 		return CPA_STATUS_INVALID_PARAM;
68678ee8d1cSJulian Grajkowski 	}
68778ee8d1cSJulian Grajkowski 
68878ee8d1cSJulian Grajkowski 	/* check the digest result pointer */
68978ee8d1cSJulian Grajkowski 	if ((CPA_CY_SYM_PACKET_TYPE_PARTIAL != pOpData->packetType) &&
690a977168cSMichal Gulbicki 	    !digestIsAppended && (NULL == pOpData->pDigestResult)) {
69178ee8d1cSJulian Grajkowski 		LAC_INVALID_PARAM_LOG("pDigestResult is NULL");
69278ee8d1cSJulian Grajkowski 		return CPA_STATUS_INVALID_PARAM;
69378ee8d1cSJulian Grajkowski 	}
69478ee8d1cSJulian Grajkowski 
69578ee8d1cSJulian Grajkowski 	/*
69678ee8d1cSJulian Grajkowski 	 * Check if the pVerifyResult pointer is not null for hash operation
697a977168cSMichal Gulbicki 	 * when the packet is the last one and user has set verifyDigest flag
69878ee8d1cSJulian Grajkowski 	 * Also, this is only needed for symchronous operation, so check if the
69978ee8d1cSJulian Grajkowski 	 * callback pointer is the internal synchronous one rather than a user-
70078ee8d1cSJulian Grajkowski 	 * supplied one.
70178ee8d1cSJulian Grajkowski 	 */
702a977168cSMichal Gulbicki 	if ((CPA_TRUE == digestVerify) &&
70378ee8d1cSJulian Grajkowski 	    (CPA_CY_SYM_PACKET_TYPE_PARTIAL != pOpData->packetType) &&
70478ee8d1cSJulian Grajkowski 	    (LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb)) {
70578ee8d1cSJulian Grajkowski 		if (NULL == pVerifyResult) {
70678ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
70778ee8d1cSJulian Grajkowski 			    "Null pointer pVerifyResult for hash op");
70878ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
70978ee8d1cSJulian Grajkowski 		}
71078ee8d1cSJulian Grajkowski 	}
71178ee8d1cSJulian Grajkowski 
71278ee8d1cSJulian Grajkowski 	/* verify start offset + messageLenToDigest is inside the source packet.
71378ee8d1cSJulian Grajkowski 	 * this also verifies that the start offset is inside the packet
71478ee8d1cSJulian Grajkowski 	 * Note: digest is specified as a pointer therefore it can be
71578ee8d1cSJulian Grajkowski 	 * written anywhere so we cannot check for this been inside a buffer
71678ee8d1cSJulian Grajkowski 	 * CCM/GCM specify the auth region using just the cipher params as this
71778ee8d1cSJulian Grajkowski 	 * region is the same for auth and cipher. It is not checked here */
718a977168cSMichal Gulbicki 	if ((CPA_CY_SYM_HASH_AES_CCM == hashAlgorithm) ||
719a977168cSMichal Gulbicki 	    (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm)) {
72078ee8d1cSJulian Grajkowski 		/* ensure AAD data pointer is non-NULL if AAD len > 0 */
72178ee8d1cSJulian Grajkowski 		if ((pSessionDesc->aadLenInBytes > 0) &&
72278ee8d1cSJulian Grajkowski 		    (NULL == pOpData->pAdditionalAuthData)) {
72378ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("pAdditionalAuthData is NULL");
72478ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
72578ee8d1cSJulian Grajkowski 		}
72678ee8d1cSJulian Grajkowski 	} else {
72778ee8d1cSJulian Grajkowski 		if ((pOpData->hashStartSrcOffsetInBytes +
72878ee8d1cSJulian Grajkowski 		     pOpData->messageLenToHashInBytes) > srcPktSize) {
72978ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
73078ee8d1cSJulian Grajkowski 			    "hashStartSrcOffsetInBytes + "
73178ee8d1cSJulian Grajkowski 			    "messageLenToHashInBytes > Src Buffer Packet Length");
73278ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
73378ee8d1cSJulian Grajkowski 		}
73478ee8d1cSJulian Grajkowski 	}
73578ee8d1cSJulian Grajkowski 
73678ee8d1cSJulian Grajkowski 	/* For Snow3g & ZUC hash pAdditionalAuthData field
73778ee8d1cSJulian Grajkowski 	 * of OpData should contain IV */
738a977168cSMichal Gulbicki 	if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) ||
739a977168cSMichal Gulbicki 	    (CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm)) {
74078ee8d1cSJulian Grajkowski 		if (NULL == pOpData->pAdditionalAuthData) {
74178ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG("pAdditionalAuthData is NULL");
74278ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
74378ee8d1cSJulian Grajkowski 		}
74478ee8d1cSJulian Grajkowski 	}
74578ee8d1cSJulian Grajkowski 
74678ee8d1cSJulian Grajkowski 	/* partial packets need to be multiples of the algorithm block size in
747a977168cSMichal Gulbicki 	 * hash only mode (except for final partial packet) */
74878ee8d1cSJulian Grajkowski 	if ((CPA_CY_SYM_PACKET_TYPE_PARTIAL == pOpData->packetType) &&
749a977168cSMichal Gulbicki 	    (CPA_CY_SYM_OP_HASH == symOperation)) {
75078ee8d1cSJulian Grajkowski 		LacSymQat_HashAlgLookupGet(instanceHandle,
751a977168cSMichal Gulbicki 					   hashAlgorithm,
75278ee8d1cSJulian Grajkowski 					   &pHashAlgInfo);
75378ee8d1cSJulian Grajkowski 
75478ee8d1cSJulian Grajkowski 		/* check if the message is a multiple of the block size. */
75578ee8d1cSJulian Grajkowski 		if ((pOpData->messageLenToHashInBytes %
75678ee8d1cSJulian Grajkowski 		     pHashAlgInfo->blockLength) != 0) {
75778ee8d1cSJulian Grajkowski 			LAC_INVALID_PARAM_LOG(
75878ee8d1cSJulian Grajkowski 			    "messageLenToHashInBytes not block size");
75978ee8d1cSJulian Grajkowski 			return CPA_STATUS_INVALID_PARAM;
76078ee8d1cSJulian Grajkowski 		}
76178ee8d1cSJulian Grajkowski 	}
76278ee8d1cSJulian Grajkowski 
76378ee8d1cSJulian Grajkowski 	return status;
76478ee8d1cSJulian Grajkowski }
76578ee8d1cSJulian Grajkowski 
766