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