#include "cpa.h"
#include "cpa_cy_key.h"
#include "cpa_cy_im.h"
#include "icp_accel_devices.h"
#include "icp_adf_debug.h"
#include "icp_adf_init.h"
#include "icp_adf_transport.h"
#include "qat_utils.h"
#include "lac_log.h"
#include "lac_hooks.h"
#include "lac_sym.h"
#include "lac_sym_qat_hash_defs_lookup.h"
#include "lac_sym_qat.h"
#include "lac_sal.h"
#include "lac_sym_key.h"
#include "lac_sal_types_crypto.h"
#include "sal_service_state.h"
#include "lac_sym_qat_key.h"
#include "lac_sym_hash_defs.h"
#include "sal_statistics.h"
#define LAC_KEY_NUM_STATS (sizeof(CpaCyKeyGenStats64) / sizeof(Cpa64U))
#define LAC_KEY_STAT_INC(statistic, instanceHandle) \
do { \
sal_crypto_service_t *pService = NULL; \
pService = (sal_crypto_service_t *)instanceHandle; \
if (CPA_TRUE == \
pService->generic_service_info.stats \
->bKeyGenStatsEnabled) { \
qatUtilsAtomicInc( \
&pService \
->pLacKeyStats[offsetof(CpaCyKeyGenStats64, \
statistic) / \
sizeof(Cpa64U)]); \
} \
} while (0)
#define LAC_KEY_STATS32_GET(keyStats, instanceHandle) \
do { \
int i; \
sal_crypto_service_t *pService = \
(sal_crypto_service_t *)instanceHandle; \
for (i = 0; i < LAC_KEY_NUM_STATS; i++) { \
((Cpa32U *)&(keyStats))[i] = \
(Cpa32U)qatUtilsAtomicGet( \
&pService->pLacKeyStats[i]); \
} \
} while (0)
#define LAC_KEY_STATS64_GET(keyStats, instanceHandle) \
do { \
int i; \
sal_crypto_service_t *pService = \
(sal_crypto_service_t *)instanceHandle; \
for (i = 0; i < LAC_KEY_NUM_STATS; i++) { \
((Cpa64U *)&(keyStats))[i] = \
qatUtilsAtomicGet(&pService->pLacKeyStats[i]); \
} \
} while (0)
#define IS_HKDF_UNSUPPORTED(cmdId, hkdfSupported) \
((ICP_QAT_FW_LA_CMD_HKDF_EXTRACT <= cmdId && \
ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL >= cmdId) && \
!hkdfSupported)
const static Cpa8U key256[HKDF_SUB_LABEL_KEY_LENGTH] = { 0, 16, 9, 't',
'l', 's', '1', '3',
' ', 'k', 'e', 'y',
0 };
const static Cpa8U key384[HKDF_SUB_LABEL_KEY_LENGTH] = { 0, 32, 9, 't',
'l', 's', '1', '3',
' ', 'k', 'e', 'y',
0 };
const static Cpa8U keyChaChaPoly[HKDF_SUB_LABEL_KEY_LENGTH] = { 0, 32, 9,
't', 'l', 's',
'1', '3', ' ',
'k', 'e', 'y',
0 };
const static Cpa8U iv256[HKDF_SUB_LABEL_IV_LENGTH] = { 0, 12, 8, 't',
'l', 's', '1', '3',
' ', 'i', 'v', 0 };
const static Cpa8U iv384[HKDF_SUB_LABEL_IV_LENGTH] = { 0, 12, 8, 't',
'l', 's', '1', '3',
' ', 'i', 'v', 0 };
const static Cpa8U resumption256[HKDF_SUB_LABEL_RESUMPTION_LENGTH] =
{ 0, 32, 16, 't', 'l', 's', '1', '3', ' ', 'r',
'e', 's', 'u', 'm', 'p', 't', 'i', 'o', 'n', 0 };
const static Cpa8U resumption384[HKDF_SUB_LABEL_RESUMPTION_LENGTH] =
{ 0, 48, 16, 't', 'l', 's', '1', '3', ' ', 'r',
'e', 's', 'u', 'm', 'p', 't', 'i', 'o', 'n', 0 };
const static Cpa8U finished256[HKDF_SUB_LABEL_FINISHED_LENGTH] =
{ 0, 32, 14, 't', 'l', 's', '1', '3', ' ',
'f', 'i', 'n', 'i', 's', 'h', 'e', 'd', 0 };
const static Cpa8U finished384[HKDF_SUB_LABEL_FINISHED_LENGTH] =
{ 0, 48, 14, 't', 'l', 's', '1', '3', ' ',
'f', 'i', 'n', 'i', 's', 'h', 'e', 'd', 0 };
typedef enum {
LAC_KEY_REQUESTS = 0,
LAC_KEY_REQUEST_ERRORS,
LAC_KEY_COMPLETED,
LAC_KEY_COMPLETED_ERRORS
} lac_key_stat_type_t;
static void
LacSymKey_MgfHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
void *pOpaqueData,
icp_qat_fw_comn_flags cmnRespFlags);
static CpaStatus
LacSymKey_MgfSync(const CpaInstanceHandle instanceHandle,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
const void *pKeyGenMgfOpData,
CpaFlatBuffer *pGeneratedMaskBuffer,
CpaBoolean bIsExtRequest);
static void
LacSymKey_SslTlsHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
void *pOpaqueData,
icp_qat_fw_comn_flags cmnRespFlags);
static CpaStatus
LacSymKey_SslTlsSync(CpaInstanceHandle instanceHandle,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
icp_qat_fw_la_cmd_id_t lacCmdId,
void *pKeyGenSslTlsOpData,
Cpa8U hashAlgorithm,
CpaFlatBuffer *pKeyGenOutpuData);
static CpaInstanceHandle
LacKey_GetHandle(CpaInstanceHandle instanceHandle_in)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
return instanceHandle;
}
static CpaStatus
LacSymKey_KeyGenSslTls_GenCommon(CpaInstanceHandle instanceHandle,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
icp_qat_fw_la_cmd_id_t lacCmdId,
void *pKeyGenSslTlsOpData,
Cpa8U hashAlgorithm,
CpaFlatBuffer *pKeyGenOutputData);
static void
LacKey_StatsInc(icp_qat_fw_la_cmd_id_t lacCmdId,
lac_key_stat_type_t statType,
CpaInstanceHandle instanceHandle)
{
if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
switch (statType) {
case LAC_KEY_REQUESTS:
LAC_KEY_STAT_INC(numSslKeyGenRequests, instanceHandle);
break;
case LAC_KEY_REQUEST_ERRORS:
LAC_KEY_STAT_INC(numSslKeyGenRequestErrors,
instanceHandle);
break;
case LAC_KEY_COMPLETED:
LAC_KEY_STAT_INC(numSslKeyGenCompleted, instanceHandle);
break;
case LAC_KEY_COMPLETED_ERRORS:
LAC_KEY_STAT_INC(numSslKeyGenCompletedErrors,
instanceHandle);
break;
default:
QAT_UTILS_LOG("Invalid statistics type\n");
break;
}
} else
{
switch (statType) {
case LAC_KEY_REQUESTS:
LAC_KEY_STAT_INC(numTlsKeyGenRequests, instanceHandle);
break;
case LAC_KEY_REQUEST_ERRORS:
LAC_KEY_STAT_INC(numTlsKeyGenRequestErrors,
instanceHandle);
break;
case LAC_KEY_COMPLETED:
LAC_KEY_STAT_INC(numTlsKeyGenCompleted, instanceHandle);
break;
case LAC_KEY_COMPLETED_ERRORS:
LAC_KEY_STAT_INC(numTlsKeyGenCompletedErrors,
instanceHandle);
break;
default:
QAT_UTILS_LOG("Invalid statistics type\n");
break;
}
}
}
void
LacKeygen_StatsShow(CpaInstanceHandle instanceHandle)
{
CpaCyKeyGenStats64 keyStats = { 0 };
LAC_KEY_STATS64_GET(keyStats, instanceHandle);
QAT_UTILS_LOG(SEPARATOR BORDER
" Key Stats: " BORDER
"\n" SEPARATOR);
QAT_UTILS_LOG(BORDER " SSL Key Requests: %16llu " BORDER
"\n" BORDER
" SSL Key Request Errors: %16llu " BORDER
"\n" BORDER
" SSL Key Completed %16llu " BORDER
"\n" BORDER
" SSL Key Complete Errors: %16llu " BORDER
"\n" SEPARATOR,
(unsigned long long)keyStats.numSslKeyGenRequests,
(unsigned long long)keyStats.numSslKeyGenRequestErrors,
(unsigned long long)keyStats.numSslKeyGenCompleted,
(unsigned long long)keyStats.numSslKeyGenCompletedErrors);
QAT_UTILS_LOG(BORDER " TLS Key Requests: %16llu " BORDER
"\n" BORDER
" TLS Key Request Errors: %16llu " BORDER
"\n" BORDER
" TLS Key Completed %16llu " BORDER
"\n" BORDER
" TLS Key Complete Errors: %16llu " BORDER
"\n" SEPARATOR,
(unsigned long long)keyStats.numTlsKeyGenRequests,
(unsigned long long)keyStats.numTlsKeyGenRequestErrors,
(unsigned long long)keyStats.numTlsKeyGenCompleted,
(unsigned long long)keyStats.numTlsKeyGenCompletedErrors);
QAT_UTILS_LOG(BORDER " MGF Key Requests: %16llu " BORDER
"\n" BORDER
" MGF Key Request Errors: %16llu " BORDER
"\n" BORDER
" MGF Key Completed %16llu " BORDER
"\n" BORDER
" MGF Key Complete Errors: %16llu " BORDER
"\n" SEPARATOR,
(unsigned long long)keyStats.numMgfKeyGenRequests,
(unsigned long long)keyStats.numMgfKeyGenRequestErrors,
(unsigned long long)keyStats.numMgfKeyGenCompleted,
(unsigned long long)keyStats.numMgfKeyGenCompletedErrors);
}
CpaStatus
cpaCyKeyGenQueryStats(CpaInstanceHandle instanceHandle_in,
struct _CpaCyKeyGenStats *pSymKeyStats)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
LAC_CHECK_NULL_PARAM(pSymKeyStats);
SAL_RUNNING_CHECK(instanceHandle);
LAC_KEY_STATS32_GET(*pSymKeyStats, instanceHandle);
return CPA_STATUS_SUCCESS;
}
CpaStatus
cpaCyKeyGenQueryStats64(CpaInstanceHandle instanceHandle_in,
CpaCyKeyGenStats64 *pSymKeyStats)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
LAC_CHECK_NULL_PARAM(pSymKeyStats);
SAL_RUNNING_CHECK(instanceHandle);
LAC_KEY_STATS64_GET(*pSymKeyStats, instanceHandle);
return CPA_STATUS_SUCCESS;
}
static Cpa32U
getDigestSizeFromHashAlgo(CpaCySymHashAlgorithm hashAlgorithm)
{
switch (hashAlgorithm) {
case CPA_CY_SYM_HASH_SHA256:
return LAC_HASH_SHA256_DIGEST_SIZE;
case CPA_CY_SYM_HASH_SHA384:
return LAC_HASH_SHA384_DIGEST_SIZE;
case CPA_CY_SYM_HASH_SHA512:
return LAC_HASH_SHA512_DIGEST_SIZE;
case CPA_CY_SYM_HASH_SM3:
return LAC_HASH_SM3_DIGEST_SIZE;
default:
return 0;
}
}
static CpaCySymHashAlgorithm
getHashAlgorithmFromCipherSuiteHKDF(CpaCyKeyHKDFCipherSuite cipherSuite)
{
switch (cipherSuite) {
case CPA_CY_HKDF_TLS_AES_128_GCM_SHA256:
case CPA_CY_HKDF_TLS_CHACHA20_POLY1305_SHA256:
case CPA_CY_HKDF_TLS_AES_128_CCM_SHA256:
case CPA_CY_HKDF_TLS_AES_128_CCM_8_SHA256:
return CPA_CY_SYM_HASH_SHA256;
case CPA_CY_HKDF_TLS_AES_256_GCM_SHA384:
return CPA_CY_SYM_HASH_SHA384;
default:
return 0;
}
}
static const Cpa32U cipherSuiteHKDFHashSizes
[LAC_KEY_HKDF_CIPHERS_MAX][LAC_KEY_HKDF_SUBLABELS_MAX] = {
{},
{ 32, 16, 12, 32, 32 },
{ 48, 32, 12, 48, 48 },
{ 32, 32, 12, 32, 32 },
{ 32, 16, 12, 32, 32 },
{ 32, 16, 12, 32, 32 }
};
static void
LacSymKey_MgfHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
void *pOpaqueData,
icp_qat_fw_comn_flags cmnRespFlags)
{
CpaCyKeyGenMgfOpData *pMgfOpData = NULL;
lac_sym_key_cookie_t *pCookie = NULL;
CpaCyGenFlatBufCbFunc pKeyGenMgfCb = NULL;
void *pCallbackTag = NULL;
CpaFlatBuffer *pGeneratedKeyBuffer = NULL;
CpaStatus status = CPA_STATUS_SUCCESS;
CpaBoolean respStatusOk =
(ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(cmnRespFlags)) ?
CPA_TRUE :
CPA_FALSE;
pCookie = (lac_sym_key_cookie_t *)pOpaqueData;
if (CPA_TRUE == respStatusOk) {
status = CPA_STATUS_SUCCESS;
LAC_KEY_STAT_INC(numMgfKeyGenCompleted,
pCookie->instanceHandle);
} else {
status = CPA_STATUS_FAIL;
LAC_KEY_STAT_INC(numMgfKeyGenCompletedErrors,
pCookie->instanceHandle);
}
pKeyGenMgfCb = (CpaCyGenFlatBufCbFunc)(pCookie->pKeyGenCb);
pMgfOpData = pCookie->pKeyGenOpData;
pCallbackTag = pCookie->pCallbackTag;
pGeneratedKeyBuffer = pCookie->pKeyGenOutputData;
Lac_MemPoolEntryFree(pCookie);
(*pKeyGenMgfCb)(pCallbackTag, status, pMgfOpData, pGeneratedKeyBuffer);
}
static CpaStatus
LacSymKey_MgfSync(const CpaInstanceHandle instanceHandle,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
const void *pKeyGenMgfOpData,
CpaFlatBuffer *pGeneratedMaskBuffer,
CpaBoolean bIsExtRequest)
{
CpaStatus status = CPA_STATUS_SUCCESS;
lac_sync_op_data_t *pSyncCallbackData = NULL;
status = LacSync_CreateSyncCookie(&pSyncCallbackData);
if (CPA_STATUS_SUCCESS == status) {
if (CPA_TRUE == bIsExtRequest) {
status = cpaCyKeyGenMgfExt(
instanceHandle,
LacSync_GenFlatBufCb,
pSyncCallbackData,
(const CpaCyKeyGenMgfOpDataExt *)pKeyGenMgfOpData,
pGeneratedMaskBuffer);
} else {
status = cpaCyKeyGenMgf(instanceHandle,
LacSync_GenFlatBufCb,
pSyncCallbackData,
(const CpaCyKeyGenMgfOpData *)
pKeyGenMgfOpData,
pGeneratedMaskBuffer);
}
} else {
LAC_KEY_STAT_INC(numMgfKeyGenRequestErrors, instanceHandle);
return status;
}
if (CPA_STATUS_SUCCESS == status) {
CpaStatus syncStatus = CPA_STATUS_SUCCESS;
syncStatus =
LacSync_WaitForCallback(pSyncCallbackData,
LAC_SYM_SYNC_CALLBACK_TIMEOUT,
&status,
NULL);
if (CPA_STATUS_SUCCESS != syncStatus) {
LAC_KEY_STAT_INC(numMgfKeyGenCompletedErrors,
instanceHandle);
LAC_LOG_ERROR("Callback timed out");
status = syncStatus;
}
} else {
LacSync_SetSyncCookieComplete(pSyncCallbackData);
}
LacSync_DestroySyncCookie(&pSyncCallbackData);
return status;
}
static CpaStatus
LacSymKey_MgfCommon(const CpaInstanceHandle instanceHandle,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
const void *pOpData,
const CpaCyKeyGenMgfOpData *pKeyGenMgfOpData,
CpaFlatBuffer *pGeneratedMaskBuffer,
CpaCySymHashAlgorithm hashAlgorithm)
{
CpaStatus status = CPA_STATUS_SUCCESS;
icp_qat_fw_la_bulk_req_t keyGenReq = { { 0 } };
icp_qat_la_bulk_req_hdr_t keyGenReqHdr = { { 0 } };
icp_qat_fw_la_key_gen_common_t keyGenReqMid = { { 0 } };
icp_qat_la_bulk_req_ftr_t keyGenReqFtr = { { { 0 } } };
Cpa8U *pMsgDummy = NULL;
Cpa8U *pCacheDummyHdr = NULL;
Cpa8U *pCacheDummyMid = NULL;
Cpa8U *pCacheDummyFtr = NULL;
sal_qat_content_desc_info_t contentDescInfo = { 0 };
lac_sym_key_cookie_t *pCookie = NULL;
lac_sym_cookie_t *pSymCookie = NULL;
sal_crypto_service_t *pService = NULL;
Cpa64U inputPhysAddr = 0;
Cpa64U outputPhysAddr = 0;
CpaCySymHashSetupData hashSetupData = { 0 };
Cpa32U hashBlkSizeInBytes = 0;
lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
icp_qat_fw_serv_specif_flags laCmdFlags = 0;
icp_qat_fw_comn_flags cmnRequestFlags =
ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_PTR_TYPE_FLAT,
QAT_COMN_CD_FLD_TYPE_64BIT_ADR);
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));
SAL_RUNNING_CHECK(instanceHandle);
LAC_CHECK_NULL_PARAM(pOpData);
LAC_CHECK_NULL_PARAM(pKeyGenMgfOpData);
LAC_CHECK_NULL_PARAM(pGeneratedMaskBuffer);
LAC_CHECK_NULL_PARAM(pGeneratedMaskBuffer->pData);
LAC_CHECK_NULL_PARAM(pKeyGenMgfOpData->seedBuffer.pData);
if (pKeyGenMgfOpData->seedBuffer.dataLenInBytes >
ICP_QAT_FW_LA_MGF_SEED_LEN_MAX) {
LAC_INVALID_PARAM_LOG("seedBuffer.dataLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
if (pKeyGenMgfOpData->maskLenInBytes > ICP_QAT_FW_LA_MGF_MASK_LEN_MAX) {
LAC_INVALID_PARAM_LOG("maskLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
if (pKeyGenMgfOpData->maskLenInBytes >
pGeneratedMaskBuffer->dataLenInBytes) {
LAC_INVALID_PARAM_LOG("pGeneratedMaskBuffer.dataLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
LacSymQat_HashAlgLookupGet(instanceHandle,
hashAlgorithm,
&pHashAlgInfo);
pCookie = (lac_sym_key_cookie_t *)Lac_MemPoolEntryAlloc(
pService->lac_sym_cookie_pool);
if (NULL == pCookie) {
LAC_LOG_ERROR("Cannot get mem pool entry");
status = CPA_STATUS_RESOURCE;
} else if ((void *)CPA_STATUS_RETRY == pCookie) {
pCookie = NULL;
status = CPA_STATUS_RETRY;
} else {
pSymCookie = (lac_sym_cookie_t *)pCookie;
}
if (CPA_STATUS_SUCCESS == status) {
pCookie->instanceHandle = instanceHandle;
pCookie->pCallbackTag = pCallbackTag;
pCookie->pKeyGenOpData = (void *)LAC_CONST_PTR_CAST(pOpData);
pCookie->pKeyGenCb = pKeyGenCb;
pCookie->pKeyGenOutputData = pGeneratedMaskBuffer;
hashSetupData.hashAlgorithm = hashAlgorithm;
hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
hashSetupData.digestResultLenInBytes =
pHashAlgInfo->digestLength;
LacSymQat_HashContentDescInit(
&(keyGenReqFtr),
instanceHandle,
&hashSetupData,
(Cpa8U *)pCookie->contentDesc,
LAC_SYM_KEY_NO_HASH_BLK_OFFSET_QW,
ICP_QAT_FW_SLICE_DRAM_WR,
ICP_QAT_HW_AUTH_MODE0,
CPA_FALSE,
CPA_FALSE,
CPA_FALSE,
NULL,
&hashBlkSizeInBytes);
LacSymQat_KeyMgfRequestPopulate(
&keyGenReqHdr,
&keyGenReqMid,
pKeyGenMgfOpData->seedBuffer.dataLenInBytes,
pKeyGenMgfOpData->maskLenInBytes,
(Cpa8U)pHashAlgInfo->digestLength);
contentDescInfo.pData = pCookie->contentDesc;
contentDescInfo.hardwareSetupBlockPhys =
LAC_MEM_CAST_PTR_TO_UINT64(
pSymCookie->keyContentDescPhyAddr);
contentDescInfo.hwBlkSzQuadWords =
LAC_BYTES_TO_QUADWORDS(hashBlkSizeInBytes);
inputPhysAddr =
LAC_MEM_CAST_PTR_TO_UINT64(LAC_OS_VIRT_TO_PHYS_EXTERNAL(
pService->generic_service_info,
pKeyGenMgfOpData->seedBuffer.pData));
if (inputPhysAddr == 0) {
LAC_LOG_ERROR(
"Unable to get the seed buffer physical address");
status = CPA_STATUS_FAIL;
}
outputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info,
pGeneratedMaskBuffer->pData));
if (outputPhysAddr == 0) {
LAC_LOG_ERROR(
"Unable to get the physical address of the mask");
status = CPA_STATUS_FAIL;
}
}
if (CPA_STATUS_SUCCESS == status) {
pMsgDummy = (Cpa8U *)&(keyGenReq);
pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
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_MID_IN_LW),
pCacheDummyMid,
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_MID_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_ContentDescHdrWrite((icp_qat_fw_comn_req_t *)&(
keyGenReq),
&(contentDescInfo));
SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&keyGenReq,
ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
ICP_QAT_FW_LA_CMD_MGF1,
cmnRequestFlags,
laCmdFlags);
SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)&(keyGenReq),
pCookie,
LAC_SYM_KEY_QAT_PTR_TYPE,
inputPhysAddr,
outputPhysAddr,
0,
0);
status = icp_adf_transPutMsg(pService->trans_handle_sym_tx,
(void *)&(keyGenReq),
LAC_QAT_SYM_REQ_SZ_LW);
}
if (CPA_STATUS_SUCCESS == status) {
LAC_KEY_STAT_INC(numMgfKeyGenRequests, instanceHandle);
} else {
LAC_KEY_STAT_INC(numMgfKeyGenRequestErrors, instanceHandle);
if (NULL != pCookie) {
Lac_MemPoolEntryFree(pCookie);
}
}
return status;
}
CpaStatus
cpaCyKeyGenMgf(const CpaInstanceHandle instanceHandle_in,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
const CpaCyKeyGenMgfOpData *pKeyGenMgfOpData,
CpaFlatBuffer *pGeneratedMaskBuffer)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
if (NULL == pKeyGenCb) {
return LacSymKey_MgfSync(instanceHandle,
pKeyGenCb,
pCallbackTag,
(const void *)pKeyGenMgfOpData,
pGeneratedMaskBuffer,
CPA_FALSE);
}
return LacSymKey_MgfCommon(instanceHandle,
pKeyGenCb,
pCallbackTag,
(const void *)pKeyGenMgfOpData,
pKeyGenMgfOpData,
pGeneratedMaskBuffer,
CPA_CY_SYM_HASH_SHA1);
}
CpaStatus
cpaCyKeyGenMgfExt(const CpaInstanceHandle instanceHandle_in,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
const CpaCyKeyGenMgfOpDataExt *pKeyGenMgfOpDataExt,
CpaFlatBuffer *pGeneratedMaskBuffer)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
if (NULL == pKeyGenCb) {
return LacSymKey_MgfSync(instanceHandle,
pKeyGenCb,
pCallbackTag,
(const void *)pKeyGenMgfOpDataExt,
pGeneratedMaskBuffer,
CPA_TRUE);
}
LAC_CHECK_NULL_PARAM(pKeyGenMgfOpDataExt);
if (CPA_CY_SYM_HASH_MD5 > pKeyGenMgfOpDataExt->hashAlgorithm ||
CPA_CY_SYM_HASH_SHA512 < pKeyGenMgfOpDataExt->hashAlgorithm) {
LAC_INVALID_PARAM_LOG("hashAlgorithm");
return CPA_STATUS_INVALID_PARAM;
}
return LacSymKey_MgfCommon(instanceHandle,
pKeyGenCb,
pCallbackTag,
(const void *)pKeyGenMgfOpDataExt,
&pKeyGenMgfOpDataExt->baseOpData,
pGeneratedMaskBuffer,
pKeyGenMgfOpDataExt->hashAlgorithm);
}
static void
LacSymKey_SslTlsHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
void *pOpaqueData,
icp_qat_fw_comn_flags cmnRespFlags)
{
void *pSslTlsOpData = NULL;
CpaCyGenFlatBufCbFunc pKeyGenSslTlsCb = NULL;
lac_sym_key_cookie_t *pCookie = NULL;
void *pCallbackTag = NULL;
CpaFlatBuffer *pGeneratedKeyBuffer = NULL;
CpaStatus status = CPA_STATUS_SUCCESS;
CpaBoolean respStatusOk =
(ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(cmnRespFlags)) ?
CPA_TRUE :
CPA_FALSE;
pCookie = (lac_sym_key_cookie_t *)pOpaqueData;
pSslTlsOpData = pCookie->pKeyGenOpData;
if (CPA_TRUE == respStatusOk) {
LacKey_StatsInc(lacCmdId,
LAC_KEY_COMPLETED,
pCookie->instanceHandle);
} else {
status = CPA_STATUS_FAIL;
LacKey_StatsInc(lacCmdId,
LAC_KEY_COMPLETED_ERRORS,
pCookie->instanceHandle);
}
pKeyGenSslTlsCb = (CpaCyGenFlatBufCbFunc)(pCookie->pKeyGenCb);
pCallbackTag = pCookie->pCallbackTag;
pGeneratedKeyBuffer = pCookie->pKeyGenOutputData;
Lac_MemPoolEntryFree(pCookie);
(*pKeyGenSslTlsCb)(pCallbackTag,
status,
pSslTlsOpData,
pGeneratedKeyBuffer);
}
static CpaStatus
LacSymKey_SslTlsSync(CpaInstanceHandle instanceHandle,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
icp_qat_fw_la_cmd_id_t lacCmdId,
void *pKeyGenSslTlsOpData,
Cpa8U hashAlgorithm,
CpaFlatBuffer *pKeyGenOutpuData)
{
lac_sync_op_data_t *pSyncCallbackData = NULL;
CpaStatus status = CPA_STATUS_SUCCESS;
status = LacSync_CreateSyncCookie(&pSyncCallbackData);
if (CPA_STATUS_SUCCESS == status) {
status = LacSymKey_KeyGenSslTls_GenCommon(instanceHandle,
pKeyGenCb,
pSyncCallbackData,
lacCmdId,
pKeyGenSslTlsOpData,
hashAlgorithm,
pKeyGenOutpuData);
} else {
LacKey_StatsInc(lacCmdId,
LAC_KEY_REQUEST_ERRORS,
instanceHandle);
return status;
}
if (CPA_STATUS_SUCCESS == status) {
CpaStatus syncStatus = CPA_STATUS_SUCCESS;
syncStatus =
LacSync_WaitForCallback(pSyncCallbackData,
LAC_SYM_SYNC_CALLBACK_TIMEOUT,
&status,
NULL);
if (CPA_STATUS_SUCCESS != syncStatus) {
LacKey_StatsInc(lacCmdId,
LAC_KEY_COMPLETED_ERRORS,
instanceHandle);
LAC_LOG_ERROR("Callback timed out");
status = syncStatus;
}
} else {
LacSync_SetSyncCookieComplete(pSyncCallbackData);
}
LacSync_DestroySyncCookie(&pSyncCallbackData);
return status;
}
static CpaStatus
computeHashKey(CpaFlatBuffer *secret,
CpaFlatBuffer *hash,
CpaCySymHashAlgorithm *hashAlgorithm)
{
CpaStatus status = CPA_STATUS_SUCCESS;
switch (*hashAlgorithm) {
case CPA_CY_SYM_HASH_MD5:
status = qatUtilsHashMD5Full(secret->pData,
hash->pData,
secret->dataLenInBytes);
break;
case CPA_CY_SYM_HASH_SHA1:
status = qatUtilsHashSHA1Full(secret->pData,
hash->pData,
secret->dataLenInBytes);
break;
case CPA_CY_SYM_HASH_SHA256:
status = qatUtilsHashSHA256Full(secret->pData,
hash->pData,
secret->dataLenInBytes);
break;
case CPA_CY_SYM_HASH_SHA384:
status = qatUtilsHashSHA384Full(secret->pData,
hash->pData,
secret->dataLenInBytes);
break;
case CPA_CY_SYM_HASH_SHA512:
status = qatUtilsHashSHA512Full(secret->pData,
hash->pData,
secret->dataLenInBytes);
break;
default:
status = CPA_STATUS_FAIL;
}
return status;
}
static CpaStatus
LacSymKey_KeyGenSslTls_GenCommon(CpaInstanceHandle instanceHandle,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
icp_qat_fw_la_cmd_id_t lacCmdId,
void *pKeyGenSslTlsOpData,
Cpa8U hashAlgCipher,
CpaFlatBuffer *pKeyGenOutputData)
{
CpaStatus status = CPA_STATUS_SUCCESS;
CpaBoolean precompute = CPA_FALSE;
icp_qat_fw_la_bulk_req_t keyGenReq = { { 0 } };
icp_qat_la_bulk_req_hdr_t keyGenReqHdr = { { 0 } };
icp_qat_fw_la_key_gen_common_t keyGenReqMid = { { 0 } };
icp_qat_la_bulk_req_ftr_t keyGenReqFtr = { { { 0 } } };
Cpa8U *pMsgDummy = NULL;
Cpa8U *pCacheDummyHdr = NULL;
Cpa8U *pCacheDummyMid = NULL;
Cpa8U *pCacheDummyFtr = NULL;
lac_sym_key_cookie_t *pCookie = NULL;
lac_sym_cookie_t *pSymCookie = NULL;
Cpa64U inputPhysAddr = 0;
Cpa64U outputPhysAddr = 0;
CpaCySymHashSetupData hashSetupData = { 0 };
sal_qat_content_desc_info_t contentDescInfo = { 0 };
Cpa32U hashBlkSizeInBytes = 0;
Cpa32U tlsPrefixLen = 0;
CpaFlatBuffer inputSecret = { 0 };
CpaFlatBuffer hashKeyOutput = { 0 };
Cpa32U uSecretLen = 0;
CpaCySymHashNestedModeSetupData *pNestedModeSetupData =
&(hashSetupData.nestedModeSetupData);
icp_qat_fw_serv_specif_flags laCmdFlags = 0;
icp_qat_fw_comn_flags cmnRequestFlags =
ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_PTR_TYPE_FLAT,
QAT_COMN_CD_FLD_TYPE_64BIT_ADR);
sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
if (NULL == pKeyGenCb) {
return LacSymKey_SslTlsSync(instanceHandle,
LacSync_GenFlatBufCb,
pCallbackTag,
lacCmdId,
pKeyGenSslTlsOpData,
hashAlgCipher,
pKeyGenOutputData);
}
pCookie = (lac_sym_key_cookie_t *)Lac_MemPoolEntryAlloc(
pService->lac_sym_cookie_pool);
if (NULL == pCookie) {
LAC_LOG_ERROR("Cannot get mem pool entry");
status = CPA_STATUS_RESOURCE;
} else if ((void *)CPA_STATUS_RETRY == pCookie) {
pCookie = NULL;
status = CPA_STATUS_RETRY;
} else {
pSymCookie = (lac_sym_cookie_t *)pCookie;
}
if (CPA_STATUS_SUCCESS == status) {
icp_qat_hw_auth_mode_t qatHashMode = 0;
if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
qatHashMode = ICP_QAT_HW_AUTH_MODE0;
} else
{
qatHashMode = ICP_QAT_HW_AUTH_MODE2;
}
pCookie->instanceHandle = pService;
pCookie->pCallbackTag = pCallbackTag;
pCookie->pKeyGenCb = pKeyGenCb;
pCookie->pKeyGenOpData = pKeyGenSslTlsOpData;
pCookie->pKeyGenOutputData = pKeyGenOutputData;
hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_NESTED;
if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
hashSetupData.digestResultLenInBytes =
LAC_HASH_MD5_DIGEST_SIZE;
pNestedModeSetupData->outerHashAlgorithm =
CPA_CY_SYM_HASH_MD5;
pNestedModeSetupData->pInnerPrefixData = NULL;
pNestedModeSetupData->innerPrefixLenInBytes = 0;
pNestedModeSetupData->pOuterPrefixData = NULL;
pNestedModeSetupData->outerPrefixLenInBytes = 0;
}
else if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == lacCmdId) {
CpaCyKeyGenTlsOpData *pKeyGenTlsOpData =
(CpaCyKeyGenTlsOpData *)pKeyGenSslTlsOpData;
hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
hashSetupData.digestResultLenInBytes =
LAC_HASH_MD5_DIGEST_SIZE;
pNestedModeSetupData->outerHashAlgorithm =
CPA_CY_SYM_HASH_MD5;
uSecretLen = pKeyGenTlsOpData->secret.dataLenInBytes;
if ((uSecretLen >
ICP_QAT_FW_LA_TLS_V1_1_SECRET_LEN_MAX) &&
(CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE ==
pKeyGenTlsOpData->tlsOp ||
CPA_CY_KEY_TLS_OP_USER_DEFINED ==
pKeyGenTlsOpData->tlsOp)) {
CpaCySymHashAlgorithm hashAlgorithm =
(CpaCySymHashAlgorithm)hashAlgCipher;
tlsPrefixLen =
(pKeyGenTlsOpData->secret.dataLenInBytes +
1) >>
1;
inputSecret.dataLenInBytes = tlsPrefixLen;
inputSecret.pData =
pKeyGenTlsOpData->secret.pData;
hashAlgorithm = CPA_CY_SYM_HASH_MD5;
hashKeyOutput.pData =
&pCookie->hashKeyBuffer[0];
hashKeyOutput.dataLenInBytes =
LAC_HASH_MD5_DIGEST_SIZE;
computeHashKey(&inputSecret,
&hashKeyOutput,
&hashAlgorithm);
pNestedModeSetupData->pOuterPrefixData =
&pCookie->hashKeyBuffer[0];
pNestedModeSetupData->outerPrefixLenInBytes =
LAC_HASH_MD5_DIGEST_SIZE;
inputSecret.pData =
pKeyGenTlsOpData->secret.pData +
(pKeyGenTlsOpData->secret.dataLenInBytes -
tlsPrefixLen);
hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
hashKeyOutput.pData =
&pCookie->hashKeyBuffer
[LAC_HASH_MD5_DIGEST_SIZE];
hashKeyOutput.dataLenInBytes =
LAC_HASH_SHA1_DIGEST_SIZE;
computeHashKey(&inputSecret,
&hashKeyOutput,
&hashAlgorithm);
pNestedModeSetupData->pInnerPrefixData =
&pCookie->hashKeyBuffer
[LAC_HASH_MD5_DIGEST_SIZE];
pNestedModeSetupData->innerPrefixLenInBytes =
LAC_HASH_SHA1_DIGEST_SIZE;
} else {
tlsPrefixLen =
(pKeyGenTlsOpData->secret.dataLenInBytes +
1) >>
1;
pNestedModeSetupData->pInnerPrefixData =
pKeyGenTlsOpData->secret.pData +
(pKeyGenTlsOpData->secret.dataLenInBytes -
tlsPrefixLen);
pNestedModeSetupData->pOuterPrefixData =
pKeyGenTlsOpData->secret.pData;
pNestedModeSetupData->innerPrefixLenInBytes =
pNestedModeSetupData
->outerPrefixLenInBytes = tlsPrefixLen;
}
}
else if (ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE == lacCmdId) {
CpaCyKeyGenTlsOpData *pKeyGenTlsOpData =
(CpaCyKeyGenTlsOpData *)pKeyGenSslTlsOpData;
CpaCySymHashAlgorithm hashAlgorithm =
(CpaCySymHashAlgorithm)hashAlgCipher;
uSecretLen = pKeyGenTlsOpData->secret.dataLenInBytes;
hashSetupData.hashAlgorithm =
(CpaCySymHashAlgorithm)hashAlgorithm;
hashSetupData.digestResultLenInBytes =
(Cpa32U)getDigestSizeFromHashAlgo(hashAlgorithm);
pNestedModeSetupData->outerHashAlgorithm =
(CpaCySymHashAlgorithm)hashAlgorithm;
if (CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE ==
pKeyGenTlsOpData->tlsOp ||
CPA_CY_KEY_TLS_OP_USER_DEFINED ==
pKeyGenTlsOpData->tlsOp) {
switch (hashAlgorithm) {
case CPA_CY_SYM_HASH_SM3:
precompute = CPA_FALSE;
break;
case CPA_CY_SYM_HASH_SHA256:
if (uSecretLen >
ICP_QAT_FW_LA_TLS_V1_2_SECRET_LEN_MAX) {
precompute = CPA_TRUE;
}
break;
case CPA_CY_SYM_HASH_SHA384:
case CPA_CY_SYM_HASH_SHA512:
if (uSecretLen >
ICP_QAT_FW_LA_TLS_SECRET_LEN_MAX) {
precompute = CPA_TRUE;
}
break;
default:
break;
}
}
if (CPA_TRUE == precompute) {
hashKeyOutput.pData =
&pCookie->hashKeyBuffer[0];
hashKeyOutput.dataLenInBytes =
hashSetupData.digestResultLenInBytes;
computeHashKey(&pKeyGenTlsOpData->secret,
&hashKeyOutput,
&hashSetupData.hashAlgorithm);
pNestedModeSetupData->pInnerPrefixData =
hashKeyOutput.pData;
pNestedModeSetupData->pOuterPrefixData =
hashKeyOutput.pData;
pNestedModeSetupData->innerPrefixLenInBytes =
hashKeyOutput.dataLenInBytes;
pNestedModeSetupData->outerPrefixLenInBytes =
hashKeyOutput.dataLenInBytes;
} else {
pNestedModeSetupData->pInnerPrefixData =
pKeyGenTlsOpData->secret.pData;
pNestedModeSetupData->pOuterPrefixData =
pKeyGenTlsOpData->secret.pData;
pNestedModeSetupData->innerPrefixLenInBytes =
pKeyGenTlsOpData->secret.dataLenInBytes;
pNestedModeSetupData->outerPrefixLenInBytes =
pKeyGenTlsOpData->secret.dataLenInBytes;
}
}
else if ((ICP_QAT_FW_LA_CMD_HKDF_EXTRACT <= lacCmdId) &&
(ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL >=
lacCmdId)) {
CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData =
(CpaCyKeyGenHKDFOpData *)pKeyGenSslTlsOpData;
CpaCySymHashAlgorithm hashAlgorithm =
getHashAlgorithmFromCipherSuiteHKDF(hashAlgCipher);
hashSetupData.hashAlgorithm = hashAlgorithm;
hashSetupData.digestResultLenInBytes =
cipherSuiteHKDFHashSizes[hashAlgCipher]
[LAC_KEY_HKDF_DIGESTS];
pNestedModeSetupData->outerHashAlgorithm =
hashAlgorithm;
if ((ICP_QAT_FW_LA_CMD_HKDF_EXPAND == lacCmdId) ||
(ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL == lacCmdId)) {
pNestedModeSetupData->pInnerPrefixData =
pKeyGenTlsOpData->secret;
pNestedModeSetupData->pOuterPrefixData =
pKeyGenTlsOpData->secret;
pNestedModeSetupData->innerPrefixLenInBytes =
pKeyGenTlsOpData->secretLen;
pNestedModeSetupData->outerPrefixLenInBytes =
pKeyGenTlsOpData->secretLen;
} else {
pNestedModeSetupData->pInnerPrefixData =
pKeyGenTlsOpData->seed;
pNestedModeSetupData->pOuterPrefixData =
pKeyGenTlsOpData->seed;
pNestedModeSetupData->innerPrefixLenInBytes =
pKeyGenTlsOpData->seedLen;
pNestedModeSetupData->outerPrefixLenInBytes =
pKeyGenTlsOpData->seedLen;
}
}
LacSymQat_HashContentDescInit(
&keyGenReqFtr,
instanceHandle,
&hashSetupData,
pCookie
->contentDesc,
LAC_SYM_KEY_NO_HASH_BLK_OFFSET_QW,
ICP_QAT_FW_SLICE_DRAM_WR,
qatHashMode,
CPA_FALSE,
CPA_FALSE,
CPA_FALSE,
NULL,
&hashBlkSizeInBytes);
if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
CpaCyKeyGenSslOpData *pKeyGenSslOpData =
(CpaCyKeyGenSslOpData *)pKeyGenSslTlsOpData;
Cpa8U *pLabel = NULL;
Cpa32U labelLen = 0;
Cpa8U iterations = 0;
Cpa64U labelPhysAddr = 0;
iterations =
(pKeyGenSslOpData->generatedKeyLenInBytes +
(LAC_SYM_QAT_KEY_SSL_BYTES_PER_ITERATION - 1)) >>
LAC_SYM_QAT_KEY_SSL_ITERATIONS_SHIFT;
if (CPA_CY_KEY_SSL_OP_USER_DEFINED ==
pKeyGenSslOpData->sslOp) {
pLabel = pKeyGenSslOpData->userLabel.pData;
labelLen =
pKeyGenSslOpData->userLabel.dataLenInBytes;
labelPhysAddr = LAC_OS_VIRT_TO_PHYS_EXTERNAL(
pService->generic_service_info, pLabel);
if (labelPhysAddr == 0) {
LAC_LOG_ERROR(
"Unable to get the physical address of the"
" label");
status = CPA_STATUS_FAIL;
}
} else {
pLabel = pService->pSslLabel;
labelLen =
((iterations * iterations) + iterations) >>
1;
labelPhysAddr =
LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
}
LacSymQat_KeySslRequestPopulate(
&keyGenReqHdr,
&keyGenReqMid,
pKeyGenSslOpData->generatedKeyLenInBytes,
labelLen,
pKeyGenSslOpData->secret.dataLenInBytes,
iterations);
LacSymQat_KeySslKeyMaterialInputPopulate(
&(pService->generic_service_info),
&(pCookie->u.sslKeyInput),
pKeyGenSslOpData->seed.pData,
labelPhysAddr,
pKeyGenSslOpData->secret.pData);
inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
pSymCookie->keySslKeyInputPhyAddr);
}
else if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == lacCmdId ||
ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE == lacCmdId) {
CpaCyKeyGenTlsOpData *pKeyGenTlsOpData =
(CpaCyKeyGenTlsOpData *)pKeyGenSslTlsOpData;
lac_sym_qat_hash_state_buffer_info_t
hashStateBufferInfo = { 0 };
CpaBoolean hashStateBuffer = CPA_FALSE;
icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock =
(icp_qat_fw_auth_cd_ctrl_hdr_t *)&(
keyGenReqFtr.cd_ctrl);
icp_qat_la_auth_req_params_t *pHashReqParams = NULL;
Cpa8U *pLabel = NULL;
Cpa32U labelLen = 0;
Cpa64U labelPhysAddr = 0;
hashStateBufferInfo.pData = pCookie->hashStateBuffer;
hashStateBufferInfo.pDataPhys =
LAC_MEM_CAST_PTR_TO_UINT64(
pSymCookie->keyHashStateBufferPhyAddr);
hashStateBufferInfo.stateStorageSzQuadWords = 0;
LacSymQat_HashSetupReqParamsMetaData(&(keyGenReqFtr),
instanceHandle,
&(hashSetupData),
hashStateBuffer,
qatHashMode,
CPA_FALSE);
pHashReqParams = (icp_qat_la_auth_req_params_t *)&(
keyGenReqFtr.serv_specif_rqpars);
hashStateBufferInfo.prefixAadSzQuadWords =
LAC_BYTES_TO_QUADWORDS(
pHashReqParams->u2.inner_prefix_sz +
pHashControlBlock->outer_prefix_sz);
pMsgDummy = (Cpa8U *)&(keyGenReq);
pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
memcpy(pMsgDummy,
pCacheDummyHdr,
(LAC_LONG_WORD_IN_BYTES *
LAC_SIZE_OF_CACHE_HDR_IN_LW));
memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
LAC_START_OF_CACHE_MID_IN_LW),
pCacheDummyMid,
(LAC_LONG_WORD_IN_BYTES *
LAC_SIZE_OF_CACHE_MID_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));
LacSymQat_HashStatePrefixAadBufferPopulate(
&hashStateBufferInfo,
&keyGenReqFtr,
pNestedModeSetupData->pInnerPrefixData,
pNestedModeSetupData->innerPrefixLenInBytes,
pNestedModeSetupData->pOuterPrefixData,
pNestedModeSetupData->outerPrefixLenInBytes);
LacSymQat_HashRequestParamsPopulate(
&(keyGenReq),
0,
0,
&(pService->generic_service_info),
&hashStateBufferInfo,
ICP_QAT_FW_LA_PARTIAL_NONE,
0,
CPA_FALSE,
NULL,
CPA_CY_SYM_HASH_NONE,
NULL);
if (CPA_CY_KEY_TLS_OP_USER_DEFINED ==
pKeyGenTlsOpData->tlsOp) {
pLabel = pKeyGenTlsOpData->userLabel.pData;
labelLen =
pKeyGenTlsOpData->userLabel.dataLenInBytes;
labelPhysAddr = LAC_OS_VIRT_TO_PHYS_EXTERNAL(
pService->generic_service_info, pLabel);
if (labelPhysAddr == 0) {
LAC_LOG_ERROR(
"Unable to get the physical address of the"
" label");
status = CPA_STATUS_FAIL;
}
} else if (CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE ==
pKeyGenTlsOpData->tlsOp) {
pLabel = pService->pTlsLabel->masterSecret;
labelLen =
sizeof(
LAC_SYM_KEY_TLS_MASTER_SECRET_LABEL) -
1;
labelPhysAddr =
LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
} else if (CPA_CY_KEY_TLS_OP_KEY_MATERIAL_DERIVE ==
pKeyGenTlsOpData->tlsOp) {
pLabel = pService->pTlsLabel->keyMaterial;
labelLen =
sizeof(LAC_SYM_KEY_TLS_KEY_MATERIAL_LABEL) -
1;
labelPhysAddr =
LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
} else if (CPA_CY_KEY_TLS_OP_CLIENT_FINISHED_DERIVE ==
pKeyGenTlsOpData->tlsOp) {
pLabel = pService->pTlsLabel->clientFinished;
labelLen =
sizeof(LAC_SYM_KEY_TLS_CLIENT_FIN_LABEL) -
1;
labelPhysAddr =
LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
} else {
pLabel = pService->pTlsLabel->serverFinished;
labelLen =
sizeof(LAC_SYM_KEY_TLS_SERVER_FIN_LABEL) -
1;
labelPhysAddr =
LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
}
LacSymQat_KeyTlsRequestPopulate(
&keyGenReqMid,
pKeyGenTlsOpData->generatedKeyLenInBytes,
labelLen,
pKeyGenTlsOpData->secret.dataLenInBytes,
pKeyGenTlsOpData->seed.dataLenInBytes,
lacCmdId);
LacSymQat_KeyTlsKeyMaterialInputPopulate(
&(pService->generic_service_info),
&(pCookie->u.tlsKeyInput),
pKeyGenTlsOpData->seed.pData,
labelPhysAddr);
inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
pSymCookie->keyTlsKeyInputPhyAddr);
}
else if (ICP_QAT_FW_LA_CMD_HKDF_EXTRACT <= lacCmdId &&
ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND >=
lacCmdId) {
CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData =
(CpaCyKeyGenHKDFOpData *)pKeyGenSslTlsOpData;
lac_sym_qat_hash_state_buffer_info_t
hashStateBufferInfo = { 0 };
CpaBoolean hashStateBuffer = CPA_FALSE;
icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock =
(icp_qat_fw_auth_cd_ctrl_hdr_t *)&(
keyGenReqFtr.cd_ctrl);
icp_qat_la_auth_req_params_t *pHashReqParams = NULL;
hashStateBufferInfo.pData = pCookie->hashStateBuffer;
hashStateBufferInfo.pDataPhys =
LAC_MEM_CAST_PTR_TO_UINT64(
pSymCookie->keyHashStateBufferPhyAddr);
hashStateBufferInfo.stateStorageSzQuadWords = 0;
LacSymQat_HashSetupReqParamsMetaData(&(keyGenReqFtr),
instanceHandle,
&(hashSetupData),
hashStateBuffer,
qatHashMode,
CPA_FALSE);
pHashReqParams = (icp_qat_la_auth_req_params_t *)&(
keyGenReqFtr.serv_specif_rqpars);
hashStateBufferInfo.prefixAadSzQuadWords =
LAC_BYTES_TO_QUADWORDS(
pHashReqParams->u2.inner_prefix_sz +
pHashControlBlock->outer_prefix_sz);
pMsgDummy = (Cpa8U *)&(keyGenReq);
pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
memcpy(pMsgDummy,
pCacheDummyHdr,
(LAC_LONG_WORD_IN_BYTES *
LAC_SIZE_OF_CACHE_HDR_IN_LW));
memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
LAC_START_OF_CACHE_MID_IN_LW),
pCacheDummyMid,
(LAC_LONG_WORD_IN_BYTES *
LAC_SIZE_OF_CACHE_MID_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));
LacSymQat_HashStatePrefixAadBufferPopulate(
&hashStateBufferInfo,
&keyGenReqFtr,
pNestedModeSetupData->pInnerPrefixData,
pNestedModeSetupData->innerPrefixLenInBytes,
pNestedModeSetupData->pOuterPrefixData,
pNestedModeSetupData->outerPrefixLenInBytes);
LacSymQat_HashRequestParamsPopulate(
&(keyGenReq),
0,
0,
&(pService->generic_service_info),
&hashStateBufferInfo,
ICP_QAT_FW_LA_PARTIAL_NONE,
0,
CPA_FALSE,
NULL,
CPA_CY_SYM_HASH_NONE,
pKeyGenTlsOpData->secret);
LacSymQat_KeyTlsRequestPopulate(
&keyGenReqMid,
cipherSuiteHKDFHashSizes[hashAlgCipher]
[LAC_KEY_HKDF_DIGESTS],
pKeyGenTlsOpData->infoLen,
pKeyGenTlsOpData->secretLen,
pKeyGenTlsOpData->seedLen,
lacCmdId);
LacSymQat_KeyTlsHKDFKeyMaterialInputPopulate(
&(pService->generic_service_info),
&(pCookie->u.tlsHKDFKeyInput),
pKeyGenTlsOpData,
0,
lacCmdId);
inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
pSymCookie->keyTlsKeyInputPhyAddr);
}
else if (ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL == lacCmdId ||
ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL ==
lacCmdId) {
CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData =
(CpaCyKeyGenHKDFOpData *)pKeyGenSslTlsOpData;
Cpa64U subLabelsPhysAddr = 0;
lac_sym_qat_hash_state_buffer_info_t
hashStateBufferInfo = { 0 };
CpaBoolean hashStateBuffer = CPA_FALSE;
icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock =
(icp_qat_fw_auth_cd_ctrl_hdr_t *)&(
keyGenReqFtr.cd_ctrl);
icp_qat_la_auth_req_params_t *pHashReqParams = NULL;
hashStateBufferInfo.pData = pCookie->hashStateBuffer;
hashStateBufferInfo.pDataPhys =
LAC_MEM_CAST_PTR_TO_UINT64(
pSymCookie->keyHashStateBufferPhyAddr);
hashStateBufferInfo.stateStorageSzQuadWords = 0;
LacSymQat_HashSetupReqParamsMetaData(&(keyGenReqFtr),
instanceHandle,
&(hashSetupData),
hashStateBuffer,
qatHashMode,
CPA_FALSE);
pHashReqParams = (icp_qat_la_auth_req_params_t *)&(
keyGenReqFtr.serv_specif_rqpars);
hashStateBufferInfo.prefixAadSzQuadWords =
LAC_BYTES_TO_QUADWORDS(
pHashReqParams->u2.inner_prefix_sz +
pHashControlBlock->outer_prefix_sz);
pMsgDummy = (Cpa8U *)&(keyGenReq);
pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
memcpy(pMsgDummy,
pCacheDummyHdr,
(LAC_LONG_WORD_IN_BYTES *
LAC_SIZE_OF_CACHE_HDR_IN_LW));
memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
LAC_START_OF_CACHE_MID_IN_LW),
pCacheDummyMid,
(LAC_LONG_WORD_IN_BYTES *
LAC_SIZE_OF_CACHE_MID_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));
LacSymQat_HashStatePrefixAadBufferPopulate(
&hashStateBufferInfo,
&keyGenReqFtr,
pNestedModeSetupData->pInnerPrefixData,
pNestedModeSetupData->innerPrefixLenInBytes,
pNestedModeSetupData->pOuterPrefixData,
pNestedModeSetupData->outerPrefixLenInBytes);
LacSymQat_HashRequestParamsPopulate(
&(keyGenReq),
0,
0,
&(pService->generic_service_info),
&hashStateBufferInfo,
ICP_QAT_FW_LA_PARTIAL_NONE,
0,
CPA_FALSE,
NULL,
CPA_CY_SYM_HASH_NONE,
pKeyGenTlsOpData->secret);
LacSymQat_KeyTlsRequestPopulate(
&keyGenReqMid,
cipherSuiteHKDFHashSizes[hashAlgCipher]
[LAC_KEY_HKDF_DIGESTS],
pKeyGenTlsOpData->numLabels,
pKeyGenTlsOpData->secretLen,
pKeyGenTlsOpData->seedLen,
lacCmdId);
switch (hashAlgCipher) {
case CPA_CY_HKDF_TLS_AES_128_GCM_SHA256:
case CPA_CY_HKDF_TLS_AES_128_CCM_SHA256:
case CPA_CY_HKDF_TLS_AES_128_CCM_8_SHA256:
subLabelsPhysAddr = pService->pTlsHKDFSubLabel
->sublabelPhysAddr256;
break;
case CPA_CY_HKDF_TLS_CHACHA20_POLY1305_SHA256:
subLabelsPhysAddr =
pService->pTlsHKDFSubLabel
->sublabelPhysAddrChaChaPoly;
break;
case CPA_CY_HKDF_TLS_AES_256_GCM_SHA384:
subLabelsPhysAddr = pService->pTlsHKDFSubLabel
->sublabelPhysAddr384;
break;
default:
break;
}
LacSymQat_KeyTlsHKDFKeyMaterialInputPopulate(
&(pService->generic_service_info),
&(pCookie->u.tlsHKDFKeyInput),
pKeyGenTlsOpData,
subLabelsPhysAddr,
lacCmdId);
inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
pSymCookie->keyTlsKeyInputPhyAddr);
}
outputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info,
pKeyGenOutputData->pData));
if (outputPhysAddr == 0) {
LAC_LOG_ERROR(
"Unable to get the physical address of the"
" output buffer");
status = CPA_STATUS_FAIL;
}
}
if (CPA_STATUS_SUCCESS == status) {
Cpa8U lw26[4];
char *tmp = NULL;
unsigned char a;
int n = 0;
pMsgDummy = (Cpa8U *)&(keyGenReq);
pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
memcpy(pMsgDummy,
pCacheDummyHdr,
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
LAC_START_OF_CACHE_MID_IN_LW),
pCacheDummyMid,
(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_MID_IN_LW));
memcpy(&lw26,
pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
LAC_START_OF_CACHE_FTR_IN_LW),
LAC_LONG_WORD_IN_BYTES);
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));
tmp = (char *)(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
LAC_START_OF_CACHE_FTR_IN_LW));
for (n = 0; n < LAC_LONG_WORD_IN_BYTES; n++) {
a = (unsigned char)*(tmp + n);
lw26[n] = lw26[n] | a;
}
memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
LAC_START_OF_CACHE_FTR_IN_LW),
&lw26,
LAC_LONG_WORD_IN_BYTES);
contentDescInfo.pData = pCookie->contentDesc;
contentDescInfo.hardwareSetupBlockPhys =
LAC_MEM_CAST_PTR_TO_UINT64(
pSymCookie->keyContentDescPhyAddr);
contentDescInfo.hwBlkSzQuadWords =
LAC_BYTES_TO_QUADWORDS(hashBlkSizeInBytes);
SalQatMsg_ContentDescHdrWrite((icp_qat_fw_comn_req_t *)&(
keyGenReq),
&(contentDescInfo));
SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&keyGenReq,
ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
lacCmdId,
cmnRequestFlags,
laCmdFlags);
SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)&(keyGenReq),
pCookie,
LAC_SYM_KEY_QAT_PTR_TYPE,
inputPhysAddr,
outputPhysAddr,
0,
0);
status = icp_adf_transPutMsg(pService->trans_handle_sym_tx,
(void *)&(keyGenReq),
LAC_QAT_SYM_REQ_SZ_LW);
}
if (CPA_STATUS_SUCCESS == status) {
LacKey_StatsInc(lacCmdId,
LAC_KEY_REQUESTS,
pCookie->instanceHandle);
} else {
if (NULL != pCookie) {
LacKey_StatsInc(lacCmdId,
LAC_KEY_REQUEST_ERRORS,
pCookie->instanceHandle);
Lac_MemPoolEntryFree(pCookie);
}
}
return status;
}
static CpaStatus
LacSymKey_CheckParamSslTls(const void *pKeyGenOpData,
Cpa8U hashAlgCipher,
const CpaFlatBuffer *pGeneratedKeyBuffer,
icp_qat_fw_la_cmd_id_t cmdId)
{
Cpa32U maxSecretLen = 0;
Cpa32U maxSeedLen = 0;
Cpa32U maxOutputLen = 0;
Cpa32U maxInfoLen = 0;
Cpa32U maxLabelLen = 0;
Cpa32U uSecretLen = 0;
Cpa32U uSeedLen = 0;
Cpa32U uOutputLen = 0;
LAC_CHECK_NULL_PARAM(pKeyGenOpData);
LAC_CHECK_NULL_PARAM(pGeneratedKeyBuffer);
LAC_CHECK_NULL_PARAM(pGeneratedKeyBuffer->pData);
if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == cmdId) {
CpaCyKeyGenSslOpData *opData =
(CpaCyKeyGenSslOpData *)pKeyGenOpData;
uSecretLen = opData->secret.dataLenInBytes;
uSeedLen = opData->seed.dataLenInBytes;
uOutputLen = opData->generatedKeyLenInBytes;
maxSecretLen = ICP_QAT_FW_LA_SSL_SECRET_LEN_MAX;
maxSeedLen = ICP_QAT_FW_LA_SSL_SEED_LEN_MAX;
maxOutputLen = ICP_QAT_FW_LA_SSL_OUTPUT_LEN_MAX;
LAC_CHECK_NULL_PARAM(opData->secret.pData);
LAC_CHECK_NULL_PARAM(opData->seed.pData);
if ((Cpa32U)opData->sslOp > CPA_CY_KEY_SSL_OP_USER_DEFINED) {
LAC_INVALID_PARAM_LOG("opData->sslOp");
return CPA_STATUS_INVALID_PARAM;
}
if ((Cpa32U)opData->sslOp == CPA_CY_KEY_SSL_OP_USER_DEFINED) {
LAC_CHECK_NULL_PARAM(opData->userLabel.pData);
if (opData->userLabel.dataLenInBytes >
ICP_QAT_FW_LA_SSL_LABEL_LEN_MAX) {
LAC_INVALID_PARAM_LOG(
"userLabel.dataLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
}
if (0 == uSecretLen) {
LAC_INVALID_PARAM_LOG1("%u secret.dataLenInBytes",
uSecretLen);
return CPA_STATUS_INVALID_PARAM;
}
if (maxSeedLen != uSeedLen) {
LAC_INVALID_PARAM_LOG("seed.dataLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
if (uOutputLen > maxOutputLen) {
LAC_INVALID_PARAM_LOG("generatedKeyLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
}
else if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == cmdId ||
ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE == cmdId) {
CpaCyKeyGenTlsOpData *opData =
(CpaCyKeyGenTlsOpData *)pKeyGenOpData;
uSecretLen = opData->secret.dataLenInBytes;
uSeedLen = opData->seed.dataLenInBytes;
uOutputLen = opData->generatedKeyLenInBytes;
if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == cmdId) {
maxSecretLen =
ICP_QAT_FW_LA_TLS_V1_1_SECRET_LEN_MAX * 4;
} else {
maxSecretLen =
ICP_QAT_FW_LA_TLS_V1_2_SECRET_LEN_MAX * 8;
if (0 == getDigestSizeFromHashAlgo(hashAlgCipher)) {
LAC_INVALID_PARAM_LOG("hashAlgorithm");
return CPA_STATUS_INVALID_PARAM;
}
}
maxSeedLen = ICP_QAT_FW_LA_TLS_SEED_LEN_MAX;
maxOutputLen = ICP_QAT_FW_LA_TLS_OUTPUT_LEN_MAX;
LAC_CHECK_NULL_PARAM(opData->secret.pData);
LAC_CHECK_NULL_PARAM(opData->seed.pData);
if ((Cpa32U)opData->tlsOp > CPA_CY_KEY_TLS_OP_USER_DEFINED) {
LAC_INVALID_PARAM_LOG("opData->tlsOp");
return CPA_STATUS_INVALID_PARAM;
} else if ((Cpa32U)opData->tlsOp ==
CPA_CY_KEY_TLS_OP_USER_DEFINED) {
LAC_CHECK_NULL_PARAM(opData->userLabel.pData);
if (opData->userLabel.dataLenInBytes >
ICP_QAT_FW_LA_TLS_LABEL_LEN_MAX) {
LAC_INVALID_PARAM_LOG(
"userLabel.dataLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
}
if (((Cpa32U)opData->tlsOp !=
CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE) &&
((Cpa32U)opData->tlsOp !=
CPA_CY_KEY_TLS_OP_KEY_MATERIAL_DERIVE)) {
if (uSeedLen > maxSeedLen) {
LAC_INVALID_PARAM_LOG("seed.dataLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
} else {
if (maxSeedLen != uSeedLen) {
LAC_INVALID_PARAM_LOG("seed.dataLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
}
if (uOutputLen > maxOutputLen) {
LAC_INVALID_PARAM_LOG("generatedKeyLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
}
else if (cmdId >= ICP_QAT_FW_LA_CMD_HKDF_EXTRACT &&
cmdId <= ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL) {
CpaCyKeyGenHKDFOpData *HKDF_Data =
(CpaCyKeyGenHKDFOpData *)pKeyGenOpData;
CpaCyKeyHKDFCipherSuite cipherSuite = hashAlgCipher;
CpaCySymHashAlgorithm hashAlgorithm =
getHashAlgorithmFromCipherSuiteHKDF(cipherSuite);
maxSeedLen =
cipherSuiteHKDFHashSizes[cipherSuite][LAC_KEY_HKDF_DIGESTS];
maxSecretLen = CPA_CY_HKDF_KEY_MAX_SECRET_SZ;
maxInfoLen = CPA_CY_HKDF_KEY_MAX_INFO_SZ;
maxLabelLen = CPA_CY_HKDF_KEY_MAX_LABEL_SZ;
uSecretLen = HKDF_Data->secretLen;
if (0 ==
(uOutputLen = getDigestSizeFromHashAlgo(hashAlgorithm))) {
LAC_INVALID_PARAM_LOG("Hash function not supported");
return CPA_STATUS_INVALID_PARAM;
}
if (HKDF_Data->numLabels > CPA_CY_HKDF_KEY_MAX_LABEL_COUNT) {
LAC_INVALID_PARAM_LOG(
"CpaCyKeyGenHKDFOpData.numLabels");
return CPA_STATUS_INVALID_PARAM;
}
switch (cmdId) {
case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT:
if (maxSeedLen < HKDF_Data->seedLen) {
LAC_INVALID_PARAM_LOG(
"CpaCyKeyGenHKDFOpData.seedLen");
return CPA_STATUS_INVALID_PARAM;
}
break;
case ICP_QAT_FW_LA_CMD_HKDF_EXPAND:
maxSecretLen =
cipherSuiteHKDFHashSizes[cipherSuite]
[LAC_KEY_HKDF_DIGESTS];
if (maxInfoLen < HKDF_Data->infoLen) {
LAC_INVALID_PARAM_LOG(
"CpaCyKeyGenHKDFOpData.infoLen");
return CPA_STATUS_INVALID_PARAM;
}
break;
case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND:
uOutputLen *= 2;
if (maxSeedLen < HKDF_Data->seedLen) {
LAC_INVALID_PARAM_LOG(
"CpaCyKeyGenHKDFOpData.seedLen");
return CPA_STATUS_INVALID_PARAM;
}
if (maxInfoLen < HKDF_Data->infoLen) {
LAC_INVALID_PARAM_LOG(
"CpaCyKeyGenHKDFOpData.infoLen");
return CPA_STATUS_INVALID_PARAM;
}
break;
case ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL:
case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL: {
Cpa8U subl_mask = 0, subl_number = 1;
Cpa8U i = 0;
if (maxSeedLen < HKDF_Data->seedLen) {
LAC_INVALID_PARAM_LOG(
"CpaCyKeyGenHKDFOpData.seedLen");
return CPA_STATUS_INVALID_PARAM;
}
if (ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL == cmdId) {
uOutputLen = 0;
maxSecretLen = cipherSuiteHKDFHashSizes
[cipherSuite][LAC_KEY_HKDF_DIGESTS];
}
for (i = 0; i < HKDF_Data->numLabels; i++) {
if (maxLabelLen <
HKDF_Data->label[i].labelLen) {
LAC_INVALID_PARAM_LOG1(
"CpaCyKeyGenHKDFOpData.label[%d].labelLen",
i);
return CPA_STATUS_INVALID_PARAM;
}
if (HKDF_Data->label[i].sublabelFlag &
~HKDF_SUB_LABELS_ALL) {
LAC_INVALID_PARAM_LOG1(
"CpaCyKeyGenHKDFOpData.label[%d]."
"subLabelFlag",
i);
return CPA_STATUS_INVALID_PARAM;
}
uOutputLen += cipherSuiteHKDFHashSizes
[cipherSuite][LAC_KEY_HKDF_DIGESTS];
subl_mask = HKDF_Data->label[i].sublabelFlag;
for (subl_number = 1;
subl_number <= LAC_KEY_HKDF_SUBLABELS_NUM;
subl_number++) {
if (subl_mask & 1) {
uOutputLen +=
cipherSuiteHKDFHashSizes
[cipherSuite]
[subl_number];
}
subl_mask >>= 1;
}
}
} break;
default:
break;
}
} else {
LAC_INVALID_PARAM_LOG("TLS/SSL operation");
return CPA_STATUS_INVALID_PARAM;
}
if (uSecretLen > maxSecretLen) {
LAC_INVALID_PARAM_LOG("HKFD.secretLen/secret.dataLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
if (uOutputLen > pGeneratedKeyBuffer->dataLenInBytes) {
LAC_INVALID_PARAM_LOG("pGeneratedKeyBuffer->dataLenInBytes");
return CPA_STATUS_INVALID_PARAM;
}
return CPA_STATUS_SUCCESS;
}
static CpaStatus
LacSymKey_KeyGenSslTls(const CpaInstanceHandle instanceHandle_in,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
const void *pKeyGenOpData,
Cpa8U hashAlgorithm,
CpaFlatBuffer *pGeneratedKeyBuffer,
icp_qat_fw_la_cmd_id_t cmdId)
{
CpaStatus status = CPA_STATUS_FAIL;
CpaInstanceHandle instanceHandle = LacKey_GetHandle(instanceHandle_in);
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
SAL_CHECK_INSTANCE_TYPE(instanceHandle,
(SAL_SERVICE_TYPE_CRYPTO |
SAL_SERVICE_TYPE_CRYPTO_SYM));
SAL_RUNNING_CHECK(instanceHandle);
status = LacSymKey_CheckParamSslTls(pKeyGenOpData,
hashAlgorithm,
pGeneratedKeyBuffer,
cmdId);
if (CPA_STATUS_SUCCESS != status)
return status;
return LacSymKey_KeyGenSslTls_GenCommon(instanceHandle,
pKeyGenCb,
pCallbackTag,
cmdId,
LAC_CONST_PTR_CAST(
pKeyGenOpData),
hashAlgorithm,
pGeneratedKeyBuffer);
}
CpaStatus
cpaCyKeyGenSsl(const CpaInstanceHandle instanceHandle_in,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
const CpaCyKeyGenSslOpData *pKeyGenSslOpData,
CpaFlatBuffer *pGeneratedKeyBuffer)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
return LacSymKey_KeyGenSslTls(instanceHandle,
pKeyGenCb,
pCallbackTag,
LAC_CONST_PTR_CAST(pKeyGenSslOpData),
CPA_CY_SYM_HASH_NONE,
pGeneratedKeyBuffer,
ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE);
}
CpaStatus
cpaCyKeyGenTls(const CpaInstanceHandle instanceHandle_in,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
const CpaCyKeyGenTlsOpData *pKeyGenTlsOpData,
CpaFlatBuffer *pGeneratedKeyBuffer)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
return LacSymKey_KeyGenSslTls(instanceHandle,
pKeyGenCb,
pCallbackTag,
LAC_CONST_PTR_CAST(pKeyGenTlsOpData),
CPA_CY_SYM_HASH_NONE,
pGeneratedKeyBuffer,
ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE);
}
CpaStatus
cpaCyKeyGenTls2(const CpaInstanceHandle instanceHandle_in,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
const CpaCyKeyGenTlsOpData *pKeyGenTlsOpData,
CpaCySymHashAlgorithm hashAlgorithm,
CpaFlatBuffer *pGeneratedKeyBuffer)
{
CpaInstanceHandle instanceHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
instanceHandle =
Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
} else {
instanceHandle = instanceHandle_in;
}
return LacSymKey_KeyGenSslTls(instanceHandle,
pKeyGenCb,
pCallbackTag,
LAC_CONST_PTR_CAST(pKeyGenTlsOpData),
hashAlgorithm,
pGeneratedKeyBuffer,
ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE);
}
CpaStatus
cpaCyKeyGenTls3(const CpaInstanceHandle instanceHandle_in,
const CpaCyGenFlatBufCbFunc pKeyGenCb,
void *pCallbackTag,
const CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData,
CpaCyKeyHKDFCipherSuite cipherSuite,
CpaFlatBuffer *pGeneratedKeyBuffer)
{
LAC_CHECK_NULL_PARAM(pKeyGenTlsOpData);
switch (pKeyGenTlsOpData->hkdfKeyOp) {
case CPA_CY_HKDF_KEY_EXTRACT:
case CPA_CY_HKDF_KEY_EXPAND:
case CPA_CY_HKDF_KEY_EXTRACT_EXPAND:
case CPA_CY_HKDF_KEY_EXPAND_LABEL:
case CPA_CY_HKDF_KEY_EXTRACT_EXPAND_LABEL:
break;
default:
LAC_INVALID_PARAM_LOG("HKDF operation not supported");
return CPA_STATUS_INVALID_PARAM;
}
return LacSymKey_KeyGenSslTls(instanceHandle_in,
pKeyGenCb,
pCallbackTag,
LAC_CONST_PTR_CAST(pKeyGenTlsOpData),
cipherSuite,
pGeneratedKeyBuffer,
(icp_qat_fw_la_cmd_id_t)
pKeyGenTlsOpData->hkdfKeyOp);
}
CpaStatus
LacSymKey_Init(CpaInstanceHandle instanceHandle_in)
{
CpaStatus status = CPA_STATUS_SUCCESS;
CpaInstanceHandle instanceHandle = LacKey_GetHandle(instanceHandle_in);
sal_crypto_service_t *pService = NULL;
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
pService = (sal_crypto_service_t *)instanceHandle;
pService->pLacKeyStats =
LAC_OS_MALLOC(LAC_KEY_NUM_STATS * sizeof(QatUtilsAtomic));
if (NULL != pService->pLacKeyStats) {
LAC_OS_BZERO((void *)pService->pLacKeyStats,
LAC_KEY_NUM_STATS * sizeof(QatUtilsAtomic));
status = LAC_OS_CAMALLOC(&pService->pSslLabel,
ICP_QAT_FW_LA_SSL_LABEL_LEN_MAX,
LAC_8BYTE_ALIGNMENT,
pService->nodeAffinity);
} else {
status = CPA_STATUS_RESOURCE;
}
if (CPA_STATUS_SUCCESS == status) {
Cpa32U i = 0;
Cpa32U offset = 0;
for (i = 0; i < ICP_QAT_FW_LA_SSL_ITERATES_LEN_MAX; i++) {
memset(pService->pSslLabel + offset, 'A' + i, i + 1);
offset += (i + 1);
}
status = LAC_OS_CAMALLOC(&pService->pTlsLabel,
sizeof(lac_sym_key_tls_labels_t),
LAC_8BYTE_ALIGNMENT,
pService->nodeAffinity);
}
if (CPA_STATUS_SUCCESS == status) {
status =
LAC_OS_CAMALLOC(&pService->pTlsHKDFSubLabel,
sizeof(lac_sym_key_tls_hkdf_sub_labels_t),
LAC_8BYTE_ALIGNMENT,
pService->nodeAffinity);
}
if (CPA_STATUS_SUCCESS == status) {
LAC_OS_BZERO(pService->pTlsLabel,
sizeof(lac_sym_key_tls_labels_t));
memcpy(pService->pTlsLabel->masterSecret,
LAC_SYM_KEY_TLS_MASTER_SECRET_LABEL,
sizeof(LAC_SYM_KEY_TLS_MASTER_SECRET_LABEL) - 1);
memcpy(pService->pTlsLabel->keyMaterial,
LAC_SYM_KEY_TLS_KEY_MATERIAL_LABEL,
sizeof(LAC_SYM_KEY_TLS_KEY_MATERIAL_LABEL) - 1);
memcpy(pService->pTlsLabel->clientFinished,
LAC_SYM_KEY_TLS_CLIENT_FIN_LABEL,
sizeof(LAC_SYM_KEY_TLS_CLIENT_FIN_LABEL) - 1);
memcpy(pService->pTlsLabel->serverFinished,
LAC_SYM_KEY_TLS_SERVER_FIN_LABEL,
sizeof(LAC_SYM_KEY_TLS_SERVER_FIN_LABEL) - 1);
LAC_OS_BZERO(pService->pTlsHKDFSubLabel,
sizeof(lac_sym_key_tls_hkdf_sub_labels_t));
memcpy(&pService->pTlsHKDFSubLabel->keySublabel256,
&key256,
HKDF_SUB_LABEL_KEY_LENGTH);
pService->pTlsHKDFSubLabel->keySublabel256.labelLen =
HKDF_SUB_LABEL_KEY_LENGTH;
pService->pTlsHKDFSubLabel->keySublabel256.sublabelFlag = 1
<< QAT_FW_HKDF_INNER_SUBLABEL_16_BYTE_OKM_BITPOS;
memcpy(&pService->pTlsHKDFSubLabel->keySublabel384,
&key384,
HKDF_SUB_LABEL_KEY_LENGTH);
pService->pTlsHKDFSubLabel->keySublabel384.labelLen =
HKDF_SUB_LABEL_KEY_LENGTH;
pService->pTlsHKDFSubLabel->keySublabel384.sublabelFlag = 1
<< QAT_FW_HKDF_INNER_SUBLABEL_32_BYTE_OKM_BITPOS;
memcpy(&pService->pTlsHKDFSubLabel->keySublabelChaChaPoly,
&keyChaChaPoly,
HKDF_SUB_LABEL_KEY_LENGTH);
pService->pTlsHKDFSubLabel->keySublabelChaChaPoly.labelLen =
HKDF_SUB_LABEL_KEY_LENGTH;
pService->pTlsHKDFSubLabel->keySublabelChaChaPoly.sublabelFlag =
1 << QAT_FW_HKDF_INNER_SUBLABEL_32_BYTE_OKM_BITPOS;
memcpy(&pService->pTlsHKDFSubLabel->ivSublabel256,
&iv256,
HKDF_SUB_LABEL_IV_LENGTH);
pService->pTlsHKDFSubLabel->ivSublabel256.labelLen =
HKDF_SUB_LABEL_IV_LENGTH;
pService->pTlsHKDFSubLabel->ivSublabel256.sublabelFlag = 1
<< QAT_FW_HKDF_INNER_SUBLABEL_12_BYTE_OKM_BITPOS;
memcpy(&pService->pTlsHKDFSubLabel->ivSublabel384,
&iv384,
HKDF_SUB_LABEL_IV_LENGTH);
pService->pTlsHKDFSubLabel->ivSublabel384.labelLen =
HKDF_SUB_LABEL_IV_LENGTH;
pService->pTlsHKDFSubLabel->ivSublabel384.sublabelFlag = 1
<< QAT_FW_HKDF_INNER_SUBLABEL_12_BYTE_OKM_BITPOS;
memcpy(&pService->pTlsHKDFSubLabel->ivSublabelChaChaPoly,
&iv256,
HKDF_SUB_LABEL_IV_LENGTH);
pService->pTlsHKDFSubLabel->ivSublabelChaChaPoly.labelLen =
HKDF_SUB_LABEL_IV_LENGTH;
pService->pTlsHKDFSubLabel->ivSublabelChaChaPoly.sublabelFlag =
1 << QAT_FW_HKDF_INNER_SUBLABEL_12_BYTE_OKM_BITPOS;
memcpy(&pService->pTlsHKDFSubLabel->resumptionSublabel256,
&resumption256,
HKDF_SUB_LABEL_RESUMPTION_LENGTH);
pService->pTlsHKDFSubLabel->resumptionSublabel256.labelLen =
HKDF_SUB_LABEL_RESUMPTION_LENGTH;
memcpy(&pService->pTlsHKDFSubLabel->resumptionSublabel384,
&resumption384,
HKDF_SUB_LABEL_RESUMPTION_LENGTH);
pService->pTlsHKDFSubLabel->resumptionSublabel384.labelLen =
HKDF_SUB_LABEL_RESUMPTION_LENGTH;
memcpy(
&pService->pTlsHKDFSubLabel->resumptionSublabelChaChaPoly,
&resumption256,
HKDF_SUB_LABEL_RESUMPTION_LENGTH);
pService->pTlsHKDFSubLabel->resumptionSublabelChaChaPoly
.labelLen = HKDF_SUB_LABEL_RESUMPTION_LENGTH;
memcpy(&pService->pTlsHKDFSubLabel->finishedSublabel256,
&finished256,
HKDF_SUB_LABEL_FINISHED_LENGTH);
pService->pTlsHKDFSubLabel->finishedSublabel256.labelLen =
HKDF_SUB_LABEL_FINISHED_LENGTH;
memcpy(&pService->pTlsHKDFSubLabel->finishedSublabel384,
&finished384,
HKDF_SUB_LABEL_FINISHED_LENGTH);
pService->pTlsHKDFSubLabel->finishedSublabel384.labelLen =
HKDF_SUB_LABEL_FINISHED_LENGTH;
memcpy(&pService->pTlsHKDFSubLabel->finishedSublabelChaChaPoly,
&finished256,
HKDF_SUB_LABEL_FINISHED_LENGTH);
pService->pTlsHKDFSubLabel->finishedSublabelChaChaPoly
.labelLen = HKDF_SUB_LABEL_FINISHED_LENGTH;
pService->pTlsHKDFSubLabel->sublabelPhysAddr256 =
LAC_OS_VIRT_TO_PHYS_INTERNAL(
&pService->pTlsHKDFSubLabel->keySublabel256);
pService->pTlsHKDFSubLabel->sublabelPhysAddr384 =
LAC_OS_VIRT_TO_PHYS_INTERNAL(
&pService->pTlsHKDFSubLabel->keySublabel384);
pService->pTlsHKDFSubLabel->sublabelPhysAddrChaChaPoly =
LAC_OS_VIRT_TO_PHYS_INTERNAL(
&pService->pTlsHKDFSubLabel->keySublabelChaChaPoly);
LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE,
LacSymKey_SslTlsHandleResponse);
LacSymQat_RespHandlerRegister(
ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE,
LacSymKey_SslTlsHandleResponse);
LacSymQat_RespHandlerRegister(
ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE,
LacSymKey_SslTlsHandleResponse);
LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_HKDF_EXTRACT,
LacSymKey_SslTlsHandleResponse);
LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_HKDF_EXPAND,
LacSymKey_SslTlsHandleResponse);
LacSymQat_RespHandlerRegister(
ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND,
LacSymKey_SslTlsHandleResponse);
LacSymQat_RespHandlerRegister(
ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL,
LacSymKey_SslTlsHandleResponse);
LacSymQat_RespHandlerRegister(
ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL,
LacSymKey_SslTlsHandleResponse);
LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_MGF1,
LacSymKey_MgfHandleResponse);
}
if (CPA_STATUS_SUCCESS != status) {
LAC_OS_FREE(pService->pLacKeyStats);
LAC_OS_CAFREE(pService->pSslLabel);
LAC_OS_CAFREE(pService->pTlsLabel);
LAC_OS_CAFREE(pService->pTlsHKDFSubLabel);
}
return status;
}
CpaStatus
LacSymKey_Shutdown(CpaInstanceHandle instanceHandle_in)
{
CpaStatus status = CPA_STATUS_SUCCESS;
CpaInstanceHandle instanceHandle = LacKey_GetHandle(instanceHandle_in);
sal_crypto_service_t *pService = NULL;
LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
pService = (sal_crypto_service_t *)instanceHandle;
if (NULL != pService->pLacKeyStats) {
LAC_OS_FREE(pService->pLacKeyStats);
}
LAC_OS_CAFREE(pService->pSslLabel);
LAC_OS_CAFREE(pService->pTlsLabel);
LAC_OS_CAFREE(pService->pTlsHKDFSubLabel);
return status;
}