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_hash.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_hash.c
    8  *
    9  * @ingroup LacHash
   10  *
   11  * Hash specific functionality
   12  ***************************************************************************/
   13 
   14 /*
   15 *******************************************************************************
   16 * Include public/global header files
   17 *******************************************************************************
   18 */
   19 
   20 #include "cpa.h"
   21 #include "cpa_cy_sym.h"
   22 
   23 #include "icp_accel_devices.h"
   24 #include "icp_adf_debug.h"
   25 
   26 /*
   27 *******************************************************************************
   28 * Include private header files
   29 *******************************************************************************
   30 */
   31 
   32 #include "lac_common.h"
   33 #include "lac_mem.h"
   34 #include "lac_sym.h"
   35 #include "lac_session.h"
   36 #include "lac_sym_hash.h"
   37 #include "lac_log.h"
   38 #include "lac_sym_qat_hash.h"
   39 #include "lac_sym_qat_hash_defs_lookup.h"
   40 #include "lac_sym_cb.h"
   41 #include "lac_sync.h"
   42 
   43 #define LAC_HASH_ALG_MODE_NOT_SUPPORTED(alg, mode)                             \
   44         ((((CPA_CY_SYM_HASH_KASUMI_F9 == (alg)) ||                             \
   45            (CPA_CY_SYM_HASH_SNOW3G_UIA2 == (alg)) ||                           \
   46            (CPA_CY_SYM_HASH_AES_XCBC == (alg)) ||                              \
   47            (CPA_CY_SYM_HASH_AES_CCM == (alg)) ||                               \
   48            (CPA_CY_SYM_HASH_AES_GCM == (alg)) ||                               \
   49            (CPA_CY_SYM_HASH_AES_GMAC == (alg)) ||                              \
   50            (CPA_CY_SYM_HASH_AES_CMAC == (alg)) ||                              \
   51            (CPA_CY_SYM_HASH_ZUC_EIA3 == (alg))) &&                             \
   52           (CPA_CY_SYM_HASH_MODE_AUTH != (mode))) ||                            \
   53          ((LAC_HASH_IS_SHA3(alg)) && (CPA_CY_SYM_HASH_MODE_NESTED == (mode))))
   54 /**< Macro to check for valid algorithm-mode combination */
   55 
   56 void LacSync_GenBufListVerifyCb(void *pCallbackTag,
   57                                 CpaStatus status,
   58                                 CpaCySymOp operationType,
   59                                 void *pOpData,
   60                                 CpaBufferList *pDstBuffer,
   61                                 CpaBoolean opResult);
   62 
   63 /**
   64  * @ingroup LacHash
   65  * This callback function will be invoked whenever a synchronous
   66  * hash precompute operation completes.  It will set the wait
   67  * queue flag for the synchronous operation.
   68  *
   69  * @param[in] pCallbackTag  Opaque value provided by user. This will
   70  *                         be a pointer to a wait queue flag.
   71  *
   72  * @retval
   73  *     None
   74  *
   75  */
   76 static void
   77 LacHash_SyncPrecomputeDoneCb(void *pCallbackTag)
   78 {
   79         LacSync_GenWakeupSyncCaller(pCallbackTag, CPA_STATUS_SUCCESS);
   80 }
   81 
   82 /** @ingroup LacHash */
   83 CpaStatus
   84 LacHash_StatePrefixAadBufferInit(
   85     sal_service_t *pService,
   86     const CpaCySymHashSetupData *pHashSetupData,
   87     icp_qat_la_bulk_req_ftr_t *pReq,
   88     icp_qat_hw_auth_mode_t qatHashMode,
   89     Cpa8U *pHashStateBuffer,
   90     lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo)
   91 {
   92         /* set up the hash state prefix buffer info structure */
   93         pHashStateBufferInfo->pData = pHashStateBuffer;
   94 
   95         pHashStateBufferInfo->pDataPhys = LAC_MEM_CAST_PTR_TO_UINT64(
   96             LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService), pHashStateBuffer));
   97 
   98         if (pHashStateBufferInfo->pDataPhys == 0) {
   99                 LAC_LOG_ERROR("Unable to get the physical address of "
  100                               "the hash state buffer\n");
  101                 return CPA_STATUS_FAIL;
  102         }
  103 
  104         LacSymQat_HashStatePrefixAadBufferSizeGet(pReq, pHashStateBufferInfo);
  105 
  106         /* Prefix data gets copied to the hash state buffer for nested mode */
  107         if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
  108                 LacSymQat_HashStatePrefixAadBufferPopulate(
  109                     pHashStateBufferInfo,
  110                     pReq,
  111                     pHashSetupData->nestedModeSetupData.pInnerPrefixData,
  112                     (Cpa8U)pHashSetupData->nestedModeSetupData
  113                         .innerPrefixLenInBytes,
  114                     pHashSetupData->nestedModeSetupData.pOuterPrefixData,
  115                     (Cpa8U)pHashSetupData->nestedModeSetupData
  116                         .outerPrefixLenInBytes);
  117         }
  118         /* For mode2 HMAC the key gets copied into both the inner and
  119          * outer prefix fields */
  120         else if (IS_HASH_MODE_2_AUTH(qatHashMode, pHashSetupData->hashMode)) {
  121                 LacSymQat_HashStatePrefixAadBufferPopulate(
  122                     pHashStateBufferInfo,
  123                     pReq,
  124                     pHashSetupData->authModeSetupData.authKey,
  125                     (Cpa8U)pHashSetupData->authModeSetupData.authKeyLenInBytes,
  126                     pHashSetupData->authModeSetupData.authKey,
  127                     (Cpa8U)pHashSetupData->authModeSetupData.authKeyLenInBytes);
  128         }
  129         /* else do nothing for the other cases */
  130         return CPA_STATUS_SUCCESS;
  131 }
  132 
  133 /** @ingroup LacHash */
  134 CpaStatus
  135 LacHash_PrecomputeDataCreate(const CpaInstanceHandle instanceHandle,
  136                              CpaCySymSessionSetupData *pSessionSetup,
  137                              lac_hash_precompute_done_cb_t callbackFn,
  138                              void *pCallbackTag,
  139                              Cpa8U *pWorkingBuffer,
  140                              Cpa8U *pState1,
  141                              Cpa8U *pState2)
  142 {
  143         CpaStatus status = CPA_STATUS_SUCCESS;
  144         Cpa8U *pAuthKey = NULL;
  145         Cpa32U authKeyLenInBytes = 0;
  146         CpaCySymHashAlgorithm hashAlgorithm =
  147             pSessionSetup->hashSetupData.hashAlgorithm;
  148         CpaCySymHashAuthModeSetupData *pAuthModeSetupData =
  149             &pSessionSetup->hashSetupData.authModeSetupData;
  150 
  151         /* synchronous operation */
  152         if (NULL == callbackFn) {
  153                 lac_sync_op_data_t *pSyncCallbackData = NULL;
  154 
  155                 status = LacSync_CreateSyncCookie(&pSyncCallbackData);
  156 
  157                 if (CPA_STATUS_SUCCESS == status) {
  158                         status = LacHash_PrecomputeDataCreate(
  159                             instanceHandle,
  160                             pSessionSetup,
  161                             LacHash_SyncPrecomputeDoneCb,
  162                             /* wait queue condition from sync cookie */
  163                             pSyncCallbackData,
  164                             pWorkingBuffer,
  165                             pState1,
  166                             pState2);
  167                 } else {
  168                         return status;
  169                 }
  170 
  171                 if (CPA_STATUS_SUCCESS == status) {
  172                         CpaStatus syncStatus = CPA_STATUS_SUCCESS;
  173 
  174                         syncStatus = LacSync_WaitForCallback(
  175                             pSyncCallbackData,
  176                             LAC_SYM_SYNC_CALLBACK_TIMEOUT,
  177                             &status,
  178                             NULL);
  179 
  180                         /* If callback doesn't come back */
  181                         if (CPA_STATUS_SUCCESS != syncStatus) {
  182                                 QAT_UTILS_LOG(
  183                                     "callback functions for precomputes did not return\n");
  184                                 status = syncStatus;
  185                         }
  186                 } else {
  187                         /* As the Request was not sent the Callback will never
  188                          * be called, so need to indicate that we're finished
  189                          * with cookie so it can be destroyed. */
  190                         LacSync_SetSyncCookieComplete(pSyncCallbackData);
  191                 }
  192                 LacSync_DestroySyncCookie(&pSyncCallbackData);
  193 
  194                 return status;
  195         }
  196 
  197         /* set up convenience pointers */
  198         pAuthKey = pAuthModeSetupData->authKey;
  199         authKeyLenInBytes = pAuthModeSetupData->authKeyLenInBytes;
  200 
  201         /* Pre-compute data state pointers must already be set up
  202          * by LacSymQat_HashSetupBlockInit()
  203          */
  204 
  205         /* state1 is not allocated for AES XCBC/CCM/GCM/Kasumi/UIA2
  206          * so for these algorithms set state2 only */
  207         if (CPA_CY_SYM_HASH_AES_XCBC == hashAlgorithm) {
  208                 status = LacSymHash_AesECBPreCompute(instanceHandle,
  209                                                      hashAlgorithm,
  210                                                      authKeyLenInBytes,
  211                                                      pAuthKey,
  212                                                      pWorkingBuffer,
  213                                                      pState2,
  214                                                      callbackFn,
  215                                                      pCallbackTag);
  216         } else if (CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) {
  217                 /* First, copy the original key to pState2 */
  218                 memcpy(pState2, pAuthKey, authKeyLenInBytes);
  219                 /* Then precompute */
  220                 status = LacSymHash_AesECBPreCompute(instanceHandle,
  221                                                      hashAlgorithm,
  222                                                      authKeyLenInBytes,
  223                                                      pAuthKey,
  224                                                      pWorkingBuffer,
  225                                                      pState2,
  226                                                      callbackFn,
  227                                                      pCallbackTag);
  228         } else if (CPA_CY_SYM_HASH_AES_CCM == hashAlgorithm) {
  229                 /*
  230                  * The Inner Hash Initial State2 block is 32 bytes long.
  231                  * Therefore, for keys bigger than 128 bits (16 bytes),
  232                  * there is no space for 16 zeroes.
  233                  */
  234                 if (pSessionSetup->cipherSetupData.cipherKeyLenInBytes ==
  235                     ICP_QAT_HW_AES_128_KEY_SZ) {
  236                         /*
  237                          * The Inner Hash Initial State2 block must contain K
  238                          * (the cipher key) and 16 zeroes which will be replaced
  239                          * with EK(Ctr0) by the QAT-ME.
  240                          */
  241 
  242                         /* write the auth key which for CCM is equivalent to
  243                          * cipher key
  244                          */
  245                         memcpy(
  246                             pState2,
  247                             pSessionSetup->cipherSetupData.pCipherKey,
  248                             pSessionSetup->cipherSetupData.cipherKeyLenInBytes);
  249 
  250                         /* initialize remaining buffer space to all zeroes */
  251                         LAC_OS_BZERO(pState2 +
  252                                          pSessionSetup->cipherSetupData
  253                                              .cipherKeyLenInBytes,
  254                                      ICP_QAT_HW_AES_CCM_CBC_E_CTR0_SZ);
  255                 }
  256 
  257                 /* There is no request sent to the QAT for this operation,
  258                  * so just invoke the user's callback directly to signal
  259                  * completion of the precompute
  260                  */
  261                 callbackFn(pCallbackTag);
  262         } else if (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm ||
  263                    CPA_CY_SYM_HASH_AES_GMAC == hashAlgorithm) {
  264                 /*
  265                  * The Inner Hash Initial State2 block contains the following
  266                  *      H (the Galois Hash Multiplier)
  267                  *      len(A) (the length of A), (length before padding)
  268                  *      16 zeroes which will be replaced with EK(Ctr0) by the
  269                  * QAT.
  270                  */
  271 
  272                 /* Memset state2 to 0 */
  273                 LAC_OS_BZERO(pState2,
  274                              ICP_QAT_HW_GALOIS_H_SZ +
  275                                  ICP_QAT_HW_GALOIS_LEN_A_SZ +
  276                                  ICP_QAT_HW_GALOIS_E_CTR0_SZ);
  277 
  278                 /* write H (the Galois Hash Multiplier) where H = E(K, 0...0)
  279                  * This will only write bytes 0-15 of pState2
  280                  */
  281                 status = LacSymHash_AesECBPreCompute(
  282                     instanceHandle,
  283                     hashAlgorithm,
  284                     pSessionSetup->cipherSetupData.cipherKeyLenInBytes,
  285                     pSessionSetup->cipherSetupData.pCipherKey,
  286                     pWorkingBuffer,
  287                     pState2,
  288                     callbackFn,
  289                     pCallbackTag);
  290 
  291                 if (CPA_STATUS_SUCCESS == status) {
  292                         /* write len(A) (the length of A) into bytes 16-19 of
  293                          * pState2 in big-endian format. This field is 8 bytes
  294                          */
  295                         *(Cpa32U *)&pState2[ICP_QAT_HW_GALOIS_H_SZ] =
  296                             LAC_MEM_WR_32(pAuthModeSetupData->aadLenInBytes);
  297                 }
  298         } else if (CPA_CY_SYM_HASH_KASUMI_F9 == hashAlgorithm) {
  299                 Cpa32U wordIndex = 0;
  300                 Cpa32U *pTempKey = (Cpa32U *)(pState2 + authKeyLenInBytes);
  301                 /*
  302                  * The Inner Hash Initial State2 block must contain IK
  303                  * (Initialisation Key), followed by IK XOR-ed with KM
  304                  * (Key Modifier): IK||(IK^KM).
  305                  */
  306 
  307                 /* write the auth key */
  308                 memcpy(pState2, pAuthKey, authKeyLenInBytes);
  309                 /* initialise temp key with auth key */
  310                 memcpy(pTempKey, pAuthKey, authKeyLenInBytes);
  311 
  312                 /* XOR Key with KASUMI F9 key modifier at 4 bytes level */
  313                 for (wordIndex = 0;
  314                      wordIndex < LAC_BYTES_TO_LONGWORDS(authKeyLenInBytes);
  315                      wordIndex++) {
  316                         pTempKey[wordIndex] ^=
  317                             LAC_HASH_KASUMI_F9_KEY_MODIFIER_4_BYTES;
  318                 }
  319                 /* There is no request sent to the QAT for this operation,
  320                  * so just invoke the user's callback directly to signal
  321                  * completion of the precompute
  322                  */
  323                 callbackFn(pCallbackTag);
  324         } else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) {
  325                 /*
  326                  * The Inner Hash Initial State2 should be all zeros
  327                  */
  328                 LAC_OS_BZERO(pState2, ICP_QAT_HW_SNOW_3G_UIA2_STATE2_SZ);
  329 
  330                 /* There is no request sent to the QAT for this operation,
  331                  * so just invoke the user's callback directly to signal
  332                  * completion of the precompute
  333                  */
  334                 callbackFn(pCallbackTag);
  335         } else if (CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm) {
  336                 /*
  337                  * The Inner Hash Initial State2 should contain the key
  338                  * and zero the rest of the state.
  339                  */
  340                 LAC_OS_BZERO(pState2, ICP_QAT_HW_ZUC_3G_EIA3_STATE2_SZ);
  341                 memcpy(pState2, pAuthKey, authKeyLenInBytes);
  342 
  343                 /* There is no request sent to the QAT for this operation,
  344                  * so just invoke the user's callback directly to signal
  345                  * completion of the precompute
  346                  */
  347                 callbackFn(pCallbackTag);
  348         } else if (CPA_CY_SYM_HASH_POLY == hashAlgorithm) {
  349                 /* There is no request sent to the QAT for this operation,
  350                  * so just invoke the user's callback directly to signal
  351                  * completion of the precompute
  352                  */
  353                 callbackFn(pCallbackTag);
  354         } else /* For Hmac Precomputes */
  355         {
  356                 status = LacSymHash_HmacPreComputes(instanceHandle,
  357                                                     hashAlgorithm,
  358                                                     authKeyLenInBytes,
  359                                                     pAuthKey,
  360                                                     pWorkingBuffer,
  361                                                     pState1,
  362                                                     pState2,
  363                                                     callbackFn,
  364                                                     pCallbackTag);
  365         }
  366 
  367         return status;
  368 }
  369 
  370 
  371 /** @ingroup LacHash */
  372 CpaStatus
  373 LacHash_HashContextCheck(CpaInstanceHandle instanceHandle,
  374                          const CpaCySymHashSetupData *pHashSetupData)
  375 {
  376         lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
  377         lac_sym_qat_hash_alg_info_t *pOuterHashAlgInfo = NULL;
  378         CpaCySymCapabilitiesInfo capInfo;
  379 
  380         /*Protect against value of hash outside the bitmap*/
  381         if (pHashSetupData->hashAlgorithm >= CPA_CY_SYM_HASH_CAP_BITMAP_SIZE) {
  382                 LAC_INVALID_PARAM_LOG("hashAlgorithm");
  383                 return CPA_STATUS_INVALID_PARAM;
  384         }
  385 
  386         cpaCySymQueryCapabilities(instanceHandle, &capInfo);
  387         if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
  388                                  pHashSetupData->hashAlgorithm) &&
  389             pHashSetupData->hashAlgorithm != CPA_CY_SYM_HASH_AES_CBC_MAC) {
  390                 LAC_INVALID_PARAM_LOG("hashAlgorithm");
  391                 return CPA_STATUS_INVALID_PARAM;
  392         }
  393 
  394         switch (pHashSetupData->hashMode) {
  395         case CPA_CY_SYM_HASH_MODE_PLAIN:
  396         case CPA_CY_SYM_HASH_MODE_AUTH:
  397         case CPA_CY_SYM_HASH_MODE_NESTED:
  398                 break;
  399 
  400         default: {
  401                 LAC_INVALID_PARAM_LOG("hashMode");
  402                 return CPA_STATUS_INVALID_PARAM;
  403         }
  404         }
  405 
  406         if (LAC_HASH_ALG_MODE_NOT_SUPPORTED(pHashSetupData->hashAlgorithm,
  407                                             pHashSetupData->hashMode)) {
  408                 LAC_UNSUPPORTED_PARAM_LOG(
  409                     "hashAlgorithm and hashMode combination");
  410                 return CPA_STATUS_UNSUPPORTED;
  411         }
  412 
  413         LacSymQat_HashAlgLookupGet(instanceHandle,
  414                                    pHashSetupData->hashAlgorithm,
  415                                    &pHashAlgInfo);
  416 
  417         /* note: nested hash mode checks digest length against outer algorithm
  418          */
  419         if ((CPA_CY_SYM_HASH_MODE_PLAIN == pHashSetupData->hashMode) ||
  420             (CPA_CY_SYM_HASH_MODE_AUTH == pHashSetupData->hashMode)) {
  421                 /* Check Digest Length is permitted by the algorithm  */
  422                 if ((0 == pHashSetupData->digestResultLenInBytes) ||
  423                     (pHashSetupData->digestResultLenInBytes >
  424                      pHashAlgInfo->digestLength)) {
  425                         LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
  426                         return CPA_STATUS_INVALID_PARAM;
  427                 }
  428         }
  429 
  430         if (CPA_CY_SYM_HASH_MODE_AUTH == pHashSetupData->hashMode) {
  431                 if (CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm ||
  432                     CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) {
  433                         Cpa32U aadDataSize = 0;
  434 
  435                         /* RFC 4106: Implementations MUST support a full-length
  436                          * 16-octet ICV, and MAY support 8 or 12 octet ICVs, and
  437                          * MUST NOT support other ICV lengths. */
  438                         if ((pHashSetupData->digestResultLenInBytes !=
  439                              LAC_HASH_AES_GCM_ICV_SIZE_8) &&
  440                             (pHashSetupData->digestResultLenInBytes !=
  441                              LAC_HASH_AES_GCM_ICV_SIZE_12) &&
  442                             (pHashSetupData->digestResultLenInBytes !=
  443                              LAC_HASH_AES_GCM_ICV_SIZE_16)) {
  444                                 LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
  445                                 return CPA_STATUS_INVALID_PARAM;
  446                         }
  447 
  448                         /* ensure aadLen is within maximum limit imposed by QAT
  449                          */
  450                         aadDataSize =
  451                             pHashSetupData->authModeSetupData.aadLenInBytes;
  452 
  453                         /* round the aad size to the multiple of GCM hash block
  454                          * size. */
  455                         aadDataSize =
  456                             LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
  457                                                    LAC_HASH_AES_GCM_BLOCK_SIZE);
  458 
  459                         if (aadDataSize > ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX &&
  460                             CPA_CY_SYM_HASH_AES_GMAC !=
  461                                 pHashSetupData->hashAlgorithm) {
  462                                 LAC_INVALID_PARAM_LOG("aadLenInBytes");
  463                                 return CPA_STATUS_INVALID_PARAM;
  464                         }
  465                 } else if (CPA_CY_SYM_HASH_AES_CCM ==
  466                            pHashSetupData->hashAlgorithm) {
  467                         Cpa32U aadDataSize = 0;
  468 
  469                         /* RFC 3610: Valid values are 4, 6, 8, 10, 12, 14, and
  470                          * 16 octets */
  471                         if ((pHashSetupData->digestResultLenInBytes >=
  472                              LAC_HASH_AES_CCM_ICV_SIZE_MIN) &&
  473                             (pHashSetupData->digestResultLenInBytes <=
  474                              LAC_HASH_AES_CCM_ICV_SIZE_MAX)) {
  475                                 if ((pHashSetupData->digestResultLenInBytes &
  476                                      0x01) != 0) {
  477                                         LAC_INVALID_PARAM_LOG(
  478                                             "digestResultLenInBytes must be a multiple of 2");
  479                                         return CPA_STATUS_INVALID_PARAM;
  480                                 }
  481                         } else {
  482                                 LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
  483                                 return CPA_STATUS_INVALID_PARAM;
  484                         }
  485 
  486                         /* ensure aadLen is within maximum limit imposed by QAT
  487                          */
  488                         /* at the beginning of the buffer there is B0 block */
  489                         aadDataSize = LAC_HASH_AES_CCM_BLOCK_SIZE;
  490 
  491                         /* then, if there is some 'a' data, the buffer will
  492                          * store encoded length of 'a' and 'a' itself */
  493                         if (pHashSetupData->authModeSetupData.aadLenInBytes >
  494                             0) {
  495                                 /* as the QAT API puts the requirement on the
  496                                  * pAdditionalAuthData not to be bigger than 240
  497                                  * bytes then we just need 2 bytes to store
  498                                  * encoded length of 'a' */
  499                                 aadDataSize += sizeof(Cpa16U);
  500                                 aadDataSize += pHashSetupData->authModeSetupData
  501                                                    .aadLenInBytes;
  502                         }
  503 
  504                         /* round the aad size to the multiple of CCM block
  505                          * size.*/
  506                         aadDataSize =
  507                             LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
  508                                                    LAC_HASH_AES_CCM_BLOCK_SIZE);
  509                         if (aadDataSize > ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX) {
  510                                 LAC_INVALID_PARAM_LOG("aadLenInBytes");
  511                                 return CPA_STATUS_INVALID_PARAM;
  512                         }
  513                 } else if (CPA_CY_SYM_HASH_KASUMI_F9 ==
  514                            pHashSetupData->hashAlgorithm) {
  515                         /* QAT-FW only supports 128 bit Integrity Key size for
  516                          * Kasumi f9
  517                          *  Ref: 3GPP TS 35.201 version 7.0.0 Release 7 */
  518                         if (pHashSetupData->authModeSetupData
  519                                 .authKeyLenInBytes !=
  520                             ICP_QAT_HW_KASUMI_KEY_SZ) {
  521                                 LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
  522                                 return CPA_STATUS_INVALID_PARAM;
  523                         }
  524                 } else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
  525                            pHashSetupData->hashAlgorithm) {
  526 
  527                         /* QAT-FW only supports 128 bits Integrity Key size for
  528                          * Snow3g */
  529                         if (pHashSetupData->authModeSetupData
  530                                 .authKeyLenInBytes !=
  531                             ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ) {
  532                                 LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
  533                                 return CPA_STATUS_INVALID_PARAM;
  534                         }
  535                         /* For Snow3g hash aad field contains IV - it needs to
  536                          * be 16 bytes long
  537                          */
  538                         if (pHashSetupData->authModeSetupData.aadLenInBytes !=
  539                             ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ) {
  540                                 LAC_INVALID_PARAM_LOG("aadLenInBytes");
  541                                 return CPA_STATUS_INVALID_PARAM;
  542                         }
  543                 } else if (CPA_CY_SYM_HASH_AES_XCBC ==
  544                                pHashSetupData->hashAlgorithm ||
  545                            CPA_CY_SYM_HASH_AES_CMAC ==
  546                                pHashSetupData->hashAlgorithm ||
  547                            CPA_CY_SYM_HASH_AES_CBC_MAC ==
  548                                pHashSetupData->hashAlgorithm) {
  549                         /* ensure auth key len is valid (128-bit keys supported)
  550                          */
  551                         if ((pHashSetupData->authModeSetupData
  552                                  .authKeyLenInBytes !=
  553                              ICP_QAT_HW_AES_128_KEY_SZ)) {
  554                                 LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
  555                                 return CPA_STATUS_INVALID_PARAM;
  556                         }
  557                 } else if (CPA_CY_SYM_HASH_ZUC_EIA3 ==
  558                            pHashSetupData->hashAlgorithm) {
  559 
  560                         /* QAT-FW only supports 128 bits Integrity Key size for
  561                          * ZUC */
  562                         if (pHashSetupData->authModeSetupData
  563                                 .authKeyLenInBytes !=
  564                             ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) {
  565                                 LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
  566                                 return CPA_STATUS_INVALID_PARAM;
  567                         }
  568                         /* For ZUC EIA3 hash aad field contains IV - it needs to
  569                          * be 16 bytes long
  570                          */
  571                         if (pHashSetupData->authModeSetupData.aadLenInBytes !=
  572                             ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ) {
  573                                 LAC_INVALID_PARAM_LOG("aadLenInBytes");
  574                                 return CPA_STATUS_INVALID_PARAM;
  575                         }
  576                 } else if (CPA_CY_SYM_HASH_POLY ==
  577                            pHashSetupData->hashAlgorithm) {
  578                         if (pHashSetupData->digestResultLenInBytes !=
  579                             ICP_QAT_HW_SPC_CTR_SZ) {
  580                                 LAC_INVALID_PARAM_LOG("Digest Length for CCP");
  581                                 return CPA_STATUS_INVALID_PARAM;
  582                         }
  583                         if (pHashSetupData->authModeSetupData.aadLenInBytes >
  584                             ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX) {
  585                                 LAC_INVALID_PARAM_LOG("AAD Length for CCP");
  586                                 return CPA_STATUS_INVALID_PARAM;
  587                         }
  588                 } else {
  589                         /* The key size must be less than or equal the block
  590                          * length */
  591                         if (pHashSetupData->authModeSetupData
  592                                 .authKeyLenInBytes >
  593                             pHashAlgInfo->blockLength) {
  594                                 LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
  595                                 return CPA_STATUS_INVALID_PARAM;
  596                         }
  597                 }
  598 
  599                 /* when the key size is greater than 0 check pointer is not null
  600                  */
  601                 if (CPA_CY_SYM_HASH_AES_CCM != pHashSetupData->hashAlgorithm &&
  602                     CPA_CY_SYM_HASH_AES_GCM != pHashSetupData->hashAlgorithm &&
  603                     pHashSetupData->authModeSetupData.authKeyLenInBytes > 0) {
  604                         LAC_CHECK_NULL_PARAM(
  605                             pHashSetupData->authModeSetupData.authKey);
  606                 }
  607         } else if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
  608                 if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
  609                                          pHashSetupData->nestedModeSetupData
  610                                              .outerHashAlgorithm)) {
  611                         LAC_INVALID_PARAM_LOG("outerHashAlgorithm");
  612                         return CPA_STATUS_INVALID_PARAM;
  613                 }
  614 
  615                 if (LAC_HASH_ALG_MODE_NOT_SUPPORTED(
  616                         pHashSetupData->nestedModeSetupData.outerHashAlgorithm,
  617                         pHashSetupData->hashMode)) {
  618                         LAC_INVALID_PARAM_LOG(
  619                             "outerHashAlgorithm and hashMode combination");
  620                         return CPA_STATUS_INVALID_PARAM;
  621                 }
  622 
  623                 LacSymQat_HashAlgLookupGet(
  624                     instanceHandle,
  625                     pHashSetupData->nestedModeSetupData.outerHashAlgorithm,
  626                     &pOuterHashAlgInfo);
  627 
  628                 /* Check Digest Length is permitted by the algorithm  */
  629                 if ((0 == pHashSetupData->digestResultLenInBytes) ||
  630                     (pHashSetupData->digestResultLenInBytes >
  631                      pOuterHashAlgInfo->digestLength)) {
  632                         LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
  633                         return CPA_STATUS_INVALID_PARAM;
  634                 }
  635 
  636                 if (pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes >
  637                     LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES) {
  638                         LAC_INVALID_PARAM_LOG("innerPrefixLenInBytes");
  639                         return CPA_STATUS_INVALID_PARAM;
  640                 }
  641 
  642                 if (pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes >
  643                     0) {
  644                         LAC_CHECK_NULL_PARAM(pHashSetupData->nestedModeSetupData
  645                                                  .pInnerPrefixData);
  646                 }
  647 
  648                 if (pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes >
  649                     LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES) {
  650                         LAC_INVALID_PARAM_LOG("outerPrefixLenInBytes");
  651                         return CPA_STATUS_INVALID_PARAM;
  652                 }
  653 
  654                 if (pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes >
  655                     0) {
  656                         LAC_CHECK_NULL_PARAM(pHashSetupData->nestedModeSetupData
  657                                                  .pOuterPrefixData);
  658                 }
  659         }
  660 
  661         return CPA_STATUS_SUCCESS;
  662 }
  663 
  664 /** @ingroup LacHash */
  665 CpaStatus
  666 LacHash_PerformParamCheck(CpaInstanceHandle instanceHandle,
  667                           lac_session_desc_t *pSessionDesc,
  668                           const CpaCySymOpData *pOpData,
  669                           Cpa64U srcPktSize,
  670                           const CpaBoolean *pVerifyResult)
  671 {
  672         CpaStatus status = CPA_STATUS_SUCCESS;
  673         lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
  674         CpaBoolean digestIsAppended = pSessionDesc->digestIsAppended;
  675         CpaBoolean digestVerify = pSessionDesc->digestVerify;
  676         CpaCySymOp symOperation = pSessionDesc->symOperation;
  677         CpaCySymHashAlgorithm hashAlgorithm = pSessionDesc->hashAlgorithm;
  678 
  679         /* digestVerify and digestIsAppended on Hash-Only operation not
  680          * supported */
  681         if (digestIsAppended && digestVerify &&
  682             (CPA_CY_SYM_OP_HASH == symOperation)) {
  683                 LAC_INVALID_PARAM_LOG(
  684                     "digestVerify and digestIsAppended set "
  685                     "on Hash-Only operation is not supported");
  686                 return CPA_STATUS_INVALID_PARAM;
  687         }
  688 
  689         /* check the digest result pointer */
  690         if ((CPA_CY_SYM_PACKET_TYPE_PARTIAL != pOpData->packetType) &&
  691             !digestIsAppended && (NULL == pOpData->pDigestResult)) {
  692                 LAC_INVALID_PARAM_LOG("pDigestResult is NULL");
  693                 return CPA_STATUS_INVALID_PARAM;
  694         }
  695 
  696         /*
  697          * Check if the pVerifyResult pointer is not null for hash operation
  698          * when the packet is the last one and user has set verifyDigest flag
  699          * Also, this is only needed for symchronous operation, so check if the
  700          * callback pointer is the internal synchronous one rather than a user-
  701          * supplied one.
  702          */
  703         if ((CPA_TRUE == digestVerify) &&
  704             (CPA_CY_SYM_PACKET_TYPE_PARTIAL != pOpData->packetType) &&
  705             (LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb)) {
  706                 if (NULL == pVerifyResult) {
  707                         LAC_INVALID_PARAM_LOG(
  708                             "Null pointer pVerifyResult for hash op");
  709                         return CPA_STATUS_INVALID_PARAM;
  710                 }
  711         }
  712 
  713         /* verify start offset + messageLenToDigest is inside the source packet.
  714          * this also verifies that the start offset is inside the packet
  715          * Note: digest is specified as a pointer therefore it can be
  716          * written anywhere so we cannot check for this been inside a buffer
  717          * CCM/GCM specify the auth region using just the cipher params as this
  718          * region is the same for auth and cipher. It is not checked here */
  719         if ((CPA_CY_SYM_HASH_AES_CCM == hashAlgorithm) ||
  720             (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm)) {
  721                 /* ensure AAD data pointer is non-NULL if AAD len > 0 */
  722                 if ((pSessionDesc->aadLenInBytes > 0) &&
  723                     (NULL == pOpData->pAdditionalAuthData)) {
  724                         LAC_INVALID_PARAM_LOG("pAdditionalAuthData is NULL");
  725                         return CPA_STATUS_INVALID_PARAM;
  726                 }
  727         } else {
  728                 if ((pOpData->hashStartSrcOffsetInBytes +
  729                      pOpData->messageLenToHashInBytes) > srcPktSize) {
  730                         LAC_INVALID_PARAM_LOG(
  731                             "hashStartSrcOffsetInBytes + "
  732                             "messageLenToHashInBytes > Src Buffer Packet Length");
  733                         return CPA_STATUS_INVALID_PARAM;
  734                 }
  735         }
  736 
  737         /* For Snow3g & ZUC hash pAdditionalAuthData field
  738          * of OpData should contain IV */
  739         if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) ||
  740             (CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm)) {
  741                 if (NULL == pOpData->pAdditionalAuthData) {
  742                         LAC_INVALID_PARAM_LOG("pAdditionalAuthData is NULL");
  743                         return CPA_STATUS_INVALID_PARAM;
  744                 }
  745         }
  746 
  747         /* partial packets need to be multiples of the algorithm block size in
  748          * hash only mode (except for final partial packet) */
  749         if ((CPA_CY_SYM_PACKET_TYPE_PARTIAL == pOpData->packetType) &&
  750             (CPA_CY_SYM_OP_HASH == symOperation)) {
  751                 LacSymQat_HashAlgLookupGet(instanceHandle,
  752                                            hashAlgorithm,
  753                                            &pHashAlgInfo);
  754 
  755                 /* check if the message is a multiple of the block size. */
  756                 if ((pOpData->messageLenToHashInBytes %
  757                      pHashAlgInfo->blockLength) != 0) {
  758                         LAC_INVALID_PARAM_LOG(
  759                             "messageLenToHashInBytes not block size");
  760                         return CPA_STATUS_INVALID_PARAM;
  761                 }
  762         }
  763 
  764         return status;
  765 }
  766 

Cache object: 1d6ec646aea3b481f34201d123f90638


[ 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.