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 76 LacHash_SyncPrecomputeDoneCb(void *pCallbackTag) 77 { 78 LacSync_GenWakeupSyncCaller(pCallbackTag, CPA_STATUS_SUCCESS); 79 } 80 81 /** @ingroup LacHash */ 82 CpaStatus 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 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 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 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