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
38 static void
LacSymQat_SymLogSliceHangError(icp_qat_fw_la_cmd_id_t symCmdId)39 LacSymQat_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 */
68 static sal_qat_resp_handler_func_t
69 respHandlerSymTbl[ICP_QAT_FW_LA_CMD_DELIMITER];
70
71 void
LacSymQat_SymRespHandler(void * pRespMsg)72 LacSymQat_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
102 CpaStatus
LacSymQat_Init(CpaInstanceHandle instanceHandle)103 LacSymQat_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
116 void
LacSymQat_RespHandlerRegister(icp_qat_fw_la_cmd_id_t lacCmdId,sal_qat_resp_handler_func_t pCbHandler)117 LacSymQat_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
129 void
LacSymQat_LaPacketCommandFlagSet(Cpa32U qatPacketType,icp_qat_fw_la_cmd_id_t laCmdId,CpaCySymCipherAlgorithm cipherAlgorithm,Cpa16U * pLaCommandFlags,Cpa32U ivLenInBytes)130 LacSymQat_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
183 void
LacSymQat_packetTypeGet(CpaCySymPacketType packetType,CpaCySymPacketType packetState,Cpa32U * pQatPacketType)184 LacSymQat_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
211 void
LacSymQat_LaSetDefaultFlags(icp_qat_fw_serv_specif_flags * laCmdFlags,CpaCySymOp symOp)212 LacSymQat_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
235 CpaBoolean
LacSymQat_UseSymConstantsTable(lac_session_desc_t * pSession,Cpa8U * pCipherOffset,Cpa8U * pHashOffset)236 LacSymQat_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
327 CpaBoolean
LacSymQat_UseOptimisedContentDesc(lac_session_desc_t * pSession)328 LacSymQat_UseOptimisedContentDesc(lac_session_desc_t *pSession)
329 {
330 return CPA_FALSE;
331 }
332