#include "cpa.h"
#include "cpa_cy_sym.h"
#include "cpa_cy_sym_dp.h"
#include "icp_accel_devices.h"
#include "icp_adf_init.h"
#include "icp_adf_transport.h"
#include "icp_adf_transport_dp.h"
#include "icp_adf_debug.h"
#include "icp_sal_poll.h"
#include "qat_utils.h"
#include "lac_list.h"
#include "lac_log.h"
#include "lac_mem.h"
#include "lac_sal_types_crypto.h"
#include "lac_sym.h"
#include "lac_sym_cipher.h"
#include "lac_sym_auth_enc.h"
#include "lac_sym_qat_cipher.h"
#include "sal_service_state.h"
#include "sal_hw_gen.h"
typedef void (*write_ringMsgFunc_t)(CpaCySymDpOpData *pRequest,
icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
static CpaStatus
LacDp_EnqueueParamCheck(const CpaCySymDpOpData *pRequest)
{
lac_session_desc_t *pSessionDesc = NULL;
CpaCySymCipherAlgorithm cipher = 0;
CpaCySymHashAlgorithm hash = 0;
Cpa32U capabilitiesMask = 0;
LAC_CHECK_NULL_PARAM(pRequest);
LAC_CHECK_NULL_PARAM(pRequest->instanceHandle);
LAC_CHECK_NULL_PARAM(pRequest->sessionCtx);
SAL_CHECK_INSTANCE_TYPE(pRequest->instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
if (NULL == pSessionDesc) {
do {
qatUtilsSleep(500);
pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(
pRequest->sessionCtx);
} while (NULL == pSessionDesc);
}
if (NULL == pSessionDesc) {
LAC_INVALID_PARAM_LOG("Session context not as expected");
return CPA_STATUS_INVALID_PARAM;
}
if (CPA_FALSE == pSessionDesc->isDPSession) {
LAC_INVALID_PARAM_LOG(
"Session not initialised for data plane API");
return CPA_STATUS_INVALID_PARAM;
}
if ((CPA_CY_SYM_CIPHER_CHACHA == pSessionDesc->cipherAlgorithm) &&
(CPA_CY_SYM_HASH_POLY == pSessionDesc->hashAlgorithm) &&
(CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
if (!pRequest->messageLenToCipherInBytes) {
LAC_INVALID_PARAM_LOG(
"Invalid messageLenToCipherInBytes for CHACHA-POLY");
return CPA_STATUS_INVALID_PARAM;
}
}
if (0 == pRequest->srcBuffer) {
LAC_INVALID_PARAM_LOG("Invalid srcBuffer");
return CPA_STATUS_INVALID_PARAM;
}
if (0 == pRequest->dstBuffer) {
LAC_INVALID_PARAM_LOG("Invalid destBuffer");
return CPA_STATUS_INVALID_PARAM;
}
if (0 == pRequest->thisPhys) {
LAC_INVALID_PARAM_LOG("Invalid thisPhys");
return CPA_STATUS_INVALID_PARAM;
}
if (pRequest->srcBufferLen != pRequest->dstBufferLen) {
LAC_INVALID_PARAM_LOG(
"Source and Destination buffer lengths need to be equal");
return CPA_STATUS_INVALID_PARAM;
}
if (pSessionDesc->digestIsAppended && pSessionDesc->digestVerify &&
(pSessionDesc->symOperation == CPA_CY_SYM_OP_HASH)) {
LAC_INVALID_PARAM_LOG(
"digestVerify and digestIsAppended set "
"on Hash-Only operation is not supported");
return CPA_STATUS_INVALID_PARAM;
}
if (CPA_CY_SYM_OP_HASH != pSessionDesc->symOperation) {
switch (pSessionDesc->cipherAlgorithm) {
case CPA_CY_SYM_CIPHER_AES_CTR:
case CPA_CY_SYM_CIPHER_3DES_CTR:
case CPA_CY_SYM_CIPHER_SM4_CTR:
case CPA_CY_SYM_CIPHER_AES_GCM:
case CPA_CY_SYM_CIPHER_CHACHA:
case CPA_CY_SYM_CIPHER_AES_CBC:
case CPA_CY_SYM_CIPHER_DES_CBC:
case CPA_CY_SYM_CIPHER_3DES_CBC:
case CPA_CY_SYM_CIPHER_SM4_CBC:
case CPA_CY_SYM_CIPHER_AES_F8: {
Cpa32U ivLenInBytes = LacSymQat_CipherIvSizeBytesGet(
pSessionDesc->cipherAlgorithm);
if (pRequest->ivLenInBytes != ivLenInBytes) {
if (!(
(LAC_CIPHER_IS_GCM(
pSessionDesc->cipherAlgorithm) &&
pRequest->ivLenInBytes ==
LAC_CIPHER_IV_SIZE_GCM_12))) {
LAC_INVALID_PARAM_LOG(
"invalid cipher IV size");
return CPA_STATUS_INVALID_PARAM;
}
}
if (0 == pRequest->iv) {
LAC_INVALID_PARAM_LOG("invalid iv of 0");
return CPA_STATUS_INVALID_PARAM;
}
} break;
case CPA_CY_SYM_CIPHER_KASUMI_F8: {
if (LAC_CIPHER_KASUMI_F8_IV_LENGTH !=
pRequest->ivLenInBytes) {
LAC_INVALID_PARAM_LOG("invalid cipher IV size");
return CPA_STATUS_INVALID_PARAM;
}
if (0 == pRequest->iv) {
LAC_INVALID_PARAM_LOG("invalid iv of 0");
return CPA_STATUS_INVALID_PARAM;
}
} break;
case CPA_CY_SYM_CIPHER_SNOW3G_UEA2: {
if (ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ !=
pRequest->ivLenInBytes) {
LAC_INVALID_PARAM_LOG("invalid cipher IV size");
return CPA_STATUS_INVALID_PARAM;
}
if (0 == pRequest->iv) {
LAC_INVALID_PARAM_LOG("invalid iv of 0");
return CPA_STATUS_INVALID_PARAM;
}
} break;
case CPA_CY_SYM_CIPHER_ZUC_EEA3: {
if (ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ !=
pRequest->ivLenInBytes) {
LAC_INVALID_PARAM_LOG("invalid cipher IV size");
return CPA_STATUS_INVALID_PARAM;
}
if (0 == pRequest->iv) {
LAC_INVALID_PARAM_LOG("invalid iv of 0");
return CPA_STATUS_INVALID_PARAM;
}
} break;
case CPA_CY_SYM_CIPHER_AES_CCM: {
if (CPA_STATUS_SUCCESS !=
LacSymAlgChain_CheckCCMData(
pRequest->pAdditionalAuthData,
pRequest->pIv,
pRequest->messageLenToCipherInBytes,
pRequest->ivLenInBytes)) {
return CPA_STATUS_INVALID_PARAM;
}
} break;
default:
break;
}
switch (pSessionDesc->cipherAlgorithm) {
case CPA_CY_SYM_CIPHER_ARC4:
case CPA_CY_SYM_CIPHER_AES_CTR:
case CPA_CY_SYM_CIPHER_3DES_CTR:
case CPA_CY_SYM_CIPHER_SM4_CTR:
case CPA_CY_SYM_CIPHER_AES_CCM:
case CPA_CY_SYM_CIPHER_AES_GCM:
case CPA_CY_SYM_CIPHER_CHACHA:
case CPA_CY_SYM_CIPHER_KASUMI_F8:
case CPA_CY_SYM_CIPHER_AES_F8:
case CPA_CY_SYM_CIPHER_SNOW3G_UEA2:
case CPA_CY_SYM_CIPHER_ZUC_EEA3:
break;
default: {
if (pRequest->messageLenToCipherInBytes &
(LacSymQat_CipherBlockSizeBytesGet(
pSessionDesc->cipherAlgorithm) -
1)) {
LAC_INVALID_PARAM_LOG(
"Data size must be block size"
" multiple");
return CPA_STATUS_INVALID_PARAM;
}
}
}
cipher = pSessionDesc->cipherAlgorithm;
hash = pSessionDesc->hashAlgorithm;
capabilitiesMask =
((sal_crypto_service_t *)pRequest->instanceHandle)
->generic_service_info.capabilitiesMask;
if (LAC_CIPHER_IS_SPC(cipher, hash, capabilitiesMask) &&
(LAC_CIPHER_SPC_IV_SIZE == pRequest->ivLenInBytes)) {
if ((0 != pSessionDesc->aadLenInBytes) &&
(CPA_CY_SYM_HASH_AES_GMAC !=
pSessionDesc->hashAlgorithm)) {
LAC_CHECK_NULL_PARAM(
pRequest->pAdditionalAuthData);
}
if ((CPA_CY_SYM_HASH_AES_GMAC == hash) &&
(ICP_QAT_FW_SPC_AAD_SZ_MAX <
pRequest->messageLenToHashInBytes)) {
LAC_INVALID_PARAM_LOG(
"aadLenInBytes for AES_GMAC");
return CPA_STATUS_INVALID_PARAM;
}
}
}
if (CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation) {
if ((CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm) ||
(CPA_CY_SYM_HASH_AES_GCM == pSessionDesc->hashAlgorithm &&
(0 != pSessionDesc->aadLenInBytes))) {
LAC_CHECK_NULL_PARAM(pRequest->pAdditionalAuthData);
if (0 == pRequest->additionalAuthData) {
LAC_INVALID_PARAM_LOG(
"Invalid additionalAuthData");
return CPA_STATUS_INVALID_PARAM;
}
} else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
pSessionDesc->hashAlgorithm ||
CPA_CY_SYM_HASH_ZUC_EIA3 ==
pSessionDesc->hashAlgorithm) {
if (0 == pRequest->additionalAuthData) {
LAC_INVALID_PARAM_LOG(
"Invalid additionalAuthData");
return CPA_STATUS_INVALID_PARAM;
}
}
if ((CPA_CY_SYM_HASH_AES_CCM != pSessionDesc->hashAlgorithm) &&
(!pSessionDesc->digestIsAppended) &&
(0 == pRequest->digestResult)) {
LAC_INVALID_PARAM_LOG("Invalid digestResult");
return CPA_STATUS_INVALID_PARAM;
}
if (CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm) {
if ((pRequest->cryptoStartSrcOffsetInBytes +
pRequest->messageLenToCipherInBytes +
pSessionDesc->hashResultSize) >
pRequest->dstBufferLen) {
LAC_INVALID_PARAM_LOG(
"CCM - Not enough room for"
" digest in destination buffer");
return CPA_STATUS_INVALID_PARAM;
}
} else if (CPA_TRUE == pSessionDesc->digestIsAppended) {
if (CPA_CY_SYM_HASH_AES_GMAC ==
pSessionDesc->hashAlgorithm) {
if ((pRequest->hashStartSrcOffsetInBytes +
pRequest->messageLenToHashInBytes +
pSessionDesc->hashResultSize) >
pRequest->dstBufferLen) {
LAC_INVALID_PARAM_LOG(
"Append Digest - Not enough room for"
" digest in destination buffer for "
"AES GMAC algorithm");
return CPA_STATUS_INVALID_PARAM;
}
}
if (CPA_CY_SYM_HASH_AES_GCM ==
pSessionDesc->hashAlgorithm) {
if ((pRequest->cryptoStartSrcOffsetInBytes +
pRequest->messageLenToCipherInBytes +
pSessionDesc->hashResultSize) >
pRequest->dstBufferLen) {
LAC_INVALID_PARAM_LOG(
"Append Digest - Not enough room "
"for digest in destination buffer"
" for GCM algorithm");
return CPA_STATUS_INVALID_PARAM;
}
}
if ((pRequest->hashStartSrcOffsetInBytes +
pRequest->messageLenToHashInBytes +
pSessionDesc->hashResultSize) >
pRequest->dstBufferLen) {
LAC_INVALID_PARAM_LOG(
"Append Digest - Not enough room for"
" digest in destination buffer");
return CPA_STATUS_INVALID_PARAM;
}
}
if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
if (pRequest->messageLenToHashInBytes == 0 ||
pRequest->pAdditionalAuthData != NULL) {
LAC_INVALID_PARAM_LOG(
"For AES_GMAC, AAD Length "
"(messageLenToHashInBytes) must be "
"non zero and pAdditionalAuthData "
"must be NULL");
return CPA_STATUS_INVALID_PARAM;
}
}
}
if (CPA_DP_BUFLIST != pRequest->srcBufferLen) {
if ((CPA_CY_SYM_OP_HASH != pSessionDesc->symOperation) &&
((pRequest->messageLenToCipherInBytes +
pRequest->cryptoStartSrcOffsetInBytes) >
pRequest->srcBufferLen)) {
LAC_INVALID_PARAM_LOG(
"cipher len + offset greater than "
"srcBufferLen");
return CPA_STATUS_INVALID_PARAM;
} else if ((CPA_CY_SYM_OP_CIPHER !=
pSessionDesc->symOperation) &&
(CPA_CY_SYM_HASH_AES_CCM !=
pSessionDesc->hashAlgorithm) &&
(CPA_CY_SYM_HASH_AES_GCM !=
pSessionDesc->hashAlgorithm) &&
(CPA_CY_SYM_HASH_AES_GMAC !=
pSessionDesc->hashAlgorithm) &&
((pRequest->messageLenToHashInBytes +
pRequest->hashStartSrcOffsetInBytes) >
pRequest->srcBufferLen)) {
LAC_INVALID_PARAM_LOG(
"hash len + offset greater than srcBufferLen");
return CPA_STATUS_INVALID_PARAM;
}
} else {
LAC_CHECK_8_BYTE_ALIGNMENT(pRequest->srcBuffer);
LAC_CHECK_8_BYTE_ALIGNMENT(pRequest->dstBuffer);
}
LAC_CHECK_8_BYTE_ALIGNMENT(pRequest->thisPhys);
return CPA_STATUS_SUCCESS;
}
void
LacDp_WriteRingMsgOpt(CpaCySymDpOpData *pRequest,
icp_qat_fw_la_bulk_req_t *pCurrentQatMsg)
{
lac_session_desc_t *pSessionDesc =
LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
Cpa8U *pMsgDummy = NULL;
Cpa8U *pCacheDummyHdr = NULL;
Cpa8U *pCacheDummyFtr = NULL;
pMsgDummy = (Cpa8U *)pCurrentQatMsg;
if (!pSessionDesc->useSymConstantsTable) {
pCacheDummyHdr = (Cpa8U *)&(pSessionDesc->reqCacheHdr);
pCacheDummyFtr = (Cpa8U *)&(pSessionDesc->reqCacheFtr);
} else {
pCacheDummyHdr = (Cpa8U *)&(pSessionDesc->shramReqCacheHdr);
pCacheDummyFtr = (Cpa8U *)&(pSessionDesc->shramReqCacheFtr);
}
memcpy(pMsgDummy,
pCacheDummyHdr,
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
memset((pMsgDummy +
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW)),
0,
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_TO_CLEAR_IN_LW));
memcpy(pMsgDummy +
(LAC_LONG_WORD_IN_BYTES * LAC_START_OF_CACHE_FTR_IN_LW),
pCacheDummyFtr,
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
SalQatMsg_CmnMidWrite(pCurrentQatMsg,
pRequest,
(CPA_DP_BUFLIST == pRequest->srcBufferLen ?
QAT_COMN_PTR_TYPE_SGL :
QAT_COMN_PTR_TYPE_FLAT),
pRequest->srcBuffer,
pRequest->dstBuffer,
pRequest->srcBufferLen,
pRequest->dstBufferLen);
if (pSessionDesc->isCipher) {
LacSymQat_CipherRequestParamsPopulate(
pSessionDesc,
pCurrentQatMsg,
pRequest->cryptoStartSrcOffsetInBytes,
pRequest->messageLenToCipherInBytes,
pRequest->iv,
pRequest->pIv);
}
if (pSessionDesc->isAuth) {
lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo =
&(pSessionDesc->hashStateBufferInfo);
icp_qat_fw_la_auth_req_params_t *pAuthReqPars =
(icp_qat_fw_la_auth_req_params_t
*)((Cpa8U *)&(pCurrentQatMsg->serv_specif_rqpars) +
ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET);
if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 !=
pSessionDesc->hashAlgorithm &&
CPA_CY_SYM_HASH_AES_CCM != pSessionDesc->hashAlgorithm &&
CPA_CY_SYM_HASH_AES_GCM != pSessionDesc->hashAlgorithm &&
CPA_CY_SYM_HASH_AES_GMAC != pSessionDesc->hashAlgorithm &&
CPA_CY_SYM_HASH_ZUC_EIA3 != pSessionDesc->hashAlgorithm) &&
(pHashStateBufferInfo->prefixAadSzQuadWords > 0)) {
pRequest->additionalAuthData =
pHashStateBufferInfo->pDataPhys +
LAC_QUADWORDS_TO_BYTES(
pHashStateBufferInfo->stateStorageSzQuadWords);
}
unsigned long cplen =
(unsigned long)&(pAuthReqPars->u2.inner_prefix_sz) -
(unsigned long)pAuthReqPars;
if (cplen == 16)
memcpy(pAuthReqPars,
(Cpa32U *)&(pRequest->hashStartSrcOffsetInBytes),
16);
else
memcpy(pAuthReqPars,
(Cpa32U *)&(pRequest->hashStartSrcOffsetInBytes),
cplen);
if (CPA_TRUE == pSessionDesc->isAuthEncryptOp) {
pAuthReqPars->hash_state_sz =
LAC_BYTES_TO_QUADWORDS(pAuthReqPars->u2.aad_sz);
} else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
pSessionDesc->hashAlgorithm ||
CPA_CY_SYM_HASH_ZUC_EIA3 ==
pSessionDesc->hashAlgorithm) {
pAuthReqPars->hash_state_sz =
LAC_BYTES_TO_QUADWORDS(pSessionDesc->aadLenInBytes);
}
}
}
void
LacDp_WriteRingMsgFull(CpaCySymDpOpData *pRequest,
icp_qat_fw_la_bulk_req_t *pCurrentQatMsg)
{
lac_session_desc_t *pSessionDesc =
LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
Cpa8U *pMsgDummy = NULL;
Cpa8U *pCacheDummyHdr = NULL;
Cpa8U *pCacheDummyFtr = NULL;
sal_qat_content_desc_info_t *pCdInfo = NULL;
Cpa8U *pHwBlockBaseInDRAM = NULL;
Cpa32U hwBlockOffsetInDRAM = 0;
Cpa32U sizeInBytes = 0;
CpaCySymCipherAlgorithm cipher = pSessionDesc->cipherAlgorithm;
CpaCySymHashAlgorithm hash = pSessionDesc->hashAlgorithm;
sal_crypto_service_t *pService =
(sal_crypto_service_t *)pRequest->instanceHandle;
Cpa32U capabilitiesMask =
((sal_crypto_service_t *)pRequest->instanceHandle)
->generic_service_info.capabilitiesMask;
CpaBoolean isSpCcm = LAC_CIPHER_IS_CCM(cipher) &&
LAC_CIPHER_IS_SPC(cipher, hash, capabilitiesMask);
Cpa8U paddingLen = 0;
Cpa8U blockLen = 0;
Cpa32U aadDataLen = 0;
pMsgDummy = (Cpa8U *)pCurrentQatMsg;
if ((NON_SPC != pSessionDesc->singlePassState) &&
(isSpCcm || (LAC_CIPHER_SPC_IV_SIZE == pRequest->ivLenInBytes))) {
pSessionDesc->singlePassState = SPC;
pSessionDesc->isCipher = CPA_TRUE;
pSessionDesc->isAuthEncryptOp = CPA_FALSE;
pSessionDesc->isAuth = CPA_FALSE;
pSessionDesc->symOperation = CPA_CY_SYM_OP_CIPHER;
pSessionDesc->laCmdId = ICP_QAT_FW_LA_CMD_CIPHER;
if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
pSessionDesc->aadLenInBytes =
pRequest->messageLenToHashInBytes;
}
ICP_QAT_FW_LA_SINGLE_PASS_PROTO_FLAG_SET(
pSessionDesc->laCmdFlags, ICP_QAT_FW_LA_SINGLE_PASS_PROTO);
if (isCyGen2x(pService))
ICP_QAT_FW_LA_PROTO_SET(pSessionDesc->laCmdFlags, 0);
pCdInfo = &(pSessionDesc->contentDescInfo);
pHwBlockBaseInDRAM = (Cpa8U *)pCdInfo->pData;
if (CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT ==
pSessionDesc->cipherDirection) {
if (LAC_CIPHER_IS_GCM(cipher))
hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
LAC_SYM_QAT_CIPHER_GCM_SPC_OFFSET_IN_DRAM);
else if (LAC_CIPHER_IS_CHACHA(cipher))
hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
LAC_SYM_QAT_CIPHER_CHACHA_SPC_OFFSET_IN_DRAM);
} else if (isSpCcm) {
hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
LAC_SYM_QAT_CIPHER_CCM_SPC_OFFSET_IN_DRAM);
}
pSessionDesc->cipherSliceType =
LacCipher_GetCipherSliceType(pService, cipher, hash);
ICP_QAT_FW_LA_SLICE_TYPE_SET(pSessionDesc->laCmdFlags,
pSessionDesc->cipherSliceType);
LacSymQat_CipherHwBlockPopulateCfgData(pSessionDesc,
pHwBlockBaseInDRAM +
hwBlockOffsetInDRAM,
&sizeInBytes);
SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&(
pSessionDesc->reqSpcCacheHdr),
ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
pSessionDesc->laCmdId,
pSessionDesc->cmnRequestFlags,
pSessionDesc->laCmdFlags);
} else if ((SPC == pSessionDesc->singlePassState) &&
(LAC_CIPHER_SPC_IV_SIZE != pRequest->ivLenInBytes)) {
pSessionDesc->symOperation = CPA_CY_SYM_OP_ALGORITHM_CHAINING;
pSessionDesc->singlePassState = LIKELY_SPC;
pSessionDesc->isCipher = CPA_TRUE;
pSessionDesc->isAuthEncryptOp = CPA_TRUE;
pSessionDesc->isAuth = CPA_TRUE;
pCdInfo = &(pSessionDesc->contentDescInfo);
pHwBlockBaseInDRAM = (Cpa8U *)pCdInfo->pData;
if (CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT ==
pSessionDesc->cipherDirection) {
pSessionDesc->laCmdId = ICP_QAT_FW_LA_CMD_CIPHER_HASH;
} else {
pSessionDesc->laCmdId = ICP_QAT_FW_LA_CMD_HASH_CIPHER;
}
ICP_QAT_FW_LA_SINGLE_PASS_PROTO_FLAG_SET(
pSessionDesc->laCmdFlags, 0);
ICP_QAT_FW_LA_PROTO_SET(pSessionDesc->laCmdFlags,
ICP_QAT_FW_LA_GCM_PROTO);
LacSymQat_CipherHwBlockPopulateCfgData(pSessionDesc,
pHwBlockBaseInDRAM +
hwBlockOffsetInDRAM,
&sizeInBytes);
SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&(
pSessionDesc->reqCacheHdr),
ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
pSessionDesc->laCmdId,
pSessionDesc->cmnRequestFlags,
pSessionDesc->laCmdFlags);
} else if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
pSessionDesc->aadLenInBytes = pRequest->messageLenToHashInBytes;
}
if (SPC == pSessionDesc->singlePassState) {
pCacheDummyHdr = (Cpa8U *)&(pSessionDesc->reqSpcCacheHdr);
pCacheDummyFtr = (Cpa8U *)&(pSessionDesc->reqSpcCacheFtr);
} else {
if (!pSessionDesc->useSymConstantsTable) {
pCacheDummyHdr = (Cpa8U *)&(pSessionDesc->reqCacheHdr);
pCacheDummyFtr = (Cpa8U *)&(pSessionDesc->reqCacheFtr);
} else {
pCacheDummyHdr =
(Cpa8U *)&(pSessionDesc->shramReqCacheHdr);
pCacheDummyFtr =
(Cpa8U *)&(pSessionDesc->shramReqCacheFtr);
}
}
memcpy(pMsgDummy,
pCacheDummyHdr,
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
memset((pMsgDummy +
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW)),
0,
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_TO_CLEAR_IN_LW));
memcpy(pMsgDummy +
(LAC_LONG_WORD_IN_BYTES * LAC_START_OF_CACHE_FTR_IN_LW),
pCacheDummyFtr,
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
SalQatMsg_CmnMidWrite(pCurrentQatMsg,
pRequest,
(CPA_DP_BUFLIST == pRequest->srcBufferLen ?
QAT_COMN_PTR_TYPE_SGL :
QAT_COMN_PTR_TYPE_FLAT),
pRequest->srcBuffer,
pRequest->dstBuffer,
pRequest->srcBufferLen,
pRequest->dstBufferLen);
if ((CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm &&
pSessionDesc->isAuth == CPA_TRUE) ||
isSpCcm) {
LacSymAlgChain_PrepareCCMData(
pSessionDesc,
pRequest->pAdditionalAuthData,
pRequest->pIv,
pRequest->messageLenToCipherInBytes,
pRequest->ivLenInBytes);
pRequest->hashStartSrcOffsetInBytes =
pRequest->cryptoStartSrcOffsetInBytes;
pRequest->messageLenToHashInBytes =
pRequest->messageLenToCipherInBytes;
} else if ((SPC != pSessionDesc->singlePassState) &&
(CPA_CY_SYM_HASH_AES_GCM == pSessionDesc->hashAlgorithm ||
CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm)) {
if (CPA_CY_SYM_HASH_AES_GMAC != pSessionDesc->hashAlgorithm) {
pRequest->hashStartSrcOffsetInBytes =
pRequest->cryptoStartSrcOffsetInBytes;
pRequest->messageLenToHashInBytes =
pRequest->messageLenToCipherInBytes;
LacSymAlgChain_PrepareGCMData(
pSessionDesc, pRequest->pAdditionalAuthData);
}
if (LAC_CIPHER_IV_SIZE_GCM_12 == pRequest->ivLenInBytes) {
ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET(
pCurrentQatMsg->comn_hdr.serv_specif_flags,
ICP_QAT_FW_LA_GCM_IV_LEN_12_OCTETS);
}
}
if (pSessionDesc->isCipher) {
if (CPA_CY_SYM_CIPHER_ARC4 == pSessionDesc->cipherAlgorithm) {
pRequest->iv =
pSessionDesc->cipherARC4InitialStatePhysAddr;
}
ICP_QAT_FW_LA_SLICE_TYPE_SET(
pCurrentQatMsg->comn_hdr.serv_specif_flags,
pSessionDesc->cipherSliceType);
LacSymQat_CipherRequestParamsPopulate(
pSessionDesc,
pCurrentQatMsg,
pRequest->cryptoStartSrcOffsetInBytes,
pRequest->messageLenToCipherInBytes,
pRequest->iv,
pRequest->pIv);
if (SPC == pSessionDesc->singlePassState) {
icp_qat_fw_la_cipher_req_params_t *pCipherReqParams =
(icp_qat_fw_la_cipher_req_params_t
*)((Cpa8U *)&(
pCurrentQatMsg->serv_specif_rqpars) +
ICP_QAT_FW_CIPHER_REQUEST_PARAMETERS_OFFSET);
icp_qat_fw_la_cipher_20_req_params_t *pCipher20ReqParams =
(void
*)((Cpa8U *)&(
pCurrentQatMsg->serv_specif_rqpars) +
ICP_QAT_FW_CIPHER_REQUEST_PARAMETERS_OFFSET);
if (isCyGen4x(pService)) {
pCipher20ReqParams->spc_aad_addr =
(uint64_t)pRequest->additionalAuthData;
pCipher20ReqParams->spc_aad_sz =
pSessionDesc->aadLenInBytes;
pCipher20ReqParams->spc_aad_offset = 0;
if (isSpCcm)
pCipher20ReqParams->spc_aad_sz +=
LAC_CIPHER_CCM_AAD_OFFSET;
pCipher20ReqParams->spc_auth_res_addr =
(uint64_t)pRequest->digestResult;
pCipher20ReqParams->spc_auth_res_sz =
(Cpa8U)pSessionDesc->hashResultSize;
} else {
pCipherReqParams->spc_aad_addr =
(uint64_t)pRequest->additionalAuthData;
pCipherReqParams->spc_aad_sz =
(Cpa16U)pSessionDesc->aadLenInBytes;
pCipherReqParams->spc_auth_res_addr =
(uint64_t)pRequest->digestResult;
pCipherReqParams->spc_auth_res_sz =
(Cpa8U)pSessionDesc->hashResultSize;
}
if (0 != pSessionDesc->aadLenInBytes &&
CPA_CY_SYM_HASH_AES_GMAC !=
pSessionDesc->hashAlgorithm) {
blockLen = LacSymQat_CipherBlockSizeBytesGet(
pSessionDesc->cipherAlgorithm);
aadDataLen = pSessionDesc->aadLenInBytes;
if (isSpCcm)
aadDataLen += LAC_CIPHER_CCM_AAD_OFFSET;
if ((aadDataLen % blockLen) != 0) {
paddingLen =
blockLen - (aadDataLen % blockLen);
memset(&pRequest->pAdditionalAuthData
[aadDataLen],
0,
paddingLen);
}
}
}
}
if (pSessionDesc->isAuth) {
lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo =
&(pSessionDesc->hashStateBufferInfo);
icp_qat_fw_la_auth_req_params_t *pAuthReqPars =
(icp_qat_fw_la_auth_req_params_t
*)((Cpa8U *)&(pCurrentQatMsg->serv_specif_rqpars) +
ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET);
if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 !=
pSessionDesc->hashAlgorithm &&
CPA_CY_SYM_HASH_AES_CCM != pSessionDesc->hashAlgorithm &&
CPA_CY_SYM_HASH_AES_GCM != pSessionDesc->hashAlgorithm &&
CPA_CY_SYM_HASH_AES_GMAC != pSessionDesc->hashAlgorithm &&
CPA_CY_SYM_HASH_ZUC_EIA3 != pSessionDesc->hashAlgorithm) &&
(pHashStateBufferInfo->prefixAadSzQuadWords > 0)) {
pRequest->additionalAuthData =
pHashStateBufferInfo->pDataPhys +
LAC_QUADWORDS_TO_BYTES(
pHashStateBufferInfo->stateStorageSzQuadWords);
}
memcpy(pAuthReqPars,
(Cpa32U *)&(pRequest->hashStartSrcOffsetInBytes),
((uintptr_t) &
(pAuthReqPars->u2.inner_prefix_sz) -
(uintptr_t)pAuthReqPars));
if (CPA_TRUE == pSessionDesc->isAuthEncryptOp) {
pAuthReqPars->hash_state_sz =
LAC_BYTES_TO_QUADWORDS(pAuthReqPars->u2.aad_sz);
} else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
pSessionDesc->hashAlgorithm ||
CPA_CY_SYM_HASH_ZUC_EIA3 ==
pSessionDesc->hashAlgorithm) {
pAuthReqPars->hash_state_sz =
LAC_BYTES_TO_QUADWORDS(pSessionDesc->aadLenInBytes);
}
}
}
CpaStatus
cpaCySymDpSessionCtxGetSize(const CpaInstanceHandle instanceHandle,
const CpaCySymSessionSetupData *pSessionSetupData,
Cpa32U *pSessionCtxSizeInBytes)
{
CpaStatus status = CPA_STATUS_SUCCESS;
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
status = cpaCySymSessionCtxGetSize(instanceHandle,
pSessionSetupData,
pSessionCtxSizeInBytes);
return status;
}
CpaStatus
cpaCySymDpSessionCtxGetDynamicSize(
const CpaInstanceHandle instanceHandle,
const CpaCySymSessionSetupData *pSessionSetupData,
Cpa32U *pSessionCtxSizeInBytes)
{
CpaStatus status = CPA_STATUS_SUCCESS;
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
status = cpaCySymSessionCtxGetDynamicSize(instanceHandle,
pSessionSetupData,
pSessionCtxSizeInBytes);
return status;
}
CpaStatus
cpaCySymDpInitSession(CpaInstanceHandle instanceHandle,
const CpaCySymSessionSetupData *pSessionSetupData,
CpaCySymDpSessionCtx sessionCtx)
{
CpaStatus status = CPA_STATUS_FAIL;
sal_service_t *pService = NULL;
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
LAC_CHECK_NULL_PARAM(pSessionSetupData);
pService = (sal_service_t *)instanceHandle;
SAL_RUNNING_CHECK(pService);
status = LacSym_InitSession(instanceHandle,
NULL,
pSessionSetupData,
CPA_TRUE,
sessionCtx);
return status;
}
CpaStatus
cpaCySymDpRemoveSession(const CpaInstanceHandle instanceHandle,
CpaCySymDpSessionCtx sessionCtx)
{
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
return cpaCySymRemoveSession(instanceHandle, sessionCtx);
}
CpaStatus
cpaCySymDpRegCbFunc(const CpaInstanceHandle instanceHandle,
const CpaCySymDpCbFunc pSymDpCb)
{
sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
LAC_CHECK_NULL_PARAM(pSymDpCb);
SAL_RUNNING_CHECK(instanceHandle);
pService->pSymDpCb = pSymDpCb;
return CPA_STATUS_SUCCESS;
}
CpaStatus
cpaCySymDpEnqueueOp(CpaCySymDpOpData *pRequest, const CpaBoolean performOpNow)
{
icp_qat_fw_la_bulk_req_t *pCurrentQatMsg = NULL;
icp_comms_trans_handle trans_handle = NULL;
lac_session_desc_t *pSessionDesc = NULL;
write_ringMsgFunc_t callFunc;
CpaStatus status = CPA_STATUS_SUCCESS;
LAC_CHECK_NULL_PARAM(pRequest);
status = LacDp_EnqueueParamCheck(pRequest);
if (CPA_STATUS_SUCCESS != status) {
return status;
}
SAL_RUNNING_CHECK(pRequest->instanceHandle);
trans_handle = ((sal_crypto_service_t *)pRequest->instanceHandle)
->trans_handle_sym_tx;
pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
icp_adf_getSingleQueueAddr(trans_handle, (void **)&pCurrentQatMsg);
if (NULL == pCurrentQatMsg) {
return CPA_STATUS_RETRY;
}
callFunc = (write_ringMsgFunc_t)pSessionDesc->writeRingMsgFunc;
LAC_CHECK_NULL_PARAM(callFunc);
callFunc(pRequest, pCurrentQatMsg);
qatUtilsAtomicInc(&(pSessionDesc->u.pendingDpCbCount));
if (CPA_TRUE == performOpNow) {
SalQatMsg_updateQueueTail(trans_handle);
}
return CPA_STATUS_SUCCESS;
}
CpaStatus
cpaCySymDpPerformOpNow(const CpaInstanceHandle instanceHandle)
{
icp_comms_trans_handle trans_handle = NULL;
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
SAL_RUNNING_CHECK(instanceHandle);
trans_handle =
((sal_crypto_service_t *)instanceHandle)->trans_handle_sym_tx;
if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
SalQatMsg_updateQueueTail(trans_handle);
}
return CPA_STATUS_SUCCESS;
}
CpaStatus
cpaCySymDpEnqueueOpBatch(const Cpa32U numberRequests,
CpaCySymDpOpData *pRequests[],
const CpaBoolean performOpNow)
{
icp_qat_fw_la_bulk_req_t *pCurrentQatMsg = NULL;
icp_comms_trans_handle trans_handle = NULL;
lac_session_desc_t *pSessionDesc = NULL;
write_ringMsgFunc_t callFunc;
Cpa32U i = 0;
CpaStatus status = CPA_STATUS_SUCCESS;
sal_crypto_service_t *pService = NULL;
LAC_CHECK_NULL_PARAM(pRequests);
LAC_CHECK_NULL_PARAM(pRequests[0]);
LAC_CHECK_NULL_PARAM(pRequests[0]->instanceHandle);
pService = (sal_crypto_service_t *)(pRequests[0]->instanceHandle);
if ((0 == numberRequests) ||
(numberRequests > pService->maxNumSymReqBatch)) {
LAC_INVALID_PARAM_LOG1(
"The number of requests needs to be between 1 "
"and %d",
pService->maxNumSymReqBatch);
return CPA_STATUS_INVALID_PARAM;
}
for (i = 0; i < numberRequests; i++) {
status = LacDp_EnqueueParamCheck(pRequests[i]);
if (CPA_STATUS_SUCCESS != status) {
return status;
}
if (pRequests[i]->instanceHandle !=
pRequests[0]->instanceHandle) {
LAC_INVALID_PARAM_LOG(
"All instance handles should be the same "
"in the requests");
return CPA_STATUS_INVALID_PARAM;
}
}
SAL_RUNNING_CHECK(pRequests[0]->instanceHandle);
trans_handle = ((sal_crypto_service_t *)pRequests[0]->instanceHandle)
->trans_handle_sym_tx;
pSessionDesc =
LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequests[0]->sessionCtx);
icp_adf_getQueueMemory(trans_handle,
numberRequests,
(void **)&pCurrentQatMsg);
if (NULL == pCurrentQatMsg) {
return CPA_STATUS_RETRY;
}
for (i = 0; i < numberRequests; i++) {
pSessionDesc =
LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequests[i]->sessionCtx);
callFunc = (write_ringMsgFunc_t)pSessionDesc->writeRingMsgFunc;
callFunc(pRequests[i], pCurrentQatMsg);
icp_adf_getQueueNext(trans_handle, (void **)&pCurrentQatMsg);
qatUtilsAtomicAdd(1, &(pSessionDesc->u.pendingDpCbCount));
}
if (CPA_TRUE == performOpNow) {
SalQatMsg_updateQueueTail(trans_handle);
}
return CPA_STATUS_SUCCESS;
}
CpaStatus
icp_sal_CyPollDpInstance(const CpaInstanceHandle instanceHandle,
const Cpa32U responseQuota)
{
icp_comms_trans_handle trans_handle = NULL;
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
SAL_RUNNING_CHECK(instanceHandle);
trans_handle =
((sal_crypto_service_t *)instanceHandle)->trans_handle_sym_rx;
return icp_adf_pollQueue(trans_handle, responseQuota);
}