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