1/* SPDX-License-Identifier: BSD-3-Clause */ 2/* Copyright(c) 2007-2022 Intel Corporation */ 3 4/** 5 ***************************************************************************** 6 * @file lac_sym_qat.c Interfaces for populating the symmetric qat structures 7 * 8 * @ingroup LacSymQat 9 * 10 *****************************************************************************/ 11 12/* 13******************************************************************************* 14* Include public/global header files 15******************************************************************************* 16*/ 17#include "cpa.h" 18 19/* 20******************************************************************************* 21* Include private header files 22******************************************************************************* 23*/ 24#include "icp_accel_devices.h" 25#include "icp_adf_cfg.h" 26#include "lac_log.h" 27#include "lac_sym.h" 28#include "lac_sym_qat.h" 29#include "lac_sal_types_crypto.h" 30#include "sal_string_parse.h" 31#include "lac_sym_key.h" 32#include "lac_sym_qat_hash_defs_lookup.h" 33#include "lac_sym_qat_constants_table.h" 34#include "lac_sym_qat_cipher.h" 35#include "lac_sym_qat_hash.h" 36 37#define EMBEDDED_CIPHER_KEY_MAX_SIZE 16 38static void 39LacSymQat_SymLogSliceHangError(icp_qat_fw_la_cmd_id_t symCmdId) 40{ 41 Cpa8U cmdId = symCmdId; 42 43 switch (cmdId) { 44 case ICP_QAT_FW_LA_CMD_CIPHER: 45 case ICP_QAT_FW_LA_CMD_CIPHER_PRE_COMP: 46 LAC_LOG_ERROR("slice hang detected on CPM cipher slice."); 47 break; 48 49 case ICP_QAT_FW_LA_CMD_AUTH: 50 case ICP_QAT_FW_LA_CMD_AUTH_PRE_COMP: 51 LAC_LOG_ERROR("slice hang detected on CPM auth slice."); 52 break; 53 54 case ICP_QAT_FW_LA_CMD_CIPHER_HASH: 55 case ICP_QAT_FW_LA_CMD_HASH_CIPHER: 56 case ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE: 57 case ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE: 58 case ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE: 59 case ICP_QAT_FW_LA_CMD_MGF1: 60 default: 61 LAC_LOG_ERROR( 62 "slice hang detected on CPM cipher or auth slice."); 63 } 64 return; 65} 66 67/* sym crypto response handlers */ 68static sal_qat_resp_handler_func_t 69 respHandlerSymTbl[ICP_QAT_FW_LA_CMD_DELIMITER]; 70 71void 72LacSymQat_SymRespHandler(void *pRespMsg) 73{ 74 Cpa8U lacCmdId = 0; 75 void *pOpaqueData = NULL; 76 icp_qat_fw_la_resp_t *pRespMsgFn = NULL; 77 Cpa8U opStatus = ICP_QAT_FW_COMN_STATUS_FLAG_OK; 78 Cpa8U comnErr = ERR_CODE_NO_ERROR; 79 80 pRespMsgFn = (icp_qat_fw_la_resp_t *)pRespMsg; 81 LAC_MEM_SHARED_READ_TO_PTR(pRespMsgFn->opaque_data, pOpaqueData); 82 83 lacCmdId = pRespMsgFn->comn_resp.cmd_id; 84 opStatus = pRespMsgFn->comn_resp.comn_status; 85 comnErr = pRespMsgFn->comn_resp.comn_error.s.comn_err_code; 86 87 /* log the slice hang and endpoint push/pull error inside the response 88 */ 89 if (ERR_CODE_SSM_ERROR == (Cpa8S)comnErr) { 90 LacSymQat_SymLogSliceHangError(lacCmdId); 91 } else if (ERR_CODE_ENDPOINT_ERROR == (Cpa8S)comnErr) { 92 LAC_LOG_ERROR("The PCIe End Point Push/Pull or" 93 " TI/RI Parity error detected."); 94 } 95 96 /* call the response message handler registered for the command ID */ 97 respHandlerSymTbl[lacCmdId]((icp_qat_fw_la_cmd_id_t)lacCmdId, 98 pOpaqueData, 99 (icp_qat_fw_comn_flags)opStatus); 100} 101 102CpaStatus 103LacSymQat_Init(CpaInstanceHandle instanceHandle) 104{ 105 CpaStatus status = CPA_STATUS_SUCCESS; 106 107 /* Initialize the SHRAM constants table */ 108 LacSymQat_ConstantsInitLookupTables(instanceHandle); 109 110 /* Initialise the Hash lookup table */ 111 status = LacSymQat_HashLookupInit(instanceHandle); 112 113 return status; 114} 115 116void 117LacSymQat_RespHandlerRegister(icp_qat_fw_la_cmd_id_t lacCmdId, 118 sal_qat_resp_handler_func_t pCbHandler) 119{ 120 if (lacCmdId >= ICP_QAT_FW_LA_CMD_DELIMITER) { 121 QAT_UTILS_LOG("Invalid Command ID\n"); 122 return; 123 } 124 125 /* set the response handler for the command ID */ 126 respHandlerSymTbl[lacCmdId] = pCbHandler; 127} 128 129void 130LacSymQat_LaPacketCommandFlagSet(Cpa32U qatPacketType, 131 icp_qat_fw_la_cmd_id_t laCmdId, 132 CpaCySymCipherAlgorithm cipherAlgorithm, 133 Cpa16U *pLaCommandFlags, 134 Cpa32U ivLenInBytes) 135{ 136 /* For SM4/Chacha ciphers set command flag as partial none to proceed 137 * with stateless processing */ 138 if (LAC_CIPHER_IS_SM4(cipherAlgorithm) || 139 LAC_CIPHER_IS_CHACHA(cipherAlgorithm)) { 140 ICP_QAT_FW_LA_PARTIAL_SET(*pLaCommandFlags, 141 ICP_QAT_FW_LA_PARTIAL_NONE); 142 return; 143 } 144 ICP_QAT_FW_LA_PARTIAL_SET(*pLaCommandFlags, qatPacketType); 145 146 /* For ECB-mode ciphers, IV is NULL so update-state flag 147 * must be disabled always. 148 * For all other ciphers and auth 149 * update state is disabled for full packets and final partials */ 150 if ((ICP_QAT_FW_LA_PARTIAL_NONE == qatPacketType) || 151 (ICP_QAT_FW_LA_PARTIAL_END == qatPacketType) || 152 ((laCmdId != ICP_QAT_FW_LA_CMD_AUTH) && 153 LAC_CIPHER_IS_ECB_MODE(cipherAlgorithm))) { 154 ICP_QAT_FW_LA_UPDATE_STATE_SET(*pLaCommandFlags, 155 ICP_QAT_FW_LA_NO_UPDATE_STATE); 156 } 157 /* For first or middle partials set the update state command flag */ 158 else { 159 ICP_QAT_FW_LA_UPDATE_STATE_SET(*pLaCommandFlags, 160 ICP_QAT_FW_LA_UPDATE_STATE); 161 162 if (laCmdId == ICP_QAT_FW_LA_CMD_AUTH) { 163 /* For hash only partial - verify and return auth result 164 * are 165 * disabled */ 166 ICP_QAT_FW_LA_RET_AUTH_SET( 167 *pLaCommandFlags, ICP_QAT_FW_LA_NO_RET_AUTH_RES); 168 169 ICP_QAT_FW_LA_CMP_AUTH_SET( 170 *pLaCommandFlags, ICP_QAT_FW_LA_NO_CMP_AUTH_RES); 171 } 172 } 173 174 if ((LAC_CIPHER_IS_GCM(cipherAlgorithm)) && 175 (LAC_CIPHER_IV_SIZE_GCM_12 == ivLenInBytes)) 176 177 { 178 ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET( 179 *pLaCommandFlags, ICP_QAT_FW_LA_GCM_IV_LEN_12_OCTETS); 180 } 181} 182 183void 184LacSymQat_packetTypeGet(CpaCySymPacketType packetType, 185 CpaCySymPacketType packetState, 186 Cpa32U *pQatPacketType) 187{ 188 switch (packetType) { 189 /* partial */ 190 case CPA_CY_SYM_PACKET_TYPE_PARTIAL: 191 /* if the previous state was full, then this is the first packet 192 */ 193 if (CPA_CY_SYM_PACKET_TYPE_FULL == packetState) { 194 *pQatPacketType = ICP_QAT_FW_LA_PARTIAL_START; 195 } else { 196 *pQatPacketType = ICP_QAT_FW_LA_PARTIAL_MID; 197 } 198 break; 199 200 /* final partial */ 201 case CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL: 202 *pQatPacketType = ICP_QAT_FW_LA_PARTIAL_END; 203 break; 204 205 /* full packet - CPA_CY_SYM_PACKET_TYPE_FULL */ 206 default: 207 *pQatPacketType = ICP_QAT_FW_LA_PARTIAL_NONE; 208 } 209} 210 211void 212LacSymQat_LaSetDefaultFlags(icp_qat_fw_serv_specif_flags *laCmdFlags, 213 CpaCySymOp symOp) 214{ 215 216 ICP_QAT_FW_LA_PARTIAL_SET(*laCmdFlags, ICP_QAT_FW_LA_PARTIAL_NONE); 217 218 ICP_QAT_FW_LA_UPDATE_STATE_SET(*laCmdFlags, 219 ICP_QAT_FW_LA_NO_UPDATE_STATE); 220 221 if (symOp != CPA_CY_SYM_OP_CIPHER) { 222 ICP_QAT_FW_LA_RET_AUTH_SET(*laCmdFlags, 223 ICP_QAT_FW_LA_RET_AUTH_RES); 224 } else { 225 ICP_QAT_FW_LA_RET_AUTH_SET(*laCmdFlags, 226 ICP_QAT_FW_LA_NO_RET_AUTH_RES); 227 } 228 229 ICP_QAT_FW_LA_CMP_AUTH_SET(*laCmdFlags, ICP_QAT_FW_LA_NO_CMP_AUTH_RES); 230 231 ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET( 232 *laCmdFlags, ICP_QAT_FW_LA_GCM_IV_LEN_NOT_12_OCTETS); 233} 234 235CpaBoolean 236LacSymQat_UseSymConstantsTable(lac_session_desc_t *pSession, 237 Cpa8U *pCipherOffset, 238 Cpa8U *pHashOffset) 239{ 240 241 CpaBoolean useOptimisedContentDesc = CPA_FALSE; 242 CpaBoolean useSHRAMConstants = CPA_FALSE; 243 244 *pCipherOffset = 0; 245 *pHashOffset = 0; 246 247 /* for chaining can we use the optimised content descritor */ 248 if (pSession->laCmdId == ICP_QAT_FW_LA_CMD_CIPHER_HASH || 249 pSession->laCmdId == ICP_QAT_FW_LA_CMD_HASH_CIPHER) { 250 useOptimisedContentDesc = 251 LacSymQat_UseOptimisedContentDesc(pSession); 252 } 253 254 /* Cipher-only case or chaining */ 255 if (pSession->laCmdId == ICP_QAT_FW_LA_CMD_CIPHER || 256 useOptimisedContentDesc) { 257 icp_qat_hw_cipher_algo_t algorithm; 258 icp_qat_hw_cipher_mode_t mode; 259 icp_qat_hw_cipher_dir_t dir; 260 icp_qat_hw_cipher_convert_t key_convert; 261 262 if (pSession->cipherKeyLenInBytes > 263 sizeof(icp_qat_fw_comn_req_hdr_cd_pars_t)) { 264 return CPA_FALSE; 265 } 266 267 LacSymQat_CipherGetCfgData( 268 pSession, &algorithm, &mode, &dir, &key_convert); 269 270 /* Check if cipher config is available in table. */ 271 LacSymQat_ConstantsGetCipherOffset(pSession->pInstance, 272 algorithm, 273 mode, 274 dir, 275 key_convert, 276 pCipherOffset); 277 if (*pCipherOffset > 0) { 278 useSHRAMConstants = CPA_TRUE; 279 } else { 280 useSHRAMConstants = CPA_FALSE; 281 } 282 } 283 284 /* hash only case or when chaining, cipher must be found in SHRAM table 285 * for 286 * optimised CD case */ 287 if (pSession->laCmdId == ICP_QAT_FW_LA_CMD_AUTH || 288 (useOptimisedContentDesc && useSHRAMConstants)) { 289 icp_qat_hw_auth_algo_t algorithm; 290 CpaBoolean nested; 291 292 if (pSession->digestVerify) { 293 return CPA_FALSE; 294 } 295 296 if ((!(useOptimisedContentDesc && useSHRAMConstants)) && 297 (pSession->qatHashMode == ICP_QAT_HW_AUTH_MODE1)) { 298 /* we can only use the SHA1-mode1 in the SHRAM constants 299 * table when 300 * we are using the opimised content desc */ 301 return CPA_FALSE; 302 } 303 304 LacSymQat_HashGetCfgData(pSession->pInstance, 305 pSession->qatHashMode, 306 pSession->hashMode, 307 pSession->hashAlgorithm, 308 &algorithm, 309 &nested); 310 311 /* Check if config data is available in table. */ 312 LacSymQat_ConstantsGetAuthOffset(pSession->pInstance, 313 algorithm, 314 pSession->qatHashMode, 315 nested, 316 pHashOffset); 317 if (*pHashOffset > 0) { 318 useSHRAMConstants = CPA_TRUE; 319 } else { 320 useSHRAMConstants = CPA_FALSE; 321 } 322 } 323 324 return useSHRAMConstants; 325} 326 327CpaBoolean 328LacSymQat_UseOptimisedContentDesc(lac_session_desc_t *pSession) 329{ 330 return CPA_FALSE; 331} 332