1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 4 /** 5 *************************************************************************** 6 * @file lac_sym_api.c Implementation of the symmetric API 7 * 8 * @ingroup LacSym 9 * 10 ***************************************************************************/ 11 12 /* 13 ******************************************************************************* 14 * Include public/global header files 15 ******************************************************************************* 16 */ 17 18 #include "cpa.h" 19 #include "cpa_cy_sym.h" 20 #include "cpa_cy_im.h" 21 22 #include "icp_adf_init.h" 23 #include "icp_adf_transport.h" 24 #include "icp_adf_transport_dp.h" 25 #include "icp_accel_devices.h" 26 #include "icp_adf_debug.h" 27 #include "icp_qat_fw_la.h" 28 29 /* 30 ****************************************************************************** 31 * Include private header files 32 ****************************************************************************** 33 */ 34 #include "lac_common.h" 35 #include "lac_log.h" 36 #include "lac_mem.h" 37 #include "lac_mem_pools.h" 38 #include "lac_list.h" 39 #include "lac_sym.h" 40 #include "lac_sym_qat.h" 41 #include "lac_sal.h" 42 #include "lac_sal_ctrl.h" 43 #include "lac_session.h" 44 #include "lac_sym_cipher.h" 45 #include "lac_sym_hash.h" 46 #include "lac_sym_alg_chain.h" 47 #include "lac_sym_stats.h" 48 #include "lac_sym_partial.h" 49 #include "lac_sym_qat_hash_defs_lookup.h" 50 #include "lac_sym_cb.h" 51 #include "lac_buffer_desc.h" 52 #include "lac_sync.h" 53 #include "lac_hooks.h" 54 #include "lac_sal_types_crypto.h" 55 #include "sal_service_state.h" 56 57 #define IS_EXT_ALG_CHAIN_UNSUPPORTED(cipherAlgorithm, \ 58 hashAlgorithm, \ 59 extAlgchainSupported) \ 60 ((((CPA_CY_SYM_CIPHER_ZUC_EEA3 == cipherAlgorithm || \ 61 CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == cipherAlgorithm) && \ 62 CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) || \ 63 ((CPA_CY_SYM_CIPHER_NULL == cipherAlgorithm || \ 64 CPA_CY_SYM_CIPHER_AES_CTR == cipherAlgorithm || \ 65 CPA_CY_SYM_CIPHER_ZUC_EEA3 == cipherAlgorithm) && \ 66 CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) || \ 67 ((CPA_CY_SYM_CIPHER_NULL == cipherAlgorithm || \ 68 CPA_CY_SYM_CIPHER_AES_CTR == cipherAlgorithm || \ 69 CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == cipherAlgorithm) && \ 70 CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm)) && \ 71 !extAlgchainSupported) 72 73 /*** Local functions definitions ***/ 74 static CpaStatus 75 LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer, 76 const CpaBufferList *const pDstBuffer, 77 const lac_session_desc_t *const pSessionDesc, 78 const CpaCySymOpData *const pOpData); 79 80 void LacDp_WriteRingMsgFull(CpaCySymDpOpData *pRequest, 81 icp_qat_fw_la_bulk_req_t *pCurrentQatMsg); 82 void LacDp_WriteRingMsgOpt(CpaCySymDpOpData *pRequest, 83 icp_qat_fw_la_bulk_req_t *pCurrentQatMsg); 84 void getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData, 85 Cpa32U *pSessionCtxSizeInBytes); 86 87 /** 88 ***************************************************************************** 89 * @ingroup LacSym 90 * Generic bufferList callback function. 91 * @description 92 * This function is used when the API is called in synchronous mode. 93 * It's assumed the callbackTag holds a lac_sync_op_data_t type 94 * and when the callback is received, this callback shall set the 95 * status and opResult element of that cookie structure and 96 * kick the sid. 97 * This function may be used directly as a callback function. 98 * 99 * @param[in] callbackTag Callback Tag 100 * @param[in] status Status of callback 101 * @param[in] operationType Operation Type 102 * @param[in] pOpData Pointer to the Op Data 103 * @param[out] pDstBuffer Pointer to destination buffer list 104 * @param[out] opResult Boolean to indicate the result of the operation 105 * 106 * @return void 107 * 108 *****************************************************************************/ 109 void 110 LacSync_GenBufListVerifyCb(void *pCallbackTag, 111 CpaStatus status, 112 CpaCySymOp operationType, 113 void *pOpData, 114 CpaBufferList *pDstBuffer, 115 CpaBoolean opResult) 116 { 117 LacSync_GenVerifyWakeupSyncCaller(pCallbackTag, status, opResult); 118 } 119 120 /* 121 ******************************************************************************* 122 * Define static function definitions 123 ******************************************************************************* 124 */ 125 /** 126 * @ingroup LacSym 127 * Function which perform parameter checks on session setup data 128 * 129 * @param[in] CpaInstanceHandle Instance Handle 130 * @param[in] pSessionSetupData Pointer to session setup data 131 * 132 * @retval CPA_STATUS_SUCCESS The operation succeeded 133 * @retval CPA_STATUS_INVALID_PARAM An invalid parameter value was found 134 */ 135 static CpaStatus 136 LacSymSession_ParamCheck(const CpaInstanceHandle instanceHandle, 137 const CpaCySymSessionSetupData *pSessionSetupData) 138 { 139 /* initialize convenient pointers to cipher and hash contexts */ 140 const CpaCySymCipherSetupData *const pCipherSetupData = 141 (const CpaCySymCipherSetupData *)&pSessionSetupData 142 ->cipherSetupData; 143 const CpaCySymHashSetupData *const pHashSetupData = 144 &pSessionSetupData->hashSetupData; 145 146 CpaCySymCapabilitiesInfo capInfo; 147 CpaCyCapabilitiesInfo cyCapInfo; 148 cpaCySymQueryCapabilities(instanceHandle, &capInfo); 149 SalCtrl_CyQueryCapabilities(instanceHandle, &cyCapInfo); 150 151 /* Ensure cipher algorithm is correct and supported */ 152 if ((CPA_CY_SYM_OP_ALGORITHM_CHAINING == 153 pSessionSetupData->symOperation) || 154 (CPA_CY_SYM_OP_CIPHER == pSessionSetupData->symOperation)) { 155 /* Protect against value of cipher outside the bitmap 156 * and check if cipher algorithm is correct 157 */ 158 if (pCipherSetupData->cipherAlgorithm >= 159 CPA_CY_SYM_CIPHER_CAP_BITMAP_SIZE) { 160 LAC_INVALID_PARAM_LOG("cipherAlgorithm"); 161 return CPA_STATUS_INVALID_PARAM; 162 } 163 if (!CPA_BITMAP_BIT_TEST(capInfo.ciphers, 164 pCipherSetupData->cipherAlgorithm)) { 165 LAC_UNSUPPORTED_PARAM_LOG( 166 "UnSupported cipherAlgorithm"); 167 return CPA_STATUS_UNSUPPORTED; 168 } 169 } 170 171 /* Ensure hash algorithm is correct and supported */ 172 if ((CPA_CY_SYM_OP_ALGORITHM_CHAINING == 173 pSessionSetupData->symOperation) || 174 (CPA_CY_SYM_OP_HASH == pSessionSetupData->symOperation)) { 175 /* Protect against value of hash outside the bitmap 176 * and check if hash algorithm is correct 177 */ 178 if (pHashSetupData->hashAlgorithm >= 179 CPA_CY_SYM_HASH_CAP_BITMAP_SIZE) { 180 LAC_INVALID_PARAM_LOG("hashAlgorithm"); 181 return CPA_STATUS_INVALID_PARAM; 182 } 183 if (!CPA_BITMAP_BIT_TEST(capInfo.hashes, 184 pHashSetupData->hashAlgorithm)) { 185 LAC_UNSUPPORTED_PARAM_LOG("UnSupported hashAlgorithm"); 186 return CPA_STATUS_UNSUPPORTED; 187 } 188 } 189 190 /* ensure CCM, GCM, Kasumi, Snow3G and ZUC cipher and hash algorithms 191 * are selected together for Algorithm Chaining */ 192 if (CPA_CY_SYM_OP_ALGORITHM_CHAINING == 193 pSessionSetupData->symOperation) { 194 /* ensure both hash and cipher algorithms are POLY and CHACHA */ 195 if (((CPA_CY_SYM_CIPHER_CHACHA == 196 pCipherSetupData->cipherAlgorithm) && 197 (CPA_CY_SYM_HASH_POLY != pHashSetupData->hashAlgorithm)) || 198 ((CPA_CY_SYM_HASH_POLY == pHashSetupData->hashAlgorithm) && 199 (CPA_CY_SYM_CIPHER_CHACHA != 200 pCipherSetupData->cipherAlgorithm))) { 201 LAC_INVALID_PARAM_LOG( 202 "Invalid combination of Cipher/Hash " 203 "Algorithms for CHACHA/POLY"); 204 return CPA_STATUS_INVALID_PARAM; 205 } 206 207 /* ensure both hash and cipher algorithms are CCM */ 208 if (((CPA_CY_SYM_CIPHER_AES_CCM == 209 pCipherSetupData->cipherAlgorithm) && 210 (CPA_CY_SYM_HASH_AES_CCM != 211 pHashSetupData->hashAlgorithm)) || 212 ((CPA_CY_SYM_HASH_AES_CCM == 213 pHashSetupData->hashAlgorithm) && 214 (CPA_CY_SYM_CIPHER_AES_CCM != 215 pCipherSetupData->cipherAlgorithm))) { 216 LAC_INVALID_PARAM_LOG( 217 "Invalid combination of Cipher/Hash Algorithms for CCM"); 218 return CPA_STATUS_INVALID_PARAM; 219 } 220 221 /* ensure both hash and cipher algorithms are GCM/GMAC */ 222 if ((CPA_CY_SYM_CIPHER_AES_GCM == 223 pCipherSetupData->cipherAlgorithm && 224 (CPA_CY_SYM_HASH_AES_GCM != 225 pHashSetupData->hashAlgorithm && 226 CPA_CY_SYM_HASH_AES_GMAC != 227 pHashSetupData->hashAlgorithm)) || 228 ((CPA_CY_SYM_HASH_AES_GCM == 229 pHashSetupData->hashAlgorithm || 230 CPA_CY_SYM_HASH_AES_GMAC == 231 pHashSetupData->hashAlgorithm) && 232 CPA_CY_SYM_CIPHER_AES_GCM != 233 pCipherSetupData->cipherAlgorithm)) { 234 LAC_INVALID_PARAM_LOG( 235 "Invalid combination of Cipher/Hash Algorithms for GCM"); 236 return CPA_STATUS_INVALID_PARAM; 237 } 238 239 /* ensure both hash and cipher algorithms are Kasumi */ 240 if (((CPA_CY_SYM_CIPHER_KASUMI_F8 == 241 pCipherSetupData->cipherAlgorithm) && 242 (CPA_CY_SYM_HASH_KASUMI_F9 != 243 pHashSetupData->hashAlgorithm)) || 244 ((CPA_CY_SYM_HASH_KASUMI_F9 == 245 pHashSetupData->hashAlgorithm) && 246 (CPA_CY_SYM_CIPHER_KASUMI_F8 != 247 pCipherSetupData->cipherAlgorithm))) { 248 LAC_INVALID_PARAM_LOG( 249 "Invalid combination of Cipher/Hash Algorithms for Kasumi"); 250 return CPA_STATUS_INVALID_PARAM; 251 } 252 253 if (IS_EXT_ALG_CHAIN_UNSUPPORTED( 254 pCipherSetupData->cipherAlgorithm, 255 pHashSetupData->hashAlgorithm, 256 cyCapInfo.extAlgchainSupported)) { 257 LAC_UNSUPPORTED_PARAM_LOG( 258 "ExtAlgChain feature not supported"); 259 return CPA_STATUS_UNSUPPORTED; 260 } 261 262 /* ensure both hash and cipher algorithms are Snow3G */ 263 if (((CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == 264 pCipherSetupData->cipherAlgorithm) && 265 (CPA_CY_SYM_HASH_SNOW3G_UIA2 != 266 pHashSetupData->hashAlgorithm)) || 267 ((CPA_CY_SYM_HASH_SNOW3G_UIA2 == 268 pHashSetupData->hashAlgorithm) && 269 (CPA_CY_SYM_CIPHER_SNOW3G_UEA2 != 270 pCipherSetupData->cipherAlgorithm))) { 271 LAC_INVALID_PARAM_LOG( 272 "Invalid combination of Cipher/Hash Algorithms for Snow3G"); 273 return CPA_STATUS_INVALID_PARAM; 274 } 275 276 /* ensure both hash and cipher algorithms are ZUC */ 277 if (((CPA_CY_SYM_CIPHER_ZUC_EEA3 == 278 pCipherSetupData->cipherAlgorithm) && 279 (CPA_CY_SYM_HASH_ZUC_EIA3 != 280 pHashSetupData->hashAlgorithm)) || 281 ((CPA_CY_SYM_HASH_ZUC_EIA3 == 282 pHashSetupData->hashAlgorithm) && 283 (CPA_CY_SYM_CIPHER_ZUC_EEA3 != 284 pCipherSetupData->cipherAlgorithm))) { 285 LAC_INVALID_PARAM_LOG( 286 "Invalid combination of Cipher/Hash Algorithms for ZUC"); 287 return CPA_STATUS_INVALID_PARAM; 288 } 289 } 290 /* not Algorithm Chaining so prevent CCM/GCM being selected */ 291 else if (CPA_CY_SYM_OP_CIPHER == pSessionSetupData->symOperation) { 292 /* ensure cipher algorithm is not CCM or GCM */ 293 if ((CPA_CY_SYM_CIPHER_AES_CCM == 294 pCipherSetupData->cipherAlgorithm) || 295 (CPA_CY_SYM_CIPHER_AES_GCM == 296 pCipherSetupData->cipherAlgorithm) || 297 (CPA_CY_SYM_CIPHER_CHACHA == 298 pCipherSetupData->cipherAlgorithm)) { 299 LAC_INVALID_PARAM_LOG( 300 "Invalid Cipher Algorithm for non-Algorithm " 301 "Chaining operation"); 302 return CPA_STATUS_INVALID_PARAM; 303 } 304 } else if (CPA_CY_SYM_OP_HASH == pSessionSetupData->symOperation) { 305 /* ensure hash algorithm is not CCM or GCM/GMAC */ 306 if ((CPA_CY_SYM_HASH_AES_CCM == 307 pHashSetupData->hashAlgorithm) || 308 (CPA_CY_SYM_HASH_AES_GCM == 309 pHashSetupData->hashAlgorithm) || 310 (CPA_CY_SYM_HASH_AES_GMAC == 311 pHashSetupData->hashAlgorithm) || 312 (CPA_CY_SYM_HASH_POLY == pHashSetupData->hashAlgorithm)) { 313 LAC_INVALID_PARAM_LOG( 314 "Invalid Hash Algorithm for non-Algorithm Chaining operation"); 315 return CPA_STATUS_INVALID_PARAM; 316 } 317 } 318 /* Unsupported operation. Return error */ 319 else { 320 LAC_INVALID_PARAM_LOG("symOperation"); 321 return CPA_STATUS_INVALID_PARAM; 322 } 323 324 /* ensure that cipher direction param is 325 * valid for cipher and algchain ops */ 326 if (CPA_CY_SYM_OP_HASH != pSessionSetupData->symOperation) { 327 if ((pCipherSetupData->cipherDirection != 328 CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) && 329 (pCipherSetupData->cipherDirection != 330 CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT)) { 331 LAC_INVALID_PARAM_LOG("Invalid Cipher Direction"); 332 return CPA_STATUS_INVALID_PARAM; 333 } 334 } 335 336 return CPA_STATUS_SUCCESS; 337 } 338 339 340 /** 341 * @ingroup LacSym 342 * Function which perform parameter checks on data buffers for symmetric 343 * crypto operations 344 * 345 * @param[in] pSrcBuffer Pointer to source buffer list 346 * @param[in] pDstBuffer Pointer to destination buffer list 347 * @param[in] pSessionDesc Pointer to session descriptor 348 * @param[in] pOpData Pointer to CryptoSymOpData. 349 * 350 * @retval CPA_STATUS_SUCCESS The operation succeeded 351 * @retval CPA_STATUS_INVALID_PARAM An invalid parameter value was found 352 */ 353 354 static CpaStatus 355 LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer, 356 const CpaBufferList *const pDstBuffer, 357 const lac_session_desc_t *const pSessionDesc, 358 const CpaCySymOpData *const pOpData) 359 { 360 Cpa64U srcBufferLen = 0, dstBufferLen = 0; 361 CpaStatus status = CPA_STATUS_SUCCESS; 362 363 /* verify packet type is in correct range */ 364 switch (pOpData->packetType) { 365 case CPA_CY_SYM_PACKET_TYPE_FULL: 366 case CPA_CY_SYM_PACKET_TYPE_PARTIAL: 367 case CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL: 368 break; 369 default: { 370 LAC_INVALID_PARAM_LOG("packetType"); 371 return CPA_STATUS_INVALID_PARAM; 372 } 373 } 374 375 if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation && 376 CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) && 377 (0 == pOpData->messageLenToHashInBytes))) { 378 if (IS_ZERO_LENGTH_BUFFER_SUPPORTED( 379 pSessionDesc->cipherAlgorithm, 380 pSessionDesc->hashAlgorithm)) { 381 status = LacBuffDesc_BufferListVerifyNull( 382 pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT); 383 } else { 384 status = LacBuffDesc_BufferListVerify( 385 pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT); 386 } 387 if (CPA_STATUS_SUCCESS != status) { 388 LAC_INVALID_PARAM_LOG("Source buffer invalid"); 389 return CPA_STATUS_INVALID_PARAM; 390 } 391 } else { 392 /* check MetaData !NULL */ 393 if (NULL == pSrcBuffer->pPrivateMetaData) { 394 LAC_INVALID_PARAM_LOG( 395 "Source buffer MetaData cannot be NULL"); 396 return CPA_STATUS_INVALID_PARAM; 397 } 398 } 399 400 /* out of place checks */ 401 if (pSrcBuffer != pDstBuffer) { 402 /* exception for this check is zero length hash requests to 403 * allow */ 404 /* for srcBufflen=DstBufferLen=0 */ 405 if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation && 406 CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) && 407 (0 == pOpData->messageLenToHashInBytes))) { 408 /* Verify buffer(s) for dest packet & return packet 409 * length */ 410 if (IS_ZERO_LENGTH_BUFFER_SUPPORTED( 411 pSessionDesc->cipherAlgorithm, 412 pSessionDesc->hashAlgorithm)) { 413 status = LacBuffDesc_BufferListVerifyNull( 414 pDstBuffer, 415 &dstBufferLen, 416 LAC_NO_ALIGNMENT_SHIFT); 417 } else { 418 status = LacBuffDesc_BufferListVerify( 419 pDstBuffer, 420 &dstBufferLen, 421 LAC_NO_ALIGNMENT_SHIFT); 422 } 423 if (CPA_STATUS_SUCCESS != status) { 424 LAC_INVALID_PARAM_LOG( 425 "Destination buffer invalid"); 426 return CPA_STATUS_INVALID_PARAM; 427 } 428 } else { 429 /* check MetaData !NULL */ 430 if (NULL == pDstBuffer->pPrivateMetaData) { 431 LAC_INVALID_PARAM_LOG( 432 "Dest buffer MetaData cannot be NULL"); 433 return CPA_STATUS_INVALID_PARAM; 434 } 435 } 436 /* Check that src Buffer and dst Buffer Lengths are equal */ 437 /* CCM output needs to be longer than input buffer for appending 438 * tag*/ 439 if (srcBufferLen != dstBufferLen && 440 pSessionDesc->cipherAlgorithm != 441 CPA_CY_SYM_CIPHER_AES_CCM) { 442 LAC_INVALID_PARAM_LOG( 443 "Source and Dest buffer lengths need to be equal "); 444 return CPA_STATUS_INVALID_PARAM; 445 } 446 } 447 448 /* check for partial packet suport for the session operation */ 449 if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) { 450 if (CPA_FALSE == pSessionDesc->isPartialSupported) { 451 /* return out here to simplify cleanup */ 452 LAC_INVALID_PARAM_LOG( 453 "Partial packets not supported for operation"); 454 return CPA_STATUS_INVALID_PARAM; 455 } else { 456 /* This function checks to see if the partial packet 457 * sequence is correct */ 458 if (CPA_STATUS_SUCCESS != 459 LacSym_PartialPacketStateCheck( 460 pOpData->packetType, 461 pSessionDesc->partialState)) { 462 LAC_INVALID_PARAM_LOG("Partial packet Type"); 463 return CPA_STATUS_INVALID_PARAM; 464 } 465 } 466 } 467 return CPA_STATUS_SUCCESS; 468 } 469 470 /** @ingroup LacSym */ 471 CpaStatus 472 cpaCySymInitSession(const CpaInstanceHandle instanceHandle_in, 473 const CpaCySymCbFunc pSymCb, 474 const CpaCySymSessionSetupData *pSessionSetupData, 475 CpaCySymSessionCtx pSessionCtx) 476 { 477 CpaStatus status = CPA_STATUS_SUCCESS; 478 CpaInstanceHandle instanceHandle = NULL; 479 sal_service_t *pService = NULL; 480 481 if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) { 482 instanceHandle = 483 Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM); 484 } else { 485 instanceHandle = instanceHandle_in; 486 } 487 488 LAC_CHECK_INSTANCE_HANDLE(instanceHandle); 489 SAL_CHECK_INSTANCE_TYPE(instanceHandle, 490 (SAL_SERVICE_TYPE_CRYPTO | 491 SAL_SERVICE_TYPE_CRYPTO_SYM)); 492 493 pService = (sal_service_t *)instanceHandle; 494 495 /* check crypto service is running otherwise return an error */ 496 SAL_RUNNING_CHECK(pService); 497 498 status = LacSym_InitSession(instanceHandle, 499 pSymCb, 500 pSessionSetupData, 501 CPA_FALSE, /* isDPSession */ 502 pSessionCtx); 503 504 if (CPA_STATUS_SUCCESS == status) { 505 /* Increment the stats for a session registered successfully */ 506 LAC_SYM_STAT_INC(numSessionsInitialized, instanceHandle); 507 } else /* if there was an error */ 508 { 509 LAC_SYM_STAT_INC(numSessionErrors, instanceHandle); 510 } 511 512 return status; 513 } 514 515 CpaStatus 516 cpaCySymSessionInUse(CpaCySymSessionCtx pSessionCtx, CpaBoolean *pSessionInUse) 517 { 518 CpaStatus status = CPA_STATUS_SUCCESS; 519 lac_session_desc_t *pSessionDesc = NULL; 520 521 LAC_CHECK_NULL_PARAM(pSessionInUse); 522 LAC_CHECK_INSTANCE_HANDLE(pSessionCtx); 523 524 *pSessionInUse = CPA_FALSE; 525 526 pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx); 527 528 /* If there are pending requests */ 529 if (pSessionDesc->isDPSession) { 530 if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount))) 531 *pSessionInUse = CPA_TRUE; 532 } else { 533 if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount))) 534 *pSessionInUse = CPA_TRUE; 535 } 536 537 return status; 538 } 539 540 CpaStatus 541 LacSym_InitSession(const CpaInstanceHandle instanceHandle, 542 const CpaCySymCbFunc pSymCb, 543 const CpaCySymSessionSetupData *pSessionSetupData, 544 const CpaBoolean isDPSession, 545 CpaCySymSessionCtx pSessionCtx) 546 { 547 CpaStatus status = CPA_STATUS_SUCCESS; 548 lac_session_desc_t *pSessionDesc = NULL; 549 Cpa32U sessionCtxSizeInBytes = 0; 550 CpaPhysicalAddr physAddress = 0; 551 CpaPhysicalAddr physAddressAligned = 0; 552 sal_service_t *pService = NULL; 553 const CpaCySymCipherSetupData *pCipherSetupData = NULL; 554 const CpaCySymHashSetupData *pHashSetupData = NULL; 555 556 /* Instance param checking done by calling function */ 557 558 LAC_CHECK_NULL_PARAM(pSessionSetupData); 559 LAC_CHECK_NULL_PARAM(pSessionCtx); 560 status = LacSymSession_ParamCheck(instanceHandle, pSessionSetupData); 561 LAC_CHECK_STATUS(status); 562 563 /* set the session priority for QAT AL*/ 564 if ((CPA_CY_PRIORITY_HIGH == pSessionSetupData->sessionPriority) || 565 (CPA_CY_PRIORITY_NORMAL == pSessionSetupData->sessionPriority)) { 566 // do nothing - clean up this code. use RANGE macro 567 } else { 568 LAC_INVALID_PARAM_LOG("sessionPriority"); 569 return CPA_STATUS_INVALID_PARAM; 570 } 571 572 573 pCipherSetupData = &pSessionSetupData->cipherSetupData; 574 pHashSetupData = &pSessionSetupData->hashSetupData; 575 576 pService = (sal_service_t *)instanceHandle; 577 578 /* Re-align the session structure to 64 byte alignment */ 579 physAddress = 580 LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService), 581 (Cpa8U *)pSessionCtx + sizeof(void *)); 582 583 if (0 == physAddress) { 584 LAC_LOG_ERROR( 585 "Unable to get the physical address of the session\n"); 586 return CPA_STATUS_FAIL; 587 } 588 589 physAddressAligned = 590 LAC_ALIGN_POW2_ROUNDUP(physAddress, LAC_64BYTE_ALIGNMENT); 591 592 pSessionDesc = (lac_session_desc_t *) 593 /* Move the session pointer by the physical offset 594 between aligned and unaligned memory */ 595 ((Cpa8U *)pSessionCtx + sizeof(void *) + 596 (physAddressAligned - physAddress)); 597 598 /* save the aligned pointer in the first bytes (size of unsigned long) 599 * of the session memory */ 600 *((LAC_ARCH_UINT *)pSessionCtx) = (LAC_ARCH_UINT)pSessionDesc; 601 602 /* start off with a clean session */ 603 /* Choose Session Context size */ 604 getCtxSize(pSessionSetupData, &sessionCtxSizeInBytes); 605 switch (sessionCtxSizeInBytes) { 606 case LAC_SYM_SESSION_D1_SIZE: 607 memset(pSessionDesc, 0, sizeof(lac_session_desc_d1_t)); 608 break; 609 case LAC_SYM_SESSION_D2_SIZE: 610 memset(pSessionDesc, 0, sizeof(lac_session_desc_d2_t)); 611 break; 612 default: 613 memset(pSessionDesc, 0, sizeof(lac_session_desc_t)); 614 break; 615 } 616 617 /* Setup content descriptor info structure 618 * assumption that content descriptor is the first field in 619 * in the session descriptor */ 620 pSessionDesc->contentDescInfo.pData = (Cpa8U *)pSessionDesc; 621 pSessionDesc->contentDescInfo.hardwareSetupBlockPhys = 622 physAddressAligned; 623 624 pSessionDesc->contentDescOptimisedInfo.pData = 625 ((Cpa8U *)pSessionDesc + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE); 626 pSessionDesc->contentDescOptimisedInfo.hardwareSetupBlockPhys = 627 (physAddressAligned + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE); 628 629 /* Set the Common Session Information */ 630 pSessionDesc->symOperation = pSessionSetupData->symOperation; 631 632 if (CPA_FALSE == isDPSession) { 633 /* For asynchronous - use the user supplied callback 634 * for synchronous - use the internal synchronous callback */ 635 pSessionDesc->pSymCb = ((void *)NULL != (void *)pSymCb) ? 636 pSymCb : 637 LacSync_GenBufListVerifyCb; 638 } 639 640 pSessionDesc->isDPSession = isDPSession; 641 if ((CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm) || 642 (CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) || 643 (CPA_CY_SYM_HASH_AES_CCM == pHashSetupData->hashAlgorithm) || 644 (CPA_CY_SYM_CIPHER_CHACHA == pCipherSetupData->cipherAlgorithm) || 645 (CPA_CY_SYM_CIPHER_ARC4 == pCipherSetupData->cipherAlgorithm)) { 646 pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgFull; 647 } else { 648 pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgOpt; 649 } 650 651 if (CPA_STATUS_SUCCESS == status) { 652 /* Session set up via API call (not internal one) */ 653 /* Services such as DRBG call the crypto api as part of their 654 * service hence the need to for the flag, it is needed to 655 * distinguish between an internal and external session. 656 */ 657 pSessionDesc->internalSession = CPA_FALSE; 658 659 status = LacAlgChain_SessionInit(instanceHandle, 660 pSessionSetupData, 661 pSessionDesc); 662 } 663 return status; 664 } 665 666 /** @ingroup LacSym */ 667 CpaStatus 668 cpaCySymRemoveSession(const CpaInstanceHandle instanceHandle_in, 669 CpaCySymSessionCtx pSessionCtx) 670 { 671 lac_session_desc_t *pSessionDesc = NULL; 672 CpaStatus status = CPA_STATUS_SUCCESS; 673 CpaInstanceHandle instanceHandle = NULL; 674 Cpa64U numPendingRequests = 0; 675 676 677 if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) { 678 instanceHandle = 679 Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM); 680 } else { 681 instanceHandle = instanceHandle_in; 682 } 683 684 LAC_CHECK_INSTANCE_HANDLE(instanceHandle); 685 SAL_CHECK_INSTANCE_TYPE(instanceHandle, 686 (SAL_SERVICE_TYPE_CRYPTO | 687 SAL_SERVICE_TYPE_CRYPTO_SYM)); 688 LAC_CHECK_NULL_PARAM(pSessionCtx); 689 690 /* check crypto service is running otherwise return an error */ 691 SAL_RUNNING_CHECK(instanceHandle); 692 pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx); 693 694 LAC_CHECK_NULL_PARAM(pSessionDesc); 695 696 if (CPA_TRUE == pSessionDesc->isDPSession) { 697 /* 698 * Based on one instance, we can initialize multiple sessions. 699 * For example, we can initialize the session "X" and session 700 * "Y" with the same instance "A". If there is no operation 701 * pending for session "X", we can remove the session "X". 702 * 703 * Now we only check the @pSessionDesc->pendingDpCbCount, if it 704 * becomes zero, we can remove the session. 705 * 706 * Why? 707 * (1) We increase it in the cpaCySymDpEnqueueOp/ 708 * cpaCySymDpEnqueueOpBatch. 709 * (2) We decrease it in the LacSymCb_ProcessCallback. 710 * 711 * If the @pSessionDesc->pendingDpCbCount becomes zero, it means 712 * there is no operation pending for the session "X" anymore, so 713 * we can remove this session. Maybe there is still some 714 * requests left in the instance's ring 715 * (icp_adf_queueDataToSend() returns true), but the request 716 * does not belong to "X", it belongs to session "Y". 717 */ 718 numPendingRequests = 719 qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount)); 720 } else { 721 numPendingRequests = 722 qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount)); 723 } 724 725 /* If there are pending requests */ 726 if (0 != numPendingRequests) { 727 QAT_UTILS_LOG("There are %llu requests pending\n", 728 (unsigned long long)numPendingRequests); 729 status = CPA_STATUS_RETRY; 730 if (CPA_TRUE == pSessionDesc->isDPSession) { 731 /* Need to update tail if messages queue on tx hi ring 732 for data plane api */ 733 icp_comms_trans_handle trans_handle = 734 ((sal_crypto_service_t *)instanceHandle) 735 ->trans_handle_sym_tx; 736 737 if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) { 738 /* process the remaining messages in the ring */ 739 QAT_UTILS_LOG("Submitting enqueued requests\n"); 740 /* 741 * SalQatMsg_updateQueueTail 742 */ 743 SalQatMsg_updateQueueTail(trans_handle); 744 return status; 745 } 746 } 747 } 748 if (CPA_STATUS_SUCCESS == status) { 749 LAC_SPINLOCK_DESTROY(&pSessionDesc->requestQueueLock); 750 if (CPA_FALSE == pSessionDesc->isDPSession) { 751 LAC_SYM_STAT_INC(numSessionsRemoved, instanceHandle); 752 } 753 } else if (CPA_FALSE == pSessionDesc->isDPSession) { 754 LAC_SYM_STAT_INC(numSessionErrors, instanceHandle); 755 } 756 return status; 757 } 758 759 /** @ingroup LacSym */ 760 static CpaStatus 761 LacSym_Perform(const CpaInstanceHandle instanceHandle, 762 void *callbackTag, 763 const CpaCySymOpData *pOpData, 764 const CpaBufferList *pSrcBuffer, 765 CpaBufferList *pDstBuffer, 766 CpaBoolean *pVerifyResult, 767 CpaBoolean isAsyncMode) 768 { 769 lac_session_desc_t *pSessionDesc = NULL; 770 CpaStatus status = CPA_STATUS_SUCCESS; 771 772 LAC_CHECK_INSTANCE_HANDLE(instanceHandle); 773 SAL_CHECK_INSTANCE_TYPE(instanceHandle, 774 (SAL_SERVICE_TYPE_CRYPTO | 775 SAL_SERVICE_TYPE_CRYPTO_SYM)); 776 /* check crypto service is running otherwise return an error */ 777 SAL_RUNNING_CHECK(instanceHandle); 778 LAC_CHECK_NULL_PARAM(pOpData); 779 LAC_CHECK_NULL_PARAM(pOpData->sessionCtx); 780 LAC_CHECK_NULL_PARAM(pSrcBuffer); 781 LAC_CHECK_NULL_PARAM(pDstBuffer); 782 783 pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pOpData->sessionCtx); 784 LAC_CHECK_NULL_PARAM(pSessionDesc); 785 786 /*check whether Payload size is zero for CHACHA-POLY*/ 787 if ((CPA_CY_SYM_CIPHER_CHACHA == pSessionDesc->cipherAlgorithm) && 788 (CPA_CY_SYM_HASH_POLY == pSessionDesc->hashAlgorithm) && 789 (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) { 790 if (!pOpData->messageLenToCipherInBytes) { 791 LAC_INVALID_PARAM_LOG( 792 "Invalid messageLenToCipherInBytes for CHACHA-POLY"); 793 return CPA_STATUS_INVALID_PARAM; 794 } 795 } 796 797 798 /* If synchronous Operation - Callback function stored in the session 799 * descriptor so a flag is set in the perform to indicate that 800 * the perform is being re-called for the synchronous operation */ 801 if ((LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb) && 802 isAsyncMode == CPA_TRUE) { 803 CpaBoolean opResult = CPA_FALSE; 804 lac_sync_op_data_t *pSyncCallbackData = NULL; 805 806 status = LacSync_CreateSyncCookie(&pSyncCallbackData); 807 808 if (CPA_STATUS_SUCCESS == status) { 809 status = LacSym_Perform(instanceHandle, 810 pSyncCallbackData, 811 pOpData, 812 pSrcBuffer, 813 pDstBuffer, 814 pVerifyResult, 815 CPA_FALSE); 816 } else { 817 /* Failure allocating sync cookie */ 818 LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle); 819 return status; 820 } 821 822 if (CPA_STATUS_SUCCESS == status) { 823 CpaStatus syncStatus = CPA_STATUS_SUCCESS; 824 syncStatus = LacSync_WaitForCallback( 825 pSyncCallbackData, 826 LAC_SYM_SYNC_CALLBACK_TIMEOUT, 827 &status, 828 &opResult); 829 /* If callback doesn't come back */ 830 if (CPA_STATUS_SUCCESS != syncStatus) { 831 LAC_SYM_STAT_INC(numSymOpCompletedErrors, 832 instanceHandle); 833 LAC_LOG_ERROR("Callback timed out"); 834 status = syncStatus; 835 } 836 } else { 837 /* As the Request was not sent the Callback will never 838 * be called, so need to indicate that we're finished 839 * with cookie so it can be destroyed. */ 840 LacSync_SetSyncCookieComplete(pSyncCallbackData); 841 } 842 843 if (CPA_STATUS_SUCCESS == status) { 844 if (NULL != pVerifyResult) { 845 *pVerifyResult = opResult; 846 } 847 } 848 849 LacSync_DestroySyncCookie(&pSyncCallbackData); 850 return status; 851 } 852 853 status = 854 LacSymPerform_BufferParamCheck((const CpaBufferList *)pSrcBuffer, 855 pDstBuffer, 856 pSessionDesc, 857 pOpData); 858 LAC_CHECK_STATUS(status); 859 860 if ((!pSessionDesc->digestIsAppended) && 861 (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) { 862 /* Check that pDigestResult is not NULL */ 863 LAC_CHECK_NULL_PARAM(pOpData->pDigestResult); 864 } 865 866 status = LacAlgChain_Perform(instanceHandle, 867 pSessionDesc, 868 callbackTag, 869 pOpData, 870 pSrcBuffer, 871 pDstBuffer, 872 pVerifyResult); 873 874 if (CPA_STATUS_SUCCESS == status) { 875 /* check for partial packet suport for the session operation */ 876 if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) { 877 LacSym_PartialPacketStateUpdate( 878 pOpData->packetType, &pSessionDesc->partialState); 879 } 880 /* increment #requests stat */ 881 LAC_SYM_STAT_INC(numSymOpRequests, instanceHandle); 882 } 883 /* Retry also results in the errors stat been incremented */ 884 else { 885 /* increment #errors stat */ 886 LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle); 887 } 888 return status; 889 } 890 891 /** @ingroup LacSym */ 892 CpaStatus 893 cpaCySymPerformOp(const CpaInstanceHandle instanceHandle_in, 894 void *callbackTag, 895 const CpaCySymOpData *pOpData, 896 const CpaBufferList *pSrcBuffer, 897 CpaBufferList *pDstBuffer, 898 CpaBoolean *pVerifyResult) 899 { 900 CpaInstanceHandle instanceHandle = NULL; 901 902 if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) { 903 instanceHandle = 904 Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM); 905 } else { 906 instanceHandle = instanceHandle_in; 907 } 908 909 return LacSym_Perform(instanceHandle, 910 callbackTag, 911 pOpData, 912 pSrcBuffer, 913 pDstBuffer, 914 pVerifyResult, 915 CPA_TRUE); 916 } 917 918 /** @ingroup LacSym */ 919 CpaStatus 920 cpaCySymQueryStats(const CpaInstanceHandle instanceHandle_in, 921 struct _CpaCySymStats *pSymStats) 922 { 923 924 CpaInstanceHandle instanceHandle = NULL; 925 926 927 if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) { 928 instanceHandle = 929 Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM); 930 } else { 931 instanceHandle = instanceHandle_in; 932 } 933 934 LAC_CHECK_INSTANCE_HANDLE(instanceHandle); 935 SAL_CHECK_INSTANCE_TYPE(instanceHandle, 936 (SAL_SERVICE_TYPE_CRYPTO | 937 SAL_SERVICE_TYPE_CRYPTO_SYM)); 938 LAC_CHECK_NULL_PARAM(pSymStats); 939 940 /* check if crypto service is running 941 * otherwise return an error */ 942 SAL_RUNNING_CHECK(instanceHandle); 943 944 /* copy the fields from the internal structure into the api defined 945 * structure */ 946 LacSym_Stats32CopyGet(instanceHandle, pSymStats); 947 return CPA_STATUS_SUCCESS; 948 } 949 950 /** @ingroup LacSym */ 951 CpaStatus 952 cpaCySymQueryStats64(const CpaInstanceHandle instanceHandle_in, 953 CpaCySymStats64 *pSymStats) 954 { 955 956 CpaInstanceHandle instanceHandle = NULL; 957 958 959 if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) { 960 instanceHandle = 961 Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM); 962 } else { 963 instanceHandle = instanceHandle_in; 964 } 965 966 LAC_CHECK_INSTANCE_HANDLE(instanceHandle); 967 SAL_CHECK_INSTANCE_TYPE(instanceHandle, 968 (SAL_SERVICE_TYPE_CRYPTO | 969 SAL_SERVICE_TYPE_CRYPTO_SYM)); 970 LAC_CHECK_NULL_PARAM(pSymStats); 971 972 /* check if crypto service is running 973 * otherwise return an error */ 974 SAL_RUNNING_CHECK(instanceHandle); 975 976 /* copy the fields from the internal structure into the api defined 977 * structure */ 978 LacSym_Stats64CopyGet(instanceHandle, pSymStats); 979 980 return CPA_STATUS_SUCCESS; 981 } 982 983 /** @ingroup LacSym */ 984 CpaStatus 985 cpaCySymSessionCtxGetSize(const CpaInstanceHandle instanceHandle_in, 986 const CpaCySymSessionSetupData *pSessionSetupData, 987 Cpa32U *pSessionCtxSizeInBytes) 988 { 989 CpaInstanceHandle instanceHandle = NULL; 990 991 if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) { 992 instanceHandle = 993 Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM); 994 } else { 995 instanceHandle = instanceHandle_in; 996 } 997 998 LAC_CHECK_INSTANCE_HANDLE(instanceHandle); 999 SAL_CHECK_INSTANCE_TYPE(instanceHandle, 1000 (SAL_SERVICE_TYPE_CRYPTO | 1001 SAL_SERVICE_TYPE_CRYPTO_SYM)); 1002 LAC_CHECK_NULL_PARAM(pSessionSetupData); 1003 LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes); 1004 1005 /* check crypto service is running otherwise return an error */ 1006 SAL_RUNNING_CHECK(instanceHandle); 1007 *pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE; 1008 1009 return CPA_STATUS_SUCCESS; 1010 } 1011 1012 /** @ingroup LacSym */ 1013 CpaStatus 1014 cpaCySymSessionCtxGetDynamicSize( 1015 const CpaInstanceHandle instanceHandle_in, 1016 const CpaCySymSessionSetupData *pSessionSetupData, 1017 Cpa32U *pSessionCtxSizeInBytes) 1018 { 1019 CpaInstanceHandle instanceHandle = NULL; 1020 1021 if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) { 1022 instanceHandle = 1023 Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM); 1024 } else { 1025 instanceHandle = instanceHandle_in; 1026 } 1027 1028 LAC_CHECK_INSTANCE_HANDLE(instanceHandle); 1029 SAL_CHECK_INSTANCE_TYPE(instanceHandle, 1030 (SAL_SERVICE_TYPE_CRYPTO | 1031 SAL_SERVICE_TYPE_CRYPTO_SYM)); 1032 LAC_CHECK_NULL_PARAM(pSessionSetupData); 1033 LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes); 1034 1035 /* check crypto service is running otherwise return an error */ 1036 SAL_RUNNING_CHECK(instanceHandle); 1037 /* Choose Session Context size */ 1038 getCtxSize(pSessionSetupData, pSessionCtxSizeInBytes); 1039 1040 1041 return CPA_STATUS_SUCCESS; 1042 } 1043 1044 void 1045 getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData, 1046 Cpa32U *pSessionCtxSizeInBytes) 1047 { 1048 /* using lac_session_desc_d1_t */ 1049 if ((pSessionSetupData->cipherSetupData.cipherAlgorithm != 1050 CPA_CY_SYM_CIPHER_ARC4) && 1051 (pSessionSetupData->cipherSetupData.cipherAlgorithm != 1052 CPA_CY_SYM_CIPHER_SNOW3G_UEA2) && 1053 (pSessionSetupData->hashSetupData.hashAlgorithm != 1054 CPA_CY_SYM_HASH_SNOW3G_UIA2) && 1055 (pSessionSetupData->cipherSetupData.cipherAlgorithm != 1056 CPA_CY_SYM_CIPHER_AES_CCM) && 1057 (pSessionSetupData->cipherSetupData.cipherAlgorithm != 1058 CPA_CY_SYM_CIPHER_AES_GCM) && 1059 (pSessionSetupData->hashSetupData.hashMode != 1060 CPA_CY_SYM_HASH_MODE_AUTH) && 1061 (pSessionSetupData->hashSetupData.hashMode != 1062 CPA_CY_SYM_HASH_MODE_NESTED) && 1063 (pSessionSetupData->partialsNotRequired == CPA_TRUE)) { 1064 *pSessionCtxSizeInBytes = LAC_SYM_SESSION_D1_SIZE; 1065 } 1066 /* using lac_session_desc_d2_t */ 1067 else if (((pSessionSetupData->cipherSetupData.cipherAlgorithm == 1068 CPA_CY_SYM_CIPHER_AES_CCM) || 1069 (pSessionSetupData->cipherSetupData.cipherAlgorithm == 1070 CPA_CY_SYM_CIPHER_AES_GCM)) && 1071 (pSessionSetupData->partialsNotRequired == CPA_TRUE)) { 1072 *pSessionCtxSizeInBytes = LAC_SYM_SESSION_D2_SIZE; 1073 } 1074 /* using lac_session_desc_t */ 1075 else { 1076 *pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE; 1077 } 1078 } 1079 1080 /** 1081 ****************************************************************************** 1082 * @ingroup LacSym 1083 *****************************************************************************/ 1084 CpaStatus 1085 cpaCyBufferListGetMetaSize(const CpaInstanceHandle instanceHandle_in, 1086 Cpa32U numBuffers, 1087 Cpa32U *pSizeInBytes) 1088 { 1089 1090 CpaInstanceHandle instanceHandle = NULL; 1091 1092 if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) { 1093 instanceHandle = 1094 Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM); 1095 } else { 1096 instanceHandle = instanceHandle_in; 1097 } 1098 LAC_CHECK_INSTANCE_HANDLE(instanceHandle); 1099 SAL_CHECK_INSTANCE_TYPE(instanceHandle, 1100 (SAL_SERVICE_TYPE_CRYPTO | 1101 SAL_SERVICE_TYPE_CRYPTO_SYM)); 1102 LAC_CHECK_NULL_PARAM(pSizeInBytes); 1103 1104 /* In the case of zero buffers we still need to allocate one 1105 * descriptor to pass to the firmware */ 1106 if (0 == numBuffers) { 1107 numBuffers = 1; 1108 } 1109 1110 /* Note: icp_buffer_list_desc_t is 8 bytes in size and 1111 * icp_flat_buffer_desc_t is 16 bytes in size. Therefore if 1112 * icp_buffer_list_desc_t is aligned 1113 * so will each icp_flat_buffer_desc_t structure */ 1114 1115 *pSizeInBytes = sizeof(icp_buffer_list_desc_t) + 1116 (sizeof(icp_flat_buffer_desc_t) * numBuffers) + 1117 ICP_DESCRIPTOR_ALIGNMENT_BYTES; 1118 1119 1120 return CPA_STATUS_SUCCESS; 1121 } 1122