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