The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/qat/qat_api/common/crypto/sym/lac_sym_cipher.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.