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 }
Cache object: ee48c77c3e22bc4a1d0808663901166a
|