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 767