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 
59 CpaStatus
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 				 * 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 
219 CpaStatus
220 LacCipher_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 
361 CpaStatus
362 LacCipher_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 
434 Cpa32U
435 LacCipher_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