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