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
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 * 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
LacCipher_SessionSetupDataCheck(const CpaCySymCipherSetupData * pCipherSetupData,Cpa32U capabilitiesMask)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
LacCipher_PerformParamCheck(CpaCySymCipherAlgorithm algorithm,const CpaCySymOpData * pOpData,const Cpa64U packetLen)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
LacCipher_GetCipherSliceType(sal_crypto_service_t * pService,CpaCySymCipherAlgorithm cipherAlgorithm,CpaCySymHashAlgorithm hashAlgorithm)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