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