1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 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
370 /** @ingroup LacHash */
371 CpaStatus
LacHash_HashContextCheck(CpaInstanceHandle instanceHandle,const CpaCySymHashSetupData * pHashSetupData)372 LacHash_HashContextCheck(CpaInstanceHandle instanceHandle,
373 const CpaCySymHashSetupData *pHashSetupData)
374 {
375 lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
376 lac_sym_qat_hash_alg_info_t *pOuterHashAlgInfo = NULL;
377 CpaCySymCapabilitiesInfo capInfo;
378
379 /*Protect against value of hash outside the bitmap*/
380 if (pHashSetupData->hashAlgorithm >= CPA_CY_SYM_HASH_CAP_BITMAP_SIZE) {
381 LAC_INVALID_PARAM_LOG("hashAlgorithm");
382 return CPA_STATUS_INVALID_PARAM;
383 }
384
385 cpaCySymQueryCapabilities(instanceHandle, &capInfo);
386 if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
387 pHashSetupData->hashAlgorithm) &&
388 pHashSetupData->hashAlgorithm != CPA_CY_SYM_HASH_AES_CBC_MAC) {
389 LAC_INVALID_PARAM_LOG("hashAlgorithm");
390 return CPA_STATUS_INVALID_PARAM;
391 }
392
393 switch (pHashSetupData->hashMode) {
394 case CPA_CY_SYM_HASH_MODE_PLAIN:
395 case CPA_CY_SYM_HASH_MODE_AUTH:
396 case CPA_CY_SYM_HASH_MODE_NESTED:
397 break;
398
399 default: {
400 LAC_INVALID_PARAM_LOG("hashMode");
401 return CPA_STATUS_INVALID_PARAM;
402 }
403 }
404
405 if (LAC_HASH_ALG_MODE_NOT_SUPPORTED(pHashSetupData->hashAlgorithm,
406 pHashSetupData->hashMode)) {
407 LAC_UNSUPPORTED_PARAM_LOG(
408 "hashAlgorithm and hashMode combination");
409 return CPA_STATUS_UNSUPPORTED;
410 }
411
412 LacSymQat_HashAlgLookupGet(instanceHandle,
413 pHashSetupData->hashAlgorithm,
414 &pHashAlgInfo);
415
416 /* note: nested hash mode checks digest length against outer algorithm
417 */
418 if ((CPA_CY_SYM_HASH_MODE_PLAIN == pHashSetupData->hashMode) ||
419 (CPA_CY_SYM_HASH_MODE_AUTH == pHashSetupData->hashMode)) {
420 /* Check Digest Length is permitted by the algorithm */
421 if ((0 == pHashSetupData->digestResultLenInBytes) ||
422 (pHashSetupData->digestResultLenInBytes >
423 pHashAlgInfo->digestLength)) {
424 LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
425 return CPA_STATUS_INVALID_PARAM;
426 }
427 }
428
429 if (CPA_CY_SYM_HASH_MODE_AUTH == pHashSetupData->hashMode) {
430 if (CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm ||
431 CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) {
432 Cpa32U aadDataSize = 0;
433
434 /* RFC 4106: Implementations MUST support a full-length
435 * 16-octet ICV, and MAY support 8 or 12 octet ICVs, and
436 * MUST NOT support other ICV lengths. */
437 if ((pHashSetupData->digestResultLenInBytes !=
438 LAC_HASH_AES_GCM_ICV_SIZE_8) &&
439 (pHashSetupData->digestResultLenInBytes !=
440 LAC_HASH_AES_GCM_ICV_SIZE_12) &&
441 (pHashSetupData->digestResultLenInBytes !=
442 LAC_HASH_AES_GCM_ICV_SIZE_16)) {
443 LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
444 return CPA_STATUS_INVALID_PARAM;
445 }
446
447 /* ensure aadLen is within maximum limit imposed by QAT
448 */
449 aadDataSize =
450 pHashSetupData->authModeSetupData.aadLenInBytes;
451
452 /* round the aad size to the multiple of GCM hash block
453 * size. */
454 aadDataSize =
455 LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
456 LAC_HASH_AES_GCM_BLOCK_SIZE);
457
458 if (aadDataSize > ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX &&
459 CPA_CY_SYM_HASH_AES_GMAC !=
460 pHashSetupData->hashAlgorithm) {
461 LAC_INVALID_PARAM_LOG("aadLenInBytes");
462 return CPA_STATUS_INVALID_PARAM;
463 }
464 } else if (CPA_CY_SYM_HASH_AES_CCM ==
465 pHashSetupData->hashAlgorithm) {
466 Cpa32U aadDataSize = 0;
467
468 /* RFC 3610: Valid values are 4, 6, 8, 10, 12, 14, and
469 * 16 octets */
470 if ((pHashSetupData->digestResultLenInBytes >=
471 LAC_HASH_AES_CCM_ICV_SIZE_MIN) &&
472 (pHashSetupData->digestResultLenInBytes <=
473 LAC_HASH_AES_CCM_ICV_SIZE_MAX)) {
474 if ((pHashSetupData->digestResultLenInBytes &
475 0x01) != 0) {
476 LAC_INVALID_PARAM_LOG(
477 "digestResultLenInBytes must be a multiple of 2");
478 return CPA_STATUS_INVALID_PARAM;
479 }
480 } else {
481 LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
482 return CPA_STATUS_INVALID_PARAM;
483 }
484
485 /* ensure aadLen is within maximum limit imposed by QAT
486 */
487 /* at the beginning of the buffer there is B0 block */
488 aadDataSize = LAC_HASH_AES_CCM_BLOCK_SIZE;
489
490 /* then, if there is some 'a' data, the buffer will
491 * store encoded length of 'a' and 'a' itself */
492 if (pHashSetupData->authModeSetupData.aadLenInBytes >
493 0) {
494 /* as the QAT API puts the requirement on the
495 * pAdditionalAuthData not to be bigger than 240
496 * bytes then we just need 2 bytes to store
497 * encoded length of 'a' */
498 aadDataSize += sizeof(Cpa16U);
499 aadDataSize += pHashSetupData->authModeSetupData
500 .aadLenInBytes;
501 }
502
503 /* round the aad size to the multiple of CCM block
504 * size.*/
505 aadDataSize =
506 LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
507 LAC_HASH_AES_CCM_BLOCK_SIZE);
508 if (aadDataSize > ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX) {
509 LAC_INVALID_PARAM_LOG("aadLenInBytes");
510 return CPA_STATUS_INVALID_PARAM;
511 }
512 } else if (CPA_CY_SYM_HASH_KASUMI_F9 ==
513 pHashSetupData->hashAlgorithm) {
514 /* QAT-FW only supports 128 bit Integrity Key size for
515 * Kasumi f9
516 * Ref: 3GPP TS 35.201 version 7.0.0 Release 7 */
517 if (pHashSetupData->authModeSetupData
518 .authKeyLenInBytes !=
519 ICP_QAT_HW_KASUMI_KEY_SZ) {
520 LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
521 return CPA_STATUS_INVALID_PARAM;
522 }
523 } else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
524 pHashSetupData->hashAlgorithm) {
525
526 /* QAT-FW only supports 128 bits Integrity Key size for
527 * Snow3g */
528 if (pHashSetupData->authModeSetupData
529 .authKeyLenInBytes !=
530 ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ) {
531 LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
532 return CPA_STATUS_INVALID_PARAM;
533 }
534 /* For Snow3g hash aad field contains IV - it needs to
535 * be 16 bytes long
536 */
537 if (pHashSetupData->authModeSetupData.aadLenInBytes !=
538 ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ) {
539 LAC_INVALID_PARAM_LOG("aadLenInBytes");
540 return CPA_STATUS_INVALID_PARAM;
541 }
542 } else if (CPA_CY_SYM_HASH_AES_XCBC ==
543 pHashSetupData->hashAlgorithm ||
544 CPA_CY_SYM_HASH_AES_CMAC ==
545 pHashSetupData->hashAlgorithm ||
546 CPA_CY_SYM_HASH_AES_CBC_MAC ==
547 pHashSetupData->hashAlgorithm) {
548 /* ensure auth key len is valid (128-bit keys supported)
549 */
550 if ((pHashSetupData->authModeSetupData
551 .authKeyLenInBytes !=
552 ICP_QAT_HW_AES_128_KEY_SZ)) {
553 LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
554 return CPA_STATUS_INVALID_PARAM;
555 }
556 } else if (CPA_CY_SYM_HASH_ZUC_EIA3 ==
557 pHashSetupData->hashAlgorithm) {
558
559 /* QAT-FW only supports 128 bits Integrity Key size for
560 * ZUC */
561 if (pHashSetupData->authModeSetupData
562 .authKeyLenInBytes !=
563 ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) {
564 LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
565 return CPA_STATUS_INVALID_PARAM;
566 }
567 /* For ZUC EIA3 hash aad field contains IV - it needs to
568 * be 16 bytes long
569 */
570 if (pHashSetupData->authModeSetupData.aadLenInBytes !=
571 ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ) {
572 LAC_INVALID_PARAM_LOG("aadLenInBytes");
573 return CPA_STATUS_INVALID_PARAM;
574 }
575 } else if (CPA_CY_SYM_HASH_POLY ==
576 pHashSetupData->hashAlgorithm) {
577 if (pHashSetupData->digestResultLenInBytes !=
578 ICP_QAT_HW_SPC_CTR_SZ) {
579 LAC_INVALID_PARAM_LOG("Digest Length for CCP");
580 return CPA_STATUS_INVALID_PARAM;
581 }
582 if (pHashSetupData->authModeSetupData.aadLenInBytes >
583 ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX) {
584 LAC_INVALID_PARAM_LOG("AAD Length for CCP");
585 return CPA_STATUS_INVALID_PARAM;
586 }
587 } else {
588 /* The key size must be less than or equal the block
589 * length */
590 if (pHashSetupData->authModeSetupData
591 .authKeyLenInBytes >
592 pHashAlgInfo->blockLength) {
593 LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
594 return CPA_STATUS_INVALID_PARAM;
595 }
596 }
597
598 /* when the key size is greater than 0 check pointer is not null
599 */
600 if (CPA_CY_SYM_HASH_AES_CCM != pHashSetupData->hashAlgorithm &&
601 CPA_CY_SYM_HASH_AES_GCM != pHashSetupData->hashAlgorithm &&
602 pHashSetupData->authModeSetupData.authKeyLenInBytes > 0) {
603 LAC_CHECK_NULL_PARAM(
604 pHashSetupData->authModeSetupData.authKey);
605 }
606 } else if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
607 if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
608 pHashSetupData->nestedModeSetupData
609 .outerHashAlgorithm)) {
610 LAC_INVALID_PARAM_LOG("outerHashAlgorithm");
611 return CPA_STATUS_INVALID_PARAM;
612 }
613
614 if (LAC_HASH_ALG_MODE_NOT_SUPPORTED(
615 pHashSetupData->nestedModeSetupData.outerHashAlgorithm,
616 pHashSetupData->hashMode)) {
617 LAC_INVALID_PARAM_LOG(
618 "outerHashAlgorithm and hashMode combination");
619 return CPA_STATUS_INVALID_PARAM;
620 }
621
622 LacSymQat_HashAlgLookupGet(
623 instanceHandle,
624 pHashSetupData->nestedModeSetupData.outerHashAlgorithm,
625 &pOuterHashAlgInfo);
626
627 /* Check Digest Length is permitted by the algorithm */
628 if ((0 == pHashSetupData->digestResultLenInBytes) ||
629 (pHashSetupData->digestResultLenInBytes >
630 pOuterHashAlgInfo->digestLength)) {
631 LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
632 return CPA_STATUS_INVALID_PARAM;
633 }
634
635 if (pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes >
636 LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES) {
637 LAC_INVALID_PARAM_LOG("innerPrefixLenInBytes");
638 return CPA_STATUS_INVALID_PARAM;
639 }
640
641 if (pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes >
642 0) {
643 LAC_CHECK_NULL_PARAM(pHashSetupData->nestedModeSetupData
644 .pInnerPrefixData);
645 }
646
647 if (pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes >
648 LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES) {
649 LAC_INVALID_PARAM_LOG("outerPrefixLenInBytes");
650 return CPA_STATUS_INVALID_PARAM;
651 }
652
653 if (pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes >
654 0) {
655 LAC_CHECK_NULL_PARAM(pHashSetupData->nestedModeSetupData
656 .pOuterPrefixData);
657 }
658 }
659
660 return CPA_STATUS_SUCCESS;
661 }
662
663 /** @ingroup LacHash */
664 CpaStatus
LacHash_PerformParamCheck(CpaInstanceHandle instanceHandle,lac_session_desc_t * pSessionDesc,const CpaCySymOpData * pOpData,Cpa64U srcPktSize,const CpaBoolean * pVerifyResult)665 LacHash_PerformParamCheck(CpaInstanceHandle instanceHandle,
666 lac_session_desc_t *pSessionDesc,
667 const CpaCySymOpData *pOpData,
668 Cpa64U srcPktSize,
669 const CpaBoolean *pVerifyResult)
670 {
671 CpaStatus status = CPA_STATUS_SUCCESS;
672 lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
673 CpaBoolean digestIsAppended = pSessionDesc->digestIsAppended;
674 CpaBoolean digestVerify = pSessionDesc->digestVerify;
675 CpaCySymOp symOperation = pSessionDesc->symOperation;
676 CpaCySymHashAlgorithm hashAlgorithm = pSessionDesc->hashAlgorithm;
677
678 /* digestVerify and digestIsAppended on Hash-Only operation not
679 * supported */
680 if (digestIsAppended && digestVerify &&
681 (CPA_CY_SYM_OP_HASH == symOperation)) {
682 LAC_INVALID_PARAM_LOG(
683 "digestVerify and digestIsAppended set "
684 "on Hash-Only operation is not supported");
685 return CPA_STATUS_INVALID_PARAM;
686 }
687
688 /* check the digest result pointer */
689 if ((CPA_CY_SYM_PACKET_TYPE_PARTIAL != pOpData->packetType) &&
690 !digestIsAppended && (NULL == pOpData->pDigestResult)) {
691 LAC_INVALID_PARAM_LOG("pDigestResult is NULL");
692 return CPA_STATUS_INVALID_PARAM;
693 }
694
695 /*
696 * Check if the pVerifyResult pointer is not null for hash operation
697 * when the packet is the last one and user has set verifyDigest flag
698 * Also, this is only needed for symchronous operation, so check if the
699 * callback pointer is the internal synchronous one rather than a user-
700 * supplied one.
701 */
702 if ((CPA_TRUE == digestVerify) &&
703 (CPA_CY_SYM_PACKET_TYPE_PARTIAL != pOpData->packetType) &&
704 (LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb)) {
705 if (NULL == pVerifyResult) {
706 LAC_INVALID_PARAM_LOG(
707 "Null pointer pVerifyResult for hash op");
708 return CPA_STATUS_INVALID_PARAM;
709 }
710 }
711
712 /* verify start offset + messageLenToDigest is inside the source packet.
713 * this also verifies that the start offset is inside the packet
714 * Note: digest is specified as a pointer therefore it can be
715 * written anywhere so we cannot check for this been inside a buffer
716 * CCM/GCM specify the auth region using just the cipher params as this
717 * region is the same for auth and cipher. It is not checked here */
718 if ((CPA_CY_SYM_HASH_AES_CCM == hashAlgorithm) ||
719 (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm)) {
720 /* ensure AAD data pointer is non-NULL if AAD len > 0 */
721 if ((pSessionDesc->aadLenInBytes > 0) &&
722 (NULL == pOpData->pAdditionalAuthData)) {
723 LAC_INVALID_PARAM_LOG("pAdditionalAuthData is NULL");
724 return CPA_STATUS_INVALID_PARAM;
725 }
726 } else {
727 if ((pOpData->hashStartSrcOffsetInBytes +
728 pOpData->messageLenToHashInBytes) > srcPktSize) {
729 LAC_INVALID_PARAM_LOG(
730 "hashStartSrcOffsetInBytes + "
731 "messageLenToHashInBytes > Src Buffer Packet Length");
732 return CPA_STATUS_INVALID_PARAM;
733 }
734 }
735
736 /* For Snow3g & ZUC hash pAdditionalAuthData field
737 * of OpData should contain IV */
738 if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) ||
739 (CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm)) {
740 if (NULL == pOpData->pAdditionalAuthData) {
741 LAC_INVALID_PARAM_LOG("pAdditionalAuthData is NULL");
742 return CPA_STATUS_INVALID_PARAM;
743 }
744 }
745
746 /* partial packets need to be multiples of the algorithm block size in
747 * hash only mode (except for final partial packet) */
748 if ((CPA_CY_SYM_PACKET_TYPE_PARTIAL == pOpData->packetType) &&
749 (CPA_CY_SYM_OP_HASH == symOperation)) {
750 LacSymQat_HashAlgLookupGet(instanceHandle,
751 hashAlgorithm,
752 &pHashAlgInfo);
753
754 /* check if the message is a multiple of the block size. */
755 if ((pOpData->messageLenToHashInBytes %
756 pHashAlgInfo->blockLength) != 0) {
757 LAC_INVALID_PARAM_LOG(
758 "messageLenToHashInBytes not block size");
759 return CPA_STATUS_INVALID_PARAM;
760 }
761 }
762
763 return status;
764 }
765
766