Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/qat/qat_api/common/crypto/sym/lac_sym_cipher.c
Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
#include "lac_sal_ctrl.h" | #include "lac_sal_ctrl.h" | ||||
#include "lac_sym_cipher_defs.h" | #include "lac_sym_cipher_defs.h" | ||||
#include "lac_sym_cipher.h" | #include "lac_sym_cipher.h" | ||||
#include "lac_sym_stats.h" | #include "lac_sym_stats.h" | ||||
#include "lac_sym.h" | #include "lac_sym.h" | ||||
#include "lac_sym_qat_cipher.h" | #include "lac_sym_qat_cipher.h" | ||||
#include "lac_log.h" | #include "lac_log.h" | ||||
#include "lac_buffer_desc.h" | #include "lac_buffer_desc.h" | ||||
#include "sal_hw_gen.h" | |||||
/* | /* | ||||
******************************************************************************* | ******************************************************************************* | ||||
* Static Variables | * Static Variables | ||||
******************************************************************************* | ******************************************************************************* | ||||
*/ | */ | ||||
CpaStatus | CpaStatus | ||||
LacCipher_PerformIvCheck(sal_service_t *pService, | LacCipher_PerformIvCheck(sal_service_t *pService, | ||||
lac_sym_bulk_cookie_t *pCbCookie, | lac_sym_bulk_cookie_t *pCbCookie, | ||||
Cpa32U qatPacketType, | Cpa32U qatPacketType, | ||||
Cpa8U **ppIvBuffer) | Cpa8U **ppIvBuffer) | ||||
{ | { | ||||
const CpaCySymOpData *pOpData = pCbCookie->pOpData; | const CpaCySymOpData *pOpData = pCbCookie->pOpData; | ||||
lac_session_desc_t *pSessionDesc = | lac_session_desc_t *pSessionDesc = | ||||
LAC_SYM_SESSION_DESC_FROM_CTX_GET(pOpData->sessionCtx); | LAC_SYM_SESSION_DESC_FROM_CTX_GET(pOpData->sessionCtx); | ||||
CpaCySymCipherAlgorithm algorithm = pSessionDesc->cipherAlgorithm; | CpaCySymCipherAlgorithm algorithm = pSessionDesc->cipherAlgorithm; | ||||
unsigned ivLenInBytes = 0; | |||||
/* Perform IV check. */ | switch (algorithm) { | ||||
if (LAC_CIPHER_IS_CTR_MODE(algorithm) || | /* Perform IV check for CTR, CBC, XTS, F8 MODE. */ | ||||
LAC_CIPHER_IS_CBC_MODE(algorithm) || | case CPA_CY_SYM_CIPHER_AES_CTR: | ||||
LAC_CIPHER_IS_AES_F8(algorithm) || | case CPA_CY_SYM_CIPHER_3DES_CTR: | ||||
LAC_CIPHER_IS_XTS_MODE(algorithm)) { | case CPA_CY_SYM_CIPHER_SM4_CTR: | ||||
unsigned ivLenInBytes = | case CPA_CY_SYM_CIPHER_AES_CCM: | ||||
LacSymQat_CipherIvSizeBytesGet(algorithm); | 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: | |||||
case CPA_CY_SYM_CIPHER_AES_XTS: { | |||||
ivLenInBytes = LacSymQat_CipherIvSizeBytesGet(algorithm); | |||||
LAC_CHECK_NULL_PARAM(pOpData->pIv); | LAC_CHECK_NULL_PARAM(pOpData->pIv); | ||||
if (pOpData->ivLenInBytes != ivLenInBytes) { | if (pOpData->ivLenInBytes != ivLenInBytes) { | ||||
if (!(/* GCM with 12 byte IV is OK */ | if (!(/* GCM with 12 byte IV is OK */ | ||||
(LAC_CIPHER_IS_GCM(algorithm) && | (LAC_CIPHER_IS_GCM(algorithm) && | ||||
pOpData->ivLenInBytes == | pOpData->ivLenInBytes == | ||||
LAC_CIPHER_IV_SIZE_GCM_12) || | LAC_CIPHER_IV_SIZE_GCM_12) || | ||||
/* IV len for CCM has been checked before */ | /* IV len for CCM has been checked before */ | ||||
LAC_CIPHER_IS_CCM(algorithm))) { | LAC_CIPHER_IS_CCM(algorithm))) { | ||||
LAC_INVALID_PARAM_LOG("invalid cipher IV size"); | LAC_INVALID_PARAM_LOG("invalid cipher IV size"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} | } | ||||
/* Always copy the user's IV into another cipher state buffer if | /* Always copy the user's IV into another cipher state buffer if | ||||
* the request is part of a partial packet sequence | * the request is part of a partial packet sequence | ||||
* (ensures that pipelined partial requests use same | * (ensures that pipelined partial requests use same | ||||
* buffer) | * buffer) | ||||
*/ | */ | ||||
if (ICP_QAT_FW_LA_PARTIAL_NONE == qatPacketType) { | if (ICP_QAT_FW_LA_PARTIAL_NONE == qatPacketType) { | ||||
/* Set the value of the ppIvBuffer to that supplied | /* Set the value of the ppIvBuffer to that supplied | ||||
* by the user. | * by the user. | ||||
* NOTE: There is no guarantee that this address is | * NOTE: There is no guarantee that this address is | ||||
* aligned on | * aligned on an 8 or 64 Byte address. */ | ||||
* an 8 or 64 Byte address. */ | |||||
*ppIvBuffer = pOpData->pIv; | *ppIvBuffer = pOpData->pIv; | ||||
} else { | } else { | ||||
/* For partial packets, we use a per-session buffer to | /* For partial packets, we use a per-session buffer to | ||||
* maintain | * maintain the IV. This allows us to easily pass the | ||||
* the IV. This allows us to easily pass the updated IV | * updated IV forward to the next partial in the | ||||
* forward | * sequence. This makes internal buffering of partials | ||||
* to the next partial in the sequence. This makes | * easier to implement. | ||||
* internal | |||||
* buffering of partials easier to implement. | |||||
*/ | */ | ||||
*ppIvBuffer = pSessionDesc->cipherPartialOpState; | *ppIvBuffer = pSessionDesc->cipherPartialOpState; | ||||
/* Ensure that the user's IV buffer gets updated between | /* Ensure that the user's IV buffer gets updated between | ||||
* partial | * partial requests so that they may also see the | ||||
* requests so that they may also see the residue from | * residue from the previous partial. Not needed for | ||||
* the | * final partials though. | ||||
* previous partial. Not needed for final partials | |||||
* though. | |||||
*/ | */ | ||||
if ((ICP_QAT_FW_LA_PARTIAL_START == qatPacketType) || | if ((ICP_QAT_FW_LA_PARTIAL_START == qatPacketType) || | ||||
(ICP_QAT_FW_LA_PARTIAL_MID == qatPacketType)) { | (ICP_QAT_FW_LA_PARTIAL_MID == qatPacketType)) { | ||||
pCbCookie->updateUserIvOnRecieve = CPA_TRUE; | pCbCookie->updateUserIvOnRecieve = CPA_TRUE; | ||||
if (ICP_QAT_FW_LA_PARTIAL_START == | if (ICP_QAT_FW_LA_PARTIAL_START == | ||||
qatPacketType) { | qatPacketType) { | ||||
/* if the previous partial state was | /* if the previous partial state was | ||||
* full, then this is | * full, then this is the first partial | ||||
* the first partial in the sequence so | * in the sequence so we need to copy in | ||||
* we need to copy | * the user's IV. But, we have to be | ||||
* in the user's IV. But, we have to be | * very careful here not to overwrite | ||||
* very careful | * the cipherPartialOpState just yet in | ||||
* here not to overwrite the | * case there's a previous partial | ||||
* cipherPartialOpState just | * sequence in flight, so we defer the | ||||
* yet in case there's a previous | * copy for now. This will be completed | ||||
* partial sequence in | * in the LacSymQueue_RequestSend() | ||||
* flight, so we defer the copy for now. | * function. | ||||
* This will be | |||||
* completed in the | |||||
* LacSymQueue_RequestSend() function. | |||||
*/ | */ | ||||
pCbCookie->updateSessionIvOnSend = | pCbCookie->updateSessionIvOnSend = | ||||
CPA_TRUE; | CPA_TRUE; | ||||
} | } | ||||
/* For subsequent partials in a sequence, we'll | /* For subsequent partials in a sequence, we'll | ||||
* re-use the | * re-use the IV that was written back by the | ||||
* IV that was written back by the QAT, using | * QAT, using internal request queueing if | ||||
* internal | * necessary to ensure that the next partial | ||||
* request queueing if necessary to ensure that | * request isn't issued to the QAT until the | ||||
* the next | |||||
* partial request isn't issued to the QAT until | |||||
* the | |||||
* previous one completes | * previous one completes | ||||
*/ | */ | ||||
} | } | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_KASUMI(algorithm)) { | } break; | ||||
case CPA_CY_SYM_CIPHER_KASUMI_F8: { | |||||
LAC_CHECK_NULL_PARAM(pOpData->pIv); | LAC_CHECK_NULL_PARAM(pOpData->pIv); | ||||
if (LAC_CIPHER_IS_KASUMI(algorithm) && | if (pOpData->ivLenInBytes != LAC_CIPHER_KASUMI_F8_IV_LENGTH) { | ||||
(pOpData->ivLenInBytes != LAC_CIPHER_KASUMI_F8_IV_LENGTH)) { | |||||
LAC_INVALID_PARAM_LOG("invalid cipher IV size"); | LAC_INVALID_PARAM_LOG("invalid cipher IV size"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
*ppIvBuffer = pOpData->pIv; | *ppIvBuffer = pOpData->pIv; | ||||
} else if (LAC_CIPHER_IS_SNOW3G_UEA2(algorithm)) { | } break; | ||||
case CPA_CY_SYM_CIPHER_SNOW3G_UEA2: { | |||||
LAC_CHECK_NULL_PARAM(pOpData->pIv); | LAC_CHECK_NULL_PARAM(pOpData->pIv); | ||||
if (LAC_CIPHER_IS_SNOW3G_UEA2(algorithm) && | if (pOpData->ivLenInBytes != ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ) { | ||||
(pOpData->ivLenInBytes != ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ)) { | |||||
LAC_INVALID_PARAM_LOG("invalid cipher IV size"); | LAC_INVALID_PARAM_LOG("invalid cipher IV size"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
*ppIvBuffer = pOpData->pIv; | *ppIvBuffer = pOpData->pIv; | ||||
} else if (LAC_CIPHER_IS_ARC4(algorithm)) { | } break; | ||||
case CPA_CY_SYM_CIPHER_ARC4: { | |||||
if (ICP_QAT_FW_LA_PARTIAL_NONE == qatPacketType) { | if (ICP_QAT_FW_LA_PARTIAL_NONE == qatPacketType) { | ||||
/* For full packets, the initial ARC4 state is stored in | /* For full packets, the initial ARC4 state is stored in | ||||
* the | * the session descriptor. Use it directly. | ||||
* session descriptor. Use it directly. | |||||
*/ | */ | ||||
*ppIvBuffer = pSessionDesc->cipherARC4InitialState; | *ppIvBuffer = pSessionDesc->cipherARC4InitialState; | ||||
} else { | } else { | ||||
/* For partial packets, we maintain the running ARC4 | /* For partial packets, we maintain the running ARC4 | ||||
* state in | * state in dedicated buffer in the session descriptor | ||||
* dedicated buffer in the session descriptor | |||||
*/ | */ | ||||
*ppIvBuffer = pSessionDesc->cipherPartialOpState; | *ppIvBuffer = pSessionDesc->cipherPartialOpState; | ||||
if (ICP_QAT_FW_LA_PARTIAL_START == qatPacketType) { | if (ICP_QAT_FW_LA_PARTIAL_START == qatPacketType) { | ||||
/* if the previous partial state was full, then | /* if the previous partial state was full, then | ||||
* this is the | * this is the first partial in the sequence so | ||||
* first partial in the sequence so we need to | * we need to (re-)initialise the contents of | ||||
* (re-)initialise | * the state buffer using the initial state that | ||||
* the contents of the state buffer using the | * is stored in the session descriptor. But, we | ||||
* initial state | * have to be very careful here not to overwrite | ||||
* that is stored in the session descriptor. | * the cipherPartialOpState just yet in case | ||||
* But, we have to be | * there's a previous partial sequence in | ||||
* very careful here not to overwrite the | |||||
* cipherPartialOpState | |||||
* just yet in case there's a previous partial | |||||
* sequence in | |||||
* flight, so we defer the copy for now. This | * flight, so we defer the copy for now. This | ||||
* will be completed | * will be completed in the | ||||
* in the LacSymQueue_RequestSend() function | * LacSymQueue_RequestSend() function when clear | ||||
* when clear to send. | * to send. | ||||
*/ | */ | ||||
pCbCookie->updateSessionIvOnSend = CPA_TRUE; | pCbCookie->updateSessionIvOnSend = CPA_TRUE; | ||||
} | } | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_ZUC_EEA3(algorithm)) { | } break; | ||||
case CPA_CY_SYM_CIPHER_ZUC_EEA3: { | |||||
LAC_CHECK_NULL_PARAM(pOpData->pIv); | LAC_CHECK_NULL_PARAM(pOpData->pIv); | ||||
if (pOpData->ivLenInBytes != ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ) { | if (pOpData->ivLenInBytes != ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ) { | ||||
LAC_INVALID_PARAM_LOG("invalid cipher IV size"); | LAC_INVALID_PARAM_LOG("invalid cipher IV size"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
*ppIvBuffer = pOpData->pIv; | *ppIvBuffer = pOpData->pIv; | ||||
} else { | } break; | ||||
default: | |||||
*ppIvBuffer = NULL; | *ppIvBuffer = NULL; | ||||
} | } | ||||
return CPA_STATUS_SUCCESS; | return CPA_STATUS_SUCCESS; | ||||
} | } | ||||
CpaStatus | CpaStatus | ||||
LacCipher_SessionSetupDataCheck(const CpaCySymCipherSetupData *pCipherSetupData) | LacCipher_SessionSetupDataCheck(const CpaCySymCipherSetupData *pCipherSetupData, | ||||
Cpa32U capabilitiesMask) | |||||
{ | { | ||||
/* No key required for NULL algorithm */ | /* No key required for NULL algorithm */ | ||||
if (!LAC_CIPHER_IS_NULL(pCipherSetupData->cipherAlgorithm)) { | if (!LAC_CIPHER_IS_NULL(pCipherSetupData->cipherAlgorithm)) { | ||||
LAC_CHECK_NULL_PARAM(pCipherSetupData->pCipherKey); | LAC_CHECK_NULL_PARAM(pCipherSetupData->pCipherKey); | ||||
/* Check that algorithm and keys passed in are correct size */ | /* Check that algorithm and keys passed in are correct size */ | ||||
if (LAC_CIPHER_IS_ARC4(pCipherSetupData->cipherAlgorithm)) { | switch (pCipherSetupData->cipherAlgorithm) { | ||||
case CPA_CY_SYM_CIPHER_ARC4: | |||||
if (pCipherSetupData->cipherKeyLenInBytes > | if (pCipherSetupData->cipherKeyLenInBytes > | ||||
ICP_QAT_HW_ARC4_KEY_SZ) { | ICP_QAT_HW_ARC4_KEY_SZ) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid ARC4 cipher key length"); | "Invalid ARC4 cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_CCM( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_AES_CCM: | ||||
if (pCipherSetupData->cipherKeyLenInBytes != | if (!LAC_CIPHER_AES_V2(capabilitiesMask) && | ||||
pCipherSetupData->cipherKeyLenInBytes != | |||||
ICP_QAT_HW_AES_128_KEY_SZ) { | ICP_QAT_HW_AES_128_KEY_SZ) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid AES CCM cipher key length"); | "Invalid AES CCM cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_XTS_MODE( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_AES_XTS: | ||||
if ((pCipherSetupData->cipherKeyLenInBytes != | if ((pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_AES_128_XTS_KEY_SZ) && | ICP_QAT_HW_AES_128_XTS_KEY_SZ) && | ||||
(pCipherSetupData->cipherKeyLenInBytes != | (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_AES_256_XTS_KEY_SZ)) { | ICP_QAT_HW_AES_256_XTS_KEY_SZ) && | ||||
(pCipherSetupData->cipherKeyLenInBytes != | |||||
ICP_QAT_HW_UCS_AES_128_XTS_KEY_SZ) && | |||||
(pCipherSetupData->cipherKeyLenInBytes != | |||||
ICP_QAT_HW_UCS_AES_256_XTS_KEY_SZ)) { | |||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid AES XTS cipher key length"); | "Invalid AES XTS cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_AES( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_AES_ECB: | ||||
case CPA_CY_SYM_CIPHER_AES_CBC: | |||||
case CPA_CY_SYM_CIPHER_AES_CTR: | |||||
case CPA_CY_SYM_CIPHER_AES_GCM: | |||||
if ((pCipherSetupData->cipherKeyLenInBytes != | if ((pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_AES_128_KEY_SZ) && | ICP_QAT_HW_AES_128_KEY_SZ) && | ||||
(pCipherSetupData->cipherKeyLenInBytes != | (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_AES_192_KEY_SZ) && | ICP_QAT_HW_AES_192_KEY_SZ) && | ||||
(pCipherSetupData->cipherKeyLenInBytes != | (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_AES_256_KEY_SZ)) { | ICP_QAT_HW_AES_256_KEY_SZ)) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid AES cipher key length"); | "Invalid AES cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_AES_F8( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_AES_F8: | ||||
if ((pCipherSetupData->cipherKeyLenInBytes != | if ((pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_AES_128_F8_KEY_SZ) && | ICP_QAT_HW_AES_128_F8_KEY_SZ) && | ||||
(pCipherSetupData->cipherKeyLenInBytes != | (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_AES_192_F8_KEY_SZ) && | ICP_QAT_HW_AES_192_F8_KEY_SZ) && | ||||
(pCipherSetupData->cipherKeyLenInBytes != | (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_AES_256_F8_KEY_SZ)) { | ICP_QAT_HW_AES_256_F8_KEY_SZ)) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid AES cipher key length"); | "Invalid AES cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_DES( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_DES_ECB: | ||||
case CPA_CY_SYM_CIPHER_DES_CBC: | |||||
if (pCipherSetupData->cipherKeyLenInBytes != | if (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_DES_KEY_SZ) { | ICP_QAT_HW_DES_KEY_SZ) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid DES cipher key length"); | "Invalid DES cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_TRIPLE_DES( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_3DES_ECB: | ||||
case CPA_CY_SYM_CIPHER_3DES_CBC: | |||||
case CPA_CY_SYM_CIPHER_3DES_CTR: | |||||
if (pCipherSetupData->cipherKeyLenInBytes != | if (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_3DES_KEY_SZ) { | ICP_QAT_HW_3DES_KEY_SZ) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid Triple-DES cipher key length"); | "Invalid Triple-DES cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_KASUMI( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_KASUMI_F8: | ||||
/* QAT-FW only supports 128 bits Cipher Key size for | /* QAT-FW only supports 128 bits Cipher Key size for | ||||
* Kasumi F8 | * Kasumi F8 Ref: 3GPP TS 55.216 V6.2.0 */ | ||||
* Ref: 3GPP TS 55.216 V6.2.0 */ | |||||
if (pCipherSetupData->cipherKeyLenInBytes != | if (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_KASUMI_KEY_SZ) { | ICP_QAT_HW_KASUMI_KEY_SZ) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid Kasumi cipher key length"); | "Invalid Kasumi cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_SNOW3G_UEA2( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_SNOW3G_UEA2: | ||||
/* QAT-FW only supports 256 bits Cipher Key size for | /* QAT-FW only supports 256 bits Cipher Key size for | ||||
* Snow_3G */ | * Snow_3G */ | ||||
if (pCipherSetupData->cipherKeyLenInBytes != | if (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ) { | ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid Snow_3G cipher key length"); | "Invalid Snow_3G cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_ZUC_EEA3( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_ZUC_EEA3: | ||||
/* ZUC EEA3 */ | /* ZUC EEA3 */ | ||||
if (pCipherSetupData->cipherKeyLenInBytes != | if (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) { | ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid ZUC cipher key length"); | "Invalid ZUC cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_CHACHA( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_CHACHA: | ||||
if (pCipherSetupData->cipherKeyLenInBytes != | if (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_CHACHAPOLY_KEY_SZ) { | ICP_QAT_HW_CHACHAPOLY_KEY_SZ) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid CHACHAPOLY cipher key length"); | "Invalid CHACHAPOLY cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (LAC_CIPHER_IS_SM4( | break; | ||||
pCipherSetupData->cipherAlgorithm)) { | case CPA_CY_SYM_CIPHER_SM4_ECB: | ||||
case CPA_CY_SYM_CIPHER_SM4_CBC: | |||||
case CPA_CY_SYM_CIPHER_SM4_CTR: | |||||
if (pCipherSetupData->cipherKeyLenInBytes != | if (pCipherSetupData->cipherKeyLenInBytes != | ||||
ICP_QAT_HW_SM4_KEY_SZ) { | ICP_QAT_HW_SM4_KEY_SZ) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"Invalid SM4 cipher key length"); | "Invalid SM4 cipher key length"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else { | break; | ||||
default: | |||||
LAC_INVALID_PARAM_LOG("Invalid cipher algorithm"); | LAC_INVALID_PARAM_LOG("Invalid cipher algorithm"); | ||||
return CPA_STATUS_INVALID_PARAM; | return CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} | } | ||||
return CPA_STATUS_SUCCESS; | return CPA_STATUS_SUCCESS; | ||||
} | } | ||||
CpaStatus | CpaStatus | ||||
LacCipher_PerformParamCheck(CpaCySymCipherAlgorithm algorithm, | LacCipher_PerformParamCheck(CpaCySymCipherAlgorithm algorithm, | ||||
const CpaCySymOpData *pOpData, | const CpaCySymOpData *pOpData, | ||||
const Cpa64U packetLen) | const Cpa64U packetLen) | ||||
{ | { | ||||
CpaStatus status = CPA_STATUS_SUCCESS; | CpaStatus status = CPA_STATUS_SUCCESS; | ||||
/* The following check will cover the dstBuffer as well, since | /* The following check will cover the dstBuffer as well, since | ||||
* the dstBuffer cannot be smaller than the srcBuffer (checked in | * the dstBuffer cannot be smaller than the srcBuffer (checked in | ||||
* LacSymPerform_BufferParamCheck() called from LacSym_Perform()) | * LacSymPerform_BufferParamCheck() called from LacSym_Perform()) | ||||
*/ | */ | ||||
if ((pOpData->messageLenToCipherInBytes + | if ((pOpData->messageLenToCipherInBytes + | ||||
pOpData->cryptoStartSrcOffsetInBytes) > packetLen) { | pOpData->cryptoStartSrcOffsetInBytes) > packetLen) { | ||||
LAC_INVALID_PARAM_LOG("cipher len + offset greater than " | LAC_INVALID_PARAM_LOG("cipher len + offset greater than " | ||||
"srcBuffer packet len"); | "srcBuffer packet len"); | ||||
status = CPA_STATUS_INVALID_PARAM; | status = CPA_STATUS_INVALID_PARAM; | ||||
} | } else { | ||||
/* Perform algorithm-specific checks */ | |||||
if (CPA_STATUS_SUCCESS == status) { | switch (algorithm) { | ||||
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: | |||||
/* No action needed */ | |||||
break; | |||||
/* | /* | ||||
* XTS Mode allow for ciphers which are not multiples of | * XTS Mode allow for ciphers which are not multiples of | ||||
* the block size. | * the block size. | ||||
*/ | */ | ||||
/* Perform algorithm-specific checks */ | case CPA_CY_SYM_CIPHER_AES_XTS: | ||||
if (LAC_CIPHER_IS_XTS_MODE(algorithm) && | if ((pOpData->packetType == | ||||
((pOpData->packetType == CPA_CY_SYM_PACKET_TYPE_FULL) || | CPA_CY_SYM_PACKET_TYPE_FULL) || | ||||
(pOpData->packetType == | (pOpData->packetType == | ||||
CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL))) { | CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL)) { | ||||
/* | /* | ||||
* If this is the last of a partial request | * If this is the last of a partial request | ||||
*/ | */ | ||||
if (pOpData->messageLenToCipherInBytes < | if (pOpData->messageLenToCipherInBytes < | ||||
ICP_QAT_HW_AES_BLK_SZ) { | ICP_QAT_HW_AES_BLK_SZ) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"data size must be greater than block " | "data size must be greater than block" | ||||
"size for last XTS partial or XTS " | " size for last XTS partial or XTS " | ||||
"full packet"); | "full packet"); | ||||
status = CPA_STATUS_INVALID_PARAM; | status = CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} else if (!(LAC_CIPHER_IS_ARC4(algorithm) || | } | ||||
LAC_CIPHER_IS_CTR_MODE(algorithm) || | break; | ||||
LAC_CIPHER_IS_F8_MODE(algorithm) || | default: | ||||
LAC_CIPHER_IS_SNOW3G_UEA2(algorithm) || | |||||
LAC_CIPHER_IS_XTS_MODE(algorithm) || | |||||
LAC_CIPHER_IS_CHACHA(algorithm) || | |||||
LAC_CIPHER_IS_ZUC_EEA3(algorithm))) { | |||||
/* Mask & check below is based on assumption that block | /* Mask & check below is based on assumption that block | ||||
* size is | * size is a power of 2. If data size is not a multiple | ||||
* a power of 2. If data size is not a multiple of the | * of the block size, the "remainder" bits selected by | ||||
* block size, | * the mask be non-zero | ||||
* the "remainder" bits selected by the mask be non-zero | |||||
*/ | */ | ||||
if (pOpData->messageLenToCipherInBytes & | if (pOpData->messageLenToCipherInBytes & | ||||
(LacSymQat_CipherBlockSizeBytesGet(algorithm) - | (LacSymQat_CipherBlockSizeBytesGet(algorithm) - | ||||
1)) { | 1)) { | ||||
LAC_INVALID_PARAM_LOG( | LAC_INVALID_PARAM_LOG( | ||||
"data size must be block size multiple"); | "data size must be block size" | ||||
" multiple"); | |||||
status = CPA_STATUS_INVALID_PARAM; | status = CPA_STATUS_INVALID_PARAM; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return status; | return status; | ||||
} | } | ||||
Cpa32U | |||||
LacCipher_GetCipherSliceType(sal_crypto_service_t *pService, | |||||
CpaCySymCipherAlgorithm cipherAlgorithm, | |||||
CpaCySymHashAlgorithm hashAlgorithm) | |||||
{ | |||||
Cpa32U sliceType = ICP_QAT_FW_LA_USE_LEGACY_SLICE_TYPE; | |||||
Cpa32U capabilitiesMask = | |||||
pService->generic_service_info.capabilitiesMask; | |||||
/* UCS Slice is supproted only in Gen4 */ | |||||
if (isCyGen4x(pService)) { | |||||
if (LAC_CIPHER_IS_XTS_MODE(cipherAlgorithm) || | |||||
LAC_CIPHER_IS_CHACHA(cipherAlgorithm) || | |||||
LAC_CIPHER_IS_GCM(cipherAlgorithm)) { | |||||
sliceType = ICP_QAT_FW_LA_USE_UCS_SLICE_TYPE; | |||||
} else if (LAC_CIPHER_IS_CCM(cipherAlgorithm) && | |||||
LAC_CIPHER_AES_V2(capabilitiesMask)) { | |||||
sliceType = ICP_QAT_FW_LA_USE_LEGACY_SLICE_TYPE; | |||||
} else if (LAC_CIPHER_IS_AES(cipherAlgorithm) && | |||||
LAC_CIPHER_IS_CTR_MODE(cipherAlgorithm)) { | |||||
sliceType = ICP_QAT_FW_LA_USE_UCS_SLICE_TYPE; | |||||
} | |||||
} | |||||
return sliceType; | |||||
} |