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