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