#include "cpa.h"
#include "cpa_cy_sym.h"
#include "icp_accel_devices.h"
#include "icp_adf_init.h"
#include "icp_adf_transport.h"
#include "icp_adf_debug.h"
#include "qat_utils.h"
#include "lac_mem.h"
#include "lac_sym.h"
#include "lac_log.h"
#include "lac_mem_pools.h"
#include "lac_list.h"
#include "lac_sym_hash_defs.h"
#include "lac_sym_qat_hash_defs_lookup.h"
#include "lac_sal_types_crypto.h"
#include "lac_sal.h"
#include "lac_session.h"
#include "lac_sym_hash_precomputes.h"
static CpaStatus
LacSymHash_Compute(CpaCySymHashAlgorithm hashAlgorithm,
lac_sym_qat_hash_alg_info_t *pHashAlgInfo,
Cpa8U *in,
Cpa8U *out)
{
CpaStatus status = CPA_STATUS_FAIL;
Cpa32U i = 0;
switch (hashAlgorithm) {
case CPA_CY_SYM_HASH_MD5:
if (CPA_STATUS_SUCCESS != qatUtilsHashMD5(in, out)) {
LAC_LOG_ERROR("qatUtilsHashMD5 Failed\n");
return status;
}
status = CPA_STATUS_SUCCESS;
break;
case CPA_CY_SYM_HASH_SHA1:
if (CPA_STATUS_SUCCESS != qatUtilsHashSHA1(in, out)) {
LAC_LOG_ERROR("qatUtilsHashSHA1 Failed\n");
return status;
}
for (i = 0; i < LAC_BYTES_TO_LONGWORDS(pHashAlgInfo->stateSize);
i++) {
((Cpa32U *)(out))[i] =
LAC_MEM_WR_32(((Cpa32U *)(out))[i]);
}
status = CPA_STATUS_SUCCESS;
break;
case CPA_CY_SYM_HASH_SHA224:
if (CPA_STATUS_SUCCESS != qatUtilsHashSHA224(in, out)) {
LAC_LOG_ERROR("qatUtilsHashSHA224 Failed\n");
return status;
}
for (i = 0; i < LAC_BYTES_TO_LONGWORDS(pHashAlgInfo->stateSize);
i++) {
((Cpa32U *)(out))[i] =
LAC_MEM_WR_32(((Cpa32U *)(out))[i]);
}
status = CPA_STATUS_SUCCESS;
break;
case CPA_CY_SYM_HASH_SHA256:
if (CPA_STATUS_SUCCESS != qatUtilsHashSHA256(in, out)) {
LAC_LOG_ERROR("qatUtilsHashSHA256 Failed\n");
return status;
}
for (i = 0; i < LAC_BYTES_TO_LONGWORDS(pHashAlgInfo->stateSize);
i++) {
((Cpa32U *)(out))[i] =
LAC_MEM_WR_32(((Cpa32U *)(out))[i]);
}
status = CPA_STATUS_SUCCESS;
break;
case CPA_CY_SYM_HASH_SHA384:
if (CPA_STATUS_SUCCESS != qatUtilsHashSHA384(in, out)) {
LAC_LOG_ERROR("qatUtilsHashSHA384 Failed\n");
return status;
}
for (i = 0; i < LAC_BYTES_TO_QUADWORDS(pHashAlgInfo->stateSize);
i++) {
((Cpa64U *)(out))[i] =
LAC_MEM_WR_64(((Cpa64U *)(out))[i]);
}
status = CPA_STATUS_SUCCESS;
break;
case CPA_CY_SYM_HASH_SHA512:
if (CPA_STATUS_SUCCESS != qatUtilsHashSHA512(in, out)) {
LAC_LOG_ERROR("qatUtilsHashSHA512 Failed\n");
return status;
}
for (i = 0; i < LAC_BYTES_TO_QUADWORDS(pHashAlgInfo->stateSize);
i++) {
((Cpa64U *)(out))[i] =
LAC_MEM_WR_64(((Cpa64U *)(out))[i]);
}
status = CPA_STATUS_SUCCESS;
break;
default:
return CPA_STATUS_INVALID_PARAM;
}
return status;
}
CpaStatus
LacSymHash_HmacPreComputes(CpaInstanceHandle instanceHandle,
CpaCySymHashAlgorithm hashAlgorithm,
Cpa32U authKeyLenInBytes,
Cpa8U *pAuthKey,
Cpa8U *pWorkingMemory,
Cpa8U *pState1,
Cpa8U *pState2,
lac_hash_precompute_done_cb_t callbackFn,
void *pCallbackTag)
{
Cpa8U *pIpadData = NULL;
Cpa8U *pOpadData = NULL;
CpaStatus status = CPA_STATUS_FAIL;
lac_sym_hash_precomp_op_data_t *pHmacIpadOpData =
(lac_sym_hash_precomp_op_data_t *)pWorkingMemory;
lac_sym_hash_precomp_op_data_t *pHmacOpadOpData = pHmacIpadOpData + 1;
lac_sym_hash_hmac_precomp_qat_t *pHmacIpadQatData =
&pHmacIpadOpData->u.hmacQatData;
lac_sym_hash_hmac_precomp_qat_t *pHmacOpadQatData =
&pHmacOpadOpData->u.hmacQatData;
lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
Cpa32U i = 0;
Cpa32U padLenBytes = 0;
LacSymQat_HashAlgLookupGet(instanceHandle,
hashAlgorithm,
&pHashAlgInfo);
pHmacIpadOpData->stateSize = pHashAlgInfo->stateSize;
pHmacOpadOpData->stateSize = pHashAlgInfo->stateSize;
if (authKeyLenInBytes > 0) {
memcpy(pHmacIpadQatData->data, pAuthKey, authKeyLenInBytes);
memcpy(pHmacOpadQatData->data, pAuthKey, authKeyLenInBytes);
}
padLenBytes = pHashAlgInfo->blockLength - authKeyLenInBytes;
if (padLenBytes > 0) {
LAC_OS_BZERO(pHmacIpadQatData->data + authKeyLenInBytes,
padLenBytes);
LAC_OS_BZERO(pHmacOpadQatData->data + authKeyLenInBytes,
padLenBytes);
}
for (i = 0; i < pHashAlgInfo->blockLength; i++) {
Cpa8U *ipad = pHmacIpadQatData->data + i;
Cpa8U *opad = pHmacOpadQatData->data + i;
*ipad ^= LAC_HASH_IPAD_BYTE;
*opad ^= LAC_HASH_OPAD_BYTE;
}
pIpadData = (Cpa8U *)pHmacIpadQatData->data;
pOpadData = (Cpa8U *)pHmacOpadQatData->data;
status = LacSymHash_Compute(hashAlgorithm,
pHashAlgInfo,
(Cpa8U *)pIpadData,
pState1);
if (CPA_STATUS_SUCCESS == status) {
status = LacSymHash_Compute(hashAlgorithm,
pHashAlgInfo,
(Cpa8U *)pOpadData,
pState2);
}
if (CPA_STATUS_SUCCESS == status) {
callbackFn(pCallbackTag);
}
return status;
}
CpaStatus
LacSymHash_AesECBPreCompute(CpaInstanceHandle instanceHandle,
CpaCySymHashAlgorithm hashAlgorithm,
Cpa32U authKeyLenInBytes,
Cpa8U *pAuthKey,
Cpa8U *pWorkingMemory,
Cpa8U *pState,
lac_hash_precompute_done_cb_t callbackFn,
void *pCallbackTag)
{
CpaStatus status = CPA_STATUS_FAIL;
Cpa32U stateSize = 0, x = 0;
lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
if (CPA_CY_SYM_HASH_AES_XCBC == hashAlgorithm) {
Cpa8U *in = pWorkingMemory;
Cpa8U *out = pState;
LacSymQat_HashAlgLookupGet(instanceHandle,
hashAlgorithm,
&pHashAlgInfo);
stateSize = pHashAlgInfo->stateSize;
memcpy(pWorkingMemory, pHashAlgInfo->initState, stateSize);
for (x = 0; x < LAC_HASH_XCBC_PRECOMP_KEY_NUM; x++) {
if (CPA_STATUS_SUCCESS !=
qatUtilsAESEncrypt(
pAuthKey, authKeyLenInBytes, in, out)) {
return status;
}
in += LAC_HASH_XCBC_MAC_BLOCK_SIZE;
out += LAC_HASH_XCBC_MAC_BLOCK_SIZE;
}
status = CPA_STATUS_SUCCESS;
} else if (CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) {
Cpa8U *out = pState;
Cpa8U k1[LAC_HASH_CMAC_BLOCK_SIZE],
k2[LAC_HASH_CMAC_BLOCK_SIZE];
Cpa8U *ptr = NULL, i = 0;
stateSize = LAC_HASH_CMAC_BLOCK_SIZE;
LacSymQat_HashAlgLookupGet(instanceHandle,
hashAlgorithm,
&pHashAlgInfo);
memcpy(out, pHashAlgInfo->initState, stateSize);
memcpy(out, pAuthKey, authKeyLenInBytes);
out += LAC_HASH_CMAC_BLOCK_SIZE;
for (x = 0; x < LAC_HASH_XCBC_PRECOMP_KEY_NUM - 1; x++) {
if (CPA_STATUS_SUCCESS !=
qatUtilsAESEncrypt(
pAuthKey, authKeyLenInBytes, out, out)) {
return status;
}
out += LAC_HASH_CMAC_BLOCK_SIZE;
}
ptr = pState + LAC_HASH_CMAC_BLOCK_SIZE;
for (i = 0; i < LAC_HASH_CMAC_BLOCK_SIZE; i++, ptr++) {
k1[i] = (*ptr) << 1;
if (i != 0) {
k1[i - 1] |=
(*ptr) >> (LAC_NUM_BITS_IN_BYTE - 1);
}
if (i + 1 == LAC_HASH_CMAC_BLOCK_SIZE) {
if ((*(pState + LAC_HASH_CMAC_BLOCK_SIZE)) &
LAC_SYM_HASH_MSBIT_MASK) {
k1[i] ^= LAC_SYM_AES_CMAC_RB_128;
}
}
}
for (i = 0; i < LAC_HASH_CMAC_BLOCK_SIZE; i++) {
k2[i] = (k1[i]) << 1;
if (i != 0) {
k2[i - 1] |=
(k1[i]) >> (LAC_NUM_BITS_IN_BYTE - 1);
}
if (i + 1 == LAC_HASH_CMAC_BLOCK_SIZE) {
if (k1[0] & LAC_SYM_HASH_MSBIT_MASK) {
k2[i] ^= LAC_SYM_AES_CMAC_RB_128;
}
}
}
ptr = pState + LAC_HASH_CMAC_BLOCK_SIZE;
memcpy(ptr, k1, LAC_HASH_CMAC_BLOCK_SIZE);
ptr += LAC_HASH_CMAC_BLOCK_SIZE;
memcpy(ptr, k2, LAC_HASH_CMAC_BLOCK_SIZE);
status = CPA_STATUS_SUCCESS;
} else if (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm ||
CPA_CY_SYM_HASH_AES_GMAC == hashAlgorithm) {
Cpa8U *in = pWorkingMemory;
Cpa8U *out = pState;
LAC_OS_BZERO(pWorkingMemory, ICP_QAT_HW_GALOIS_H_SZ);
if (CPA_STATUS_SUCCESS !=
qatUtilsAESEncrypt(pAuthKey, authKeyLenInBytes, in, out)) {
return status;
}
status = CPA_STATUS_SUCCESS;
} else {
return CPA_STATUS_INVALID_PARAM;
}
callbackFn(pCallbackTag);
return status;
}
CpaStatus
LacSymHash_HmacPrecompInit(CpaInstanceHandle instanceHandle)
{
CpaStatus status = CPA_STATUS_SUCCESS;
return status;
}
void
LacSymHash_HmacPrecompShutdown(CpaInstanceHandle instanceHandle)
{
return;
}