1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2025 Intel Corporation */
3
4 /**
5 ***************************************************************************
6 * @file lac_sym_cipher.c Cipher
7 *
8 * @ingroup LacCipher
9 *
10 * @description Functions specific to cipher
11 ***************************************************************************/
12
13 /*
14 *******************************************************************************
15 * Include public/global header files
16 *******************************************************************************
17 */
18 #include "cpa.h"
19 #include "cpa_cy_sym.h"
20
21 #include "icp_adf_init.h"
22 #include "icp_adf_transport.h"
23 #include "icp_accel_devices.h"
24 #include "icp_adf_debug.h"
25
26 #include "icp_qat_fw_la.h"
27
28 /*
29 *******************************************************************************
30 * Include private header files
31 *******************************************************************************
32 */
33 #include "lac_sym_cipher.h"
34 #include "lac_session.h"
35 #include "lac_mem.h"
36 #include "lac_common.h"
37 #include "lac_list.h"
38 #include "lac_sym.h"
39 #include "lac_sym_key.h"
40 #include "lac_sym_qat_hash_defs_lookup.h"
41 #include "lac_sal_types_crypto.h"
42 #include "lac_sal.h"
43 #include "lac_sal_ctrl.h"
44 #include "lac_sym_cipher_defs.h"
45 #include "lac_sym_cipher.h"
46 #include "lac_sym_stats.h"
47 #include "lac_sym.h"
48 #include "lac_sym_qat_cipher.h"
49 #include "lac_log.h"
50 #include "lac_buffer_desc.h"
51 #include "sal_hw_gen.h"
52
53 /*
54 *******************************************************************************
55 * Static Variables
56 *******************************************************************************
57 */
58
59 CpaStatus
LacCipher_PerformIvCheck(sal_service_t * pService,lac_sym_bulk_cookie_t * pCbCookie,Cpa32U qatPacketType,Cpa8U ** ppIvBuffer)60 LacCipher_PerformIvCheck(sal_service_t *pService,
61 lac_sym_bulk_cookie_t *pCbCookie,
62 Cpa32U qatPacketType,
63 Cpa8U **ppIvBuffer)
64 {
65 const CpaCySymOpData *pOpData = pCbCookie->pOpData;
66 lac_session_desc_t *pSessionDesc =
67 LAC_SYM_SESSION_DESC_FROM_CTX_GET(pOpData->sessionCtx);
68 CpaCySymCipherAlgorithm algorithm = pSessionDesc->cipherAlgorithm;
69 unsigned ivLenInBytes = 0;
70
71 switch (algorithm) {
72 /* Perform IV check for CTR, CBC, XTS, F8 MODE. */
73 case CPA_CY_SYM_CIPHER_AES_CTR:
74 case CPA_CY_SYM_CIPHER_3DES_CTR:
75 case CPA_CY_SYM_CIPHER_SM4_CTR:
76 case CPA_CY_SYM_CIPHER_AES_CCM:
77 case CPA_CY_SYM_CIPHER_AES_GCM:
78 case CPA_CY_SYM_CIPHER_CHACHA:
79 case CPA_CY_SYM_CIPHER_AES_CBC:
80 case CPA_CY_SYM_CIPHER_DES_CBC:
81 case CPA_CY_SYM_CIPHER_3DES_CBC:
82 case CPA_CY_SYM_CIPHER_SM4_CBC:
83 case CPA_CY_SYM_CIPHER_AES_F8:
84 case CPA_CY_SYM_CIPHER_AES_XTS: {
85 ivLenInBytes = LacSymQat_CipherIvSizeBytesGet(algorithm);
86 LAC_CHECK_NULL_PARAM(pOpData->pIv);
87 if (pOpData->ivLenInBytes != ivLenInBytes) {
88 if (!(/* GCM with 12 byte IV is OK */
89 (LAC_CIPHER_IS_GCM(algorithm) &&
90 pOpData->ivLenInBytes ==
91 LAC_CIPHER_IV_SIZE_GCM_12) ||
92 /* IV len for CCM has been checked before */
93 LAC_CIPHER_IS_CCM(algorithm))) {
94 LAC_INVALID_PARAM_LOG("invalid cipher IV size");
95 return CPA_STATUS_INVALID_PARAM;
96 }
97 }
98
99 /* Always copy the user's IV into another cipher state buffer if
100 * the request is part of a partial packet sequence
101 * (ensures that pipelined partial requests use same
102 * buffer)
103 */
104 if (ICP_QAT_FW_LA_PARTIAL_NONE == qatPacketType) {
105 /* Set the value of the ppIvBuffer to that supplied
106 * by the user.
107 * NOTE: There is no guarantee that this address is
108 * aligned on an 8 or 64 Byte address. */
109 *ppIvBuffer = pOpData->pIv;
110 } else {
111 /* For partial packets, we use a per-session buffer to
112 * maintain the IV. This allows us to easily pass the
113 * updated IV forward to the next partial in the
114 * sequence. This makes internal buffering of partials
115 * easier to implement.
116 */
117 *ppIvBuffer = pSessionDesc->cipherPartialOpState;
118
119 /* Ensure that the user's IV buffer gets updated between
120 * partial requests so that they may also see the
121 * residue from the previous partial. Not needed for
122 * final partials though.
123 */
124 if ((ICP_QAT_FW_LA_PARTIAL_START == qatPacketType) ||
125 (ICP_QAT_FW_LA_PARTIAL_MID == qatPacketType)) {
126 pCbCookie->updateUserIvOnRecieve = CPA_TRUE;
127
128 if (ICP_QAT_FW_LA_PARTIAL_START ==
129 qatPacketType) {
130 /* if the previous partial state was
131 * full, then this is the first partial
132 * in the sequence so we need to copy in
133 * the user's IV. But, we have to be
134 * very careful here not to overwrite
135 * the cipherPartialOpState just yet in
136 * case there's a previous partial
137 * sequence in flight, so we defer the
138 * copy for now. This will be completed
139 * in the LacSymQueue_RequestSend()
140 * function.
141 */
142 pCbCookie->updateSessionIvOnSend =
143 CPA_TRUE;
144 }
145 /* For subsequent partials in a sequence, we'll
146 * reuse the IV that was written back by the
147 * QAT, using internal request queueing if
148 * necessary to ensure that the next partial
149 * request isn't issued to the QAT until the
150 * previous one completes
151 */
152 }
153 }
154 } break;
155 case CPA_CY_SYM_CIPHER_KASUMI_F8: {
156 LAC_CHECK_NULL_PARAM(pOpData->pIv);
157
158 if (pOpData->ivLenInBytes != LAC_CIPHER_KASUMI_F8_IV_LENGTH) {
159 LAC_INVALID_PARAM_LOG("invalid cipher IV size");
160 return CPA_STATUS_INVALID_PARAM;
161 }
162
163 *ppIvBuffer = pOpData->pIv;
164 } break;
165 case CPA_CY_SYM_CIPHER_SNOW3G_UEA2: {
166 LAC_CHECK_NULL_PARAM(pOpData->pIv);
167 if (pOpData->ivLenInBytes != ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ) {
168 LAC_INVALID_PARAM_LOG("invalid cipher IV size");
169 return CPA_STATUS_INVALID_PARAM;
170 }
171 *ppIvBuffer = pOpData->pIv;
172 } break;
173 case CPA_CY_SYM_CIPHER_ARC4: {
174 if (ICP_QAT_FW_LA_PARTIAL_NONE == qatPacketType) {
175 /* For full packets, the initial ARC4 state is stored in
176 * the session descriptor. Use it directly.
177 */
178 *ppIvBuffer = pSessionDesc->cipherARC4InitialState;
179 } else {
180 /* For partial packets, we maintain the running ARC4
181 * state in dedicated buffer in the session descriptor
182 */
183 *ppIvBuffer = pSessionDesc->cipherPartialOpState;
184
185 if (ICP_QAT_FW_LA_PARTIAL_START == qatPacketType) {
186 /* if the previous partial state was full, then
187 * this is the first partial in the sequence so
188 * we need to (re-)initialise the contents of
189 * the state buffer using the initial state that
190 * is stored in the session descriptor. But, we
191 * have to be very careful here not to overwrite
192 * the cipherPartialOpState just yet in case
193 * there's a previous partial sequence in
194 * flight, so we defer the copy for now. This
195 * will be completed in the
196 * LacSymQueue_RequestSend() function when clear
197 * to send.
198 */
199 pCbCookie->updateSessionIvOnSend = CPA_TRUE;
200 }
201 }
202 } break;
203 case CPA_CY_SYM_CIPHER_ZUC_EEA3: {
204 LAC_CHECK_NULL_PARAM(pOpData->pIv);
205 if (pOpData->ivLenInBytes != ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ) {
206 LAC_INVALID_PARAM_LOG("invalid cipher IV size");
207 return CPA_STATUS_INVALID_PARAM;
208 }
209 *ppIvBuffer = pOpData->pIv;
210 } break;
211 default:
212 *ppIvBuffer = NULL;
213 }
214
215 return CPA_STATUS_SUCCESS;
216 }
217
218 CpaStatus
LacCipher_SessionSetupDataCheck(const CpaCySymCipherSetupData * pCipherSetupData,Cpa32U capabilitiesMask)219 LacCipher_SessionSetupDataCheck(const CpaCySymCipherSetupData *pCipherSetupData,
220 Cpa32U capabilitiesMask)
221 {
222 /* No key required for NULL algorithm */
223 if (!LAC_CIPHER_IS_NULL(pCipherSetupData->cipherAlgorithm)) {
224 LAC_CHECK_NULL_PARAM(pCipherSetupData->pCipherKey);
225
226 /* Check that algorithm and keys passed in are correct size */
227 switch (pCipherSetupData->cipherAlgorithm) {
228 case CPA_CY_SYM_CIPHER_ARC4:
229 if (pCipherSetupData->cipherKeyLenInBytes >
230 ICP_QAT_HW_ARC4_KEY_SZ) {
231 LAC_INVALID_PARAM_LOG(
232 "Invalid ARC4 cipher key length");
233 return CPA_STATUS_INVALID_PARAM;
234 }
235 break;
236 case CPA_CY_SYM_CIPHER_AES_CCM:
237 if (!LAC_CIPHER_AES_V2(capabilitiesMask) &&
238 pCipherSetupData->cipherKeyLenInBytes !=
239 ICP_QAT_HW_AES_128_KEY_SZ) {
240 LAC_INVALID_PARAM_LOG(
241 "Invalid AES CCM cipher key length");
242 return CPA_STATUS_INVALID_PARAM;
243 }
244 break;
245 case CPA_CY_SYM_CIPHER_AES_XTS:
246 if ((pCipherSetupData->cipherKeyLenInBytes !=
247 ICP_QAT_HW_AES_128_XTS_KEY_SZ) &&
248 (pCipherSetupData->cipherKeyLenInBytes !=
249 ICP_QAT_HW_AES_256_XTS_KEY_SZ) &&
250 (pCipherSetupData->cipherKeyLenInBytes !=
251 ICP_QAT_HW_UCS_AES_128_XTS_KEY_SZ) &&
252 (pCipherSetupData->cipherKeyLenInBytes !=
253 ICP_QAT_HW_UCS_AES_256_XTS_KEY_SZ)) {
254 LAC_INVALID_PARAM_LOG(
255 "Invalid AES XTS cipher key length");
256 return CPA_STATUS_INVALID_PARAM;
257 }
258 break;
259 case CPA_CY_SYM_CIPHER_AES_ECB:
260 case CPA_CY_SYM_CIPHER_AES_CBC:
261 case CPA_CY_SYM_CIPHER_AES_CTR:
262 case CPA_CY_SYM_CIPHER_AES_GCM:
263 if ((pCipherSetupData->cipherKeyLenInBytes !=
264 ICP_QAT_HW_AES_128_KEY_SZ) &&
265 (pCipherSetupData->cipherKeyLenInBytes !=
266 ICP_QAT_HW_AES_192_KEY_SZ) &&
267 (pCipherSetupData->cipherKeyLenInBytes !=
268 ICP_QAT_HW_AES_256_KEY_SZ)) {
269 LAC_INVALID_PARAM_LOG(
270 "Invalid AES cipher key length");
271 return CPA_STATUS_INVALID_PARAM;
272 }
273 break;
274 case CPA_CY_SYM_CIPHER_AES_F8:
275 if ((pCipherSetupData->cipherKeyLenInBytes !=
276 ICP_QAT_HW_AES_128_F8_KEY_SZ) &&
277 (pCipherSetupData->cipherKeyLenInBytes !=
278 ICP_QAT_HW_AES_192_F8_KEY_SZ) &&
279 (pCipherSetupData->cipherKeyLenInBytes !=
280 ICP_QAT_HW_AES_256_F8_KEY_SZ)) {
281 LAC_INVALID_PARAM_LOG(
282 "Invalid AES cipher key length");
283 return CPA_STATUS_INVALID_PARAM;
284 }
285 break;
286 case CPA_CY_SYM_CIPHER_DES_ECB:
287 case CPA_CY_SYM_CIPHER_DES_CBC:
288 if (pCipherSetupData->cipherKeyLenInBytes !=
289 ICP_QAT_HW_DES_KEY_SZ) {
290 LAC_INVALID_PARAM_LOG(
291 "Invalid DES cipher key length");
292 return CPA_STATUS_INVALID_PARAM;
293 }
294 break;
295 case CPA_CY_SYM_CIPHER_3DES_ECB:
296 case CPA_CY_SYM_CIPHER_3DES_CBC:
297 case CPA_CY_SYM_CIPHER_3DES_CTR:
298 if (pCipherSetupData->cipherKeyLenInBytes !=
299 ICP_QAT_HW_3DES_KEY_SZ) {
300 LAC_INVALID_PARAM_LOG(
301 "Invalid Triple-DES cipher key length");
302 return CPA_STATUS_INVALID_PARAM;
303 }
304 break;
305 case CPA_CY_SYM_CIPHER_KASUMI_F8:
306 /* QAT-FW only supports 128 bits Cipher Key size for
307 * Kasumi F8 Ref: 3GPP TS 55.216 V6.2.0 */
308 if (pCipherSetupData->cipherKeyLenInBytes !=
309 ICP_QAT_HW_KASUMI_KEY_SZ) {
310 LAC_INVALID_PARAM_LOG(
311 "Invalid Kasumi cipher key length");
312 return CPA_STATUS_INVALID_PARAM;
313 }
314 break;
315 case CPA_CY_SYM_CIPHER_SNOW3G_UEA2:
316 /* QAT-FW only supports 256 bits Cipher Key size for
317 * Snow_3G */
318 if (pCipherSetupData->cipherKeyLenInBytes !=
319 ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ) {
320 LAC_INVALID_PARAM_LOG(
321 "Invalid Snow_3G cipher key length");
322 return CPA_STATUS_INVALID_PARAM;
323 }
324 break;
325 case CPA_CY_SYM_CIPHER_ZUC_EEA3:
326 /* ZUC EEA3 */
327 if (pCipherSetupData->cipherKeyLenInBytes !=
328 ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) {
329 LAC_INVALID_PARAM_LOG(
330 "Invalid ZUC cipher key length");
331 return CPA_STATUS_INVALID_PARAM;
332 }
333 break;
334 case CPA_CY_SYM_CIPHER_CHACHA:
335 if (pCipherSetupData->cipherKeyLenInBytes !=
336 ICP_QAT_HW_CHACHAPOLY_KEY_SZ) {
337 LAC_INVALID_PARAM_LOG(
338 "Invalid CHACHAPOLY cipher key length");
339 return CPA_STATUS_INVALID_PARAM;
340 }
341 break;
342 case CPA_CY_SYM_CIPHER_SM4_ECB:
343 case CPA_CY_SYM_CIPHER_SM4_CBC:
344 case CPA_CY_SYM_CIPHER_SM4_CTR:
345 if (pCipherSetupData->cipherKeyLenInBytes !=
346 ICP_QAT_HW_SM4_KEY_SZ) {
347 LAC_INVALID_PARAM_LOG(
348 "Invalid SM4 cipher key length");
349 return CPA_STATUS_INVALID_PARAM;
350 }
351 break;
352 default:
353 LAC_INVALID_PARAM_LOG("Invalid cipher algorithm");
354 return CPA_STATUS_INVALID_PARAM;
355 }
356 }
357 return CPA_STATUS_SUCCESS;
358 }
359
360 CpaStatus
LacCipher_PerformParamCheck(CpaCySymCipherAlgorithm algorithm,const CpaCySymOpData * pOpData,const Cpa64U packetLen)361 LacCipher_PerformParamCheck(CpaCySymCipherAlgorithm algorithm,
362 const CpaCySymOpData *pOpData,
363 const Cpa64U packetLen)
364 {
365 CpaStatus status = CPA_STATUS_SUCCESS;
366
367 /* The following check will cover the dstBuffer as well, since
368 * the dstBuffer cannot be smaller than the srcBuffer (checked in
369 * LacSymPerform_BufferParamCheck() called from LacSym_Perform())
370 */
371 if ((pOpData->messageLenToCipherInBytes +
372 pOpData->cryptoStartSrcOffsetInBytes) > packetLen) {
373 LAC_INVALID_PARAM_LOG("cipher len + offset greater than "
374 "srcBuffer packet len");
375 status = CPA_STATUS_INVALID_PARAM;
376 } else {
377 /* Perform algorithm-specific checks */
378 switch (algorithm) {
379 case CPA_CY_SYM_CIPHER_ARC4:
380 case CPA_CY_SYM_CIPHER_AES_CTR:
381 case CPA_CY_SYM_CIPHER_3DES_CTR:
382 case CPA_CY_SYM_CIPHER_SM4_CTR:
383 case CPA_CY_SYM_CIPHER_AES_CCM:
384 case CPA_CY_SYM_CIPHER_AES_GCM:
385 case CPA_CY_SYM_CIPHER_CHACHA:
386 case CPA_CY_SYM_CIPHER_KASUMI_F8:
387 case CPA_CY_SYM_CIPHER_AES_F8:
388 case CPA_CY_SYM_CIPHER_SNOW3G_UEA2:
389 case CPA_CY_SYM_CIPHER_ZUC_EEA3:
390 /* No action needed */
391 break;
392 /*
393 * XTS Mode allow for ciphers which are not multiples of
394 * the block size.
395 */
396 case CPA_CY_SYM_CIPHER_AES_XTS:
397 if ((pOpData->packetType ==
398 CPA_CY_SYM_PACKET_TYPE_FULL) ||
399 (pOpData->packetType ==
400 CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL)) {
401 /*
402 * If this is the last of a partial request
403 */
404 if (pOpData->messageLenToCipherInBytes <
405 ICP_QAT_HW_AES_BLK_SZ) {
406 LAC_INVALID_PARAM_LOG(
407 "data size must be greater than block"
408 " size for last XTS partial or XTS "
409 "full packet");
410 status = CPA_STATUS_INVALID_PARAM;
411 }
412 }
413 break;
414 default:
415 /* Mask & check below is based on assumption that block
416 * size is a power of 2. If data size is not a multiple
417 * of the block size, the "remainder" bits selected by
418 * the mask be non-zero
419 */
420 if (pOpData->messageLenToCipherInBytes &
421 (LacSymQat_CipherBlockSizeBytesGet(algorithm) -
422 1)) {
423 LAC_INVALID_PARAM_LOG(
424 "data size must be block size"
425 " multiple");
426 status = CPA_STATUS_INVALID_PARAM;
427 }
428 }
429 }
430 return status;
431 }
432
433 Cpa32U
LacCipher_GetCipherSliceType(sal_crypto_service_t * pService,CpaCySymCipherAlgorithm cipherAlgorithm,CpaCySymHashAlgorithm hashAlgorithm)434 LacCipher_GetCipherSliceType(sal_crypto_service_t *pService,
435 CpaCySymCipherAlgorithm cipherAlgorithm,
436 CpaCySymHashAlgorithm hashAlgorithm)
437 {
438 Cpa32U sliceType = ICP_QAT_FW_LA_USE_LEGACY_SLICE_TYPE;
439 Cpa32U capabilitiesMask =
440 pService->generic_service_info.capabilitiesMask;
441
442 /* UCS Slice is supported only in Gen4 */
443 if (isCyGen4x(pService)) {
444 if (LAC_CIPHER_IS_XTS_MODE(cipherAlgorithm) ||
445 LAC_CIPHER_IS_CHACHA(cipherAlgorithm) ||
446 LAC_CIPHER_IS_GCM(cipherAlgorithm)) {
447 sliceType = ICP_QAT_FW_LA_USE_UCS_SLICE_TYPE;
448 } else if (LAC_CIPHER_IS_CCM(cipherAlgorithm) &&
449 LAC_CIPHER_AES_V2(capabilitiesMask)) {
450 sliceType = ICP_QAT_FW_LA_USE_LEGACY_SLICE_TYPE;
451 } else if (LAC_CIPHER_IS_AES(cipherAlgorithm) &&
452 LAC_CIPHER_IS_CTR_MODE(cipherAlgorithm)) {
453 sliceType = ICP_QAT_FW_LA_USE_UCS_SLICE_TYPE;
454 }
455 }
456
457 return sliceType;
458 }
459