1/* SPDX-License-Identifier: BSD-3-Clause */
2/* Copyright(c) 2007-2022 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
59CpaStatus
60LacCipher_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				 * re-use 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
219CpaStatus
220LacCipher_SessionSetupDataCheck(const CpaCySymCipherSetupData *pCipherSetupData,
221				Cpa32U capabilitiesMask)
222{
223	/* No key required for NULL algorithm */
224	if (!LAC_CIPHER_IS_NULL(pCipherSetupData->cipherAlgorithm)) {
225		LAC_CHECK_NULL_PARAM(pCipherSetupData->pCipherKey);
226
227		/* Check that algorithm and keys passed in are correct size */
228		switch (pCipherSetupData->cipherAlgorithm) {
229		case CPA_CY_SYM_CIPHER_ARC4:
230			if (pCipherSetupData->cipherKeyLenInBytes >
231			    ICP_QAT_HW_ARC4_KEY_SZ) {
232				LAC_INVALID_PARAM_LOG(
233				    "Invalid ARC4 cipher key length");
234				return CPA_STATUS_INVALID_PARAM;
235			}
236			break;
237		case CPA_CY_SYM_CIPHER_AES_CCM:
238			if (!LAC_CIPHER_AES_V2(capabilitiesMask) &&
239			    pCipherSetupData->cipherKeyLenInBytes !=
240				ICP_QAT_HW_AES_128_KEY_SZ) {
241				LAC_INVALID_PARAM_LOG(
242				    "Invalid AES CCM cipher key length");
243				return CPA_STATUS_INVALID_PARAM;
244			}
245			break;
246		case CPA_CY_SYM_CIPHER_AES_XTS:
247			if ((pCipherSetupData->cipherKeyLenInBytes !=
248			     ICP_QAT_HW_AES_128_XTS_KEY_SZ) &&
249			    (pCipherSetupData->cipherKeyLenInBytes !=
250			     ICP_QAT_HW_AES_256_XTS_KEY_SZ) &&
251			    (pCipherSetupData->cipherKeyLenInBytes !=
252			     ICP_QAT_HW_UCS_AES_128_XTS_KEY_SZ) &&
253			    (pCipherSetupData->cipherKeyLenInBytes !=
254			     ICP_QAT_HW_UCS_AES_256_XTS_KEY_SZ)) {
255				LAC_INVALID_PARAM_LOG(
256				    "Invalid AES XTS cipher key length");
257				return CPA_STATUS_INVALID_PARAM;
258			}
259			break;
260		case CPA_CY_SYM_CIPHER_AES_ECB:
261		case CPA_CY_SYM_CIPHER_AES_CBC:
262		case CPA_CY_SYM_CIPHER_AES_CTR:
263		case CPA_CY_SYM_CIPHER_AES_GCM:
264			if ((pCipherSetupData->cipherKeyLenInBytes !=
265			     ICP_QAT_HW_AES_128_KEY_SZ) &&
266			    (pCipherSetupData->cipherKeyLenInBytes !=
267			     ICP_QAT_HW_AES_192_KEY_SZ) &&
268			    (pCipherSetupData->cipherKeyLenInBytes !=
269			     ICP_QAT_HW_AES_256_KEY_SZ)) {
270				LAC_INVALID_PARAM_LOG(
271				    "Invalid AES cipher key length");
272				return CPA_STATUS_INVALID_PARAM;
273			}
274			break;
275		case CPA_CY_SYM_CIPHER_AES_F8:
276			if ((pCipherSetupData->cipherKeyLenInBytes !=
277			     ICP_QAT_HW_AES_128_F8_KEY_SZ) &&
278			    (pCipherSetupData->cipherKeyLenInBytes !=
279			     ICP_QAT_HW_AES_192_F8_KEY_SZ) &&
280			    (pCipherSetupData->cipherKeyLenInBytes !=
281			     ICP_QAT_HW_AES_256_F8_KEY_SZ)) {
282				LAC_INVALID_PARAM_LOG(
283				    "Invalid AES cipher key length");
284				return CPA_STATUS_INVALID_PARAM;
285			}
286			break;
287		case CPA_CY_SYM_CIPHER_DES_ECB:
288		case CPA_CY_SYM_CIPHER_DES_CBC:
289			if (pCipherSetupData->cipherKeyLenInBytes !=
290			    ICP_QAT_HW_DES_KEY_SZ) {
291				LAC_INVALID_PARAM_LOG(
292				    "Invalid DES cipher key length");
293				return CPA_STATUS_INVALID_PARAM;
294			}
295			break;
296		case CPA_CY_SYM_CIPHER_3DES_ECB:
297		case CPA_CY_SYM_CIPHER_3DES_CBC:
298		case CPA_CY_SYM_CIPHER_3DES_CTR:
299			if (pCipherSetupData->cipherKeyLenInBytes !=
300			    ICP_QAT_HW_3DES_KEY_SZ) {
301				LAC_INVALID_PARAM_LOG(
302				    "Invalid Triple-DES cipher key length");
303				return CPA_STATUS_INVALID_PARAM;
304			}
305			break;
306		case CPA_CY_SYM_CIPHER_KASUMI_F8:
307			/* QAT-FW only supports 128 bits Cipher Key size for
308			 * Kasumi F8 Ref: 3GPP TS 55.216 V6.2.0 */
309			if (pCipherSetupData->cipherKeyLenInBytes !=
310			    ICP_QAT_HW_KASUMI_KEY_SZ) {
311				LAC_INVALID_PARAM_LOG(
312				    "Invalid Kasumi cipher key length");
313				return CPA_STATUS_INVALID_PARAM;
314			}
315			break;
316		case CPA_CY_SYM_CIPHER_SNOW3G_UEA2:
317			/* QAT-FW only supports 256 bits Cipher Key size for
318			 * Snow_3G */
319			if (pCipherSetupData->cipherKeyLenInBytes !=
320			    ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ) {
321				LAC_INVALID_PARAM_LOG(
322				    "Invalid Snow_3G cipher key length");
323				return CPA_STATUS_INVALID_PARAM;
324			}
325			break;
326		case CPA_CY_SYM_CIPHER_ZUC_EEA3:
327			/* ZUC EEA3 */
328			if (pCipherSetupData->cipherKeyLenInBytes !=
329			    ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) {
330				LAC_INVALID_PARAM_LOG(
331				    "Invalid ZUC cipher key length");
332				return CPA_STATUS_INVALID_PARAM;
333			}
334			break;
335		case CPA_CY_SYM_CIPHER_CHACHA:
336			if (pCipherSetupData->cipherKeyLenInBytes !=
337			    ICP_QAT_HW_CHACHAPOLY_KEY_SZ) {
338				LAC_INVALID_PARAM_LOG(
339				    "Invalid CHACHAPOLY cipher key length");
340				return CPA_STATUS_INVALID_PARAM;
341			}
342			break;
343		case CPA_CY_SYM_CIPHER_SM4_ECB:
344		case CPA_CY_SYM_CIPHER_SM4_CBC:
345		case CPA_CY_SYM_CIPHER_SM4_CTR:
346			if (pCipherSetupData->cipherKeyLenInBytes !=
347			    ICP_QAT_HW_SM4_KEY_SZ) {
348				LAC_INVALID_PARAM_LOG(
349				    "Invalid SM4 cipher key length");
350				return CPA_STATUS_INVALID_PARAM;
351			}
352			break;
353		default:
354			LAC_INVALID_PARAM_LOG("Invalid cipher algorithm");
355			return CPA_STATUS_INVALID_PARAM;
356		}
357	}
358	return CPA_STATUS_SUCCESS;
359}
360
361CpaStatus
362LacCipher_PerformParamCheck(CpaCySymCipherAlgorithm algorithm,
363			    const CpaCySymOpData *pOpData,
364			    const Cpa64U packetLen)
365{
366	CpaStatus status = CPA_STATUS_SUCCESS;
367
368	/* The following check will cover the dstBuffer as well, since
369	 * the dstBuffer cannot be smaller than the srcBuffer (checked in
370	 * LacSymPerform_BufferParamCheck() called from LacSym_Perform())
371	 */
372	if ((pOpData->messageLenToCipherInBytes +
373	     pOpData->cryptoStartSrcOffsetInBytes) > packetLen) {
374		LAC_INVALID_PARAM_LOG("cipher len + offset greater than "
375				      "srcBuffer packet len");
376		status = CPA_STATUS_INVALID_PARAM;
377	} else {
378		/* Perform algorithm-specific checks */
379		switch (algorithm) {
380		case CPA_CY_SYM_CIPHER_ARC4:
381		case CPA_CY_SYM_CIPHER_AES_CTR:
382		case CPA_CY_SYM_CIPHER_3DES_CTR:
383		case CPA_CY_SYM_CIPHER_SM4_CTR:
384		case CPA_CY_SYM_CIPHER_AES_CCM:
385		case CPA_CY_SYM_CIPHER_AES_GCM:
386		case CPA_CY_SYM_CIPHER_CHACHA:
387		case CPA_CY_SYM_CIPHER_KASUMI_F8:
388		case CPA_CY_SYM_CIPHER_AES_F8:
389		case CPA_CY_SYM_CIPHER_SNOW3G_UEA2:
390		case CPA_CY_SYM_CIPHER_ZUC_EEA3:
391			/* No action needed */
392			break;
393		/*
394		 * XTS Mode allow for ciphers which are not multiples of
395		 * the block size.
396		 */
397		case CPA_CY_SYM_CIPHER_AES_XTS:
398			if ((pOpData->packetType ==
399			     CPA_CY_SYM_PACKET_TYPE_FULL) ||
400			    (pOpData->packetType ==
401			     CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL)) {
402				/*
403				 * If this is the last of a partial request
404				 */
405				if (pOpData->messageLenToCipherInBytes <
406				    ICP_QAT_HW_AES_BLK_SZ) {
407					LAC_INVALID_PARAM_LOG(
408					    "data size must be greater than block"
409					    " size for last XTS partial or XTS "
410					    "full packet");
411					status = CPA_STATUS_INVALID_PARAM;
412				}
413			}
414			break;
415		default:
416			/* Mask & check below is based on assumption that block
417			 * size is a power of 2. If data size is not a multiple
418			 * of the block size, the "remainder" bits selected by
419			 * the mask be non-zero
420			 */
421			if (pOpData->messageLenToCipherInBytes &
422			    (LacSymQat_CipherBlockSizeBytesGet(algorithm) -
423			     1)) {
424				LAC_INVALID_PARAM_LOG(
425				    "data size must be block size"
426				    " multiple");
427				status = CPA_STATUS_INVALID_PARAM;
428			}
429		}
430	}
431	return status;
432}
433
434Cpa32U
435LacCipher_GetCipherSliceType(sal_crypto_service_t *pService,
436			     CpaCySymCipherAlgorithm cipherAlgorithm,
437			     CpaCySymHashAlgorithm hashAlgorithm)
438{
439	Cpa32U sliceType = ICP_QAT_FW_LA_USE_LEGACY_SLICE_TYPE;
440	Cpa32U capabilitiesMask =
441	    pService->generic_service_info.capabilitiesMask;
442
443	/* UCS Slice is supproted only in Gen4 */
444	if (isCyGen4x(pService)) {
445		if (LAC_CIPHER_IS_XTS_MODE(cipherAlgorithm) ||
446		    LAC_CIPHER_IS_CHACHA(cipherAlgorithm) ||
447		    LAC_CIPHER_IS_GCM(cipherAlgorithm)) {
448			sliceType = ICP_QAT_FW_LA_USE_UCS_SLICE_TYPE;
449		} else if (LAC_CIPHER_IS_CCM(cipherAlgorithm) &&
450			   LAC_CIPHER_AES_V2(capabilitiesMask)) {
451			sliceType = ICP_QAT_FW_LA_USE_LEGACY_SLICE_TYPE;
452		} else if (LAC_CIPHER_IS_AES(cipherAlgorithm) &&
453			   LAC_CIPHER_IS_CTR_MODE(cipherAlgorithm)) {
454			sliceType = ICP_QAT_FW_LA_USE_UCS_SLICE_TYPE;
455		}
456	}
457
458	return sliceType;
459}
460