Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:06

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_cryp_ex.c
0004   * @author  MCD Application Team
0005   * @brief   Extended CRYP HAL module driver
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of CRYP extension peripheral:
0008   *           + Extended AES processing functions
0009   *
0010   ******************************************************************************
0011   * @attention
0012   *
0013   * Copyright (c) 2017 STMicroelectronics.
0014   * All rights reserved.
0015   *
0016   * This software is licensed under terms that can be found in the LICENSE file
0017   * in the root directory of this software component.
0018   * If no LICENSE file comes with this software, it is provided AS-IS.
0019   *
0020   ******************************************************************************
0021   @verbatim
0022   ==============================================================================
0023                      ##### How to use this driver #####
0024   ==============================================================================
0025     [..]
0026     The CRYP extension HAL driver can be used after AES-GCM or AES-CCM
0027     Encryption/Decryption to get the authentication messages.
0028 
0029   @endverbatim
0030   */
0031 
0032 /* Includes ------------------------------------------------------------------*/
0033 #include "stm32h7xx_hal.h"
0034 
0035 /** @addtogroup STM32H7xx_HAL_Driver
0036   * @{
0037   */
0038 #if defined (CRYP)
0039 /** @defgroup CRYPEx CRYPEx
0040   * @ingroup RTEMSBSPsARMSTM32H7
0041   * @brief CRYP Extension HAL module driver.
0042   * @{
0043   */
0044 
0045 #ifdef HAL_CRYP_MODULE_ENABLED
0046 
0047 /* Private typedef -----------------------------------------------------------*/
0048 /* Private define ------------------------------------------------------------*/
0049 /** @addtogroup CRYPEx_Private_Defines
0050   * @{
0051   */
0052 
0053 #define CRYP_PHASE_INIT                 0x00000000U
0054 #define CRYP_PHASE_HEADER               CRYP_CR_GCM_CCMPH_0
0055 #define CRYP_PHASE_PAYLOAD              CRYP_CR_GCM_CCMPH_1
0056 #define CRYP_PHASE_FINAL                CRYP_CR_GCM_CCMPH
0057 
0058 #define CRYP_OPERATINGMODE_ENCRYPT      0x00000000U
0059 #define CRYP_OPERATINGMODE_DECRYPT      CRYP_CR_ALGODIR
0060 
0061 #define  CRYPEx_PHASE_PROCESS       0x02U     /*!< CRYP peripheral is in processing phase */
0062 #define  CRYPEx_PHASE_FINAL         0x03U     /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
0063 
0064 /*  CTR0 information to use in CCM algorithm */
0065 #define CRYP_CCM_CTR0_0            0x07FFFFFFU
0066 #define CRYP_CCM_CTR0_3            0xFFFFFF00U
0067 
0068 /**
0069   * @}
0070   */
0071 
0072 /* Private macro -------------------------------------------------------------*/
0073 /* Private variables ---------------------------------------------------------*/
0074 /* Private function prototypes -----------------------------------------------*/
0075 
0076 
0077 
0078 /* Exported functions---------------------------------------------------------*/
0079 /** @addtogroup CRYPEx_Exported_Functions
0080   * @{
0081   */
0082 
0083 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
0084   * @ingroup RTEMSBSPsARMSTM32H7
0085   *  @brief    CRYPEx Extended processing functions.
0086   *
0087 @verbatim
0088   ==============================================================================
0089               ##### Extended AES processing functions #####
0090   ==============================================================================
0091     [..]  This section provides functions allowing to generate the authentication
0092           TAG in Polling mode
0093       (+)HAL_CRYPEx_AESGCM_GenerateAuthTAG
0094       (+)HAL_CRYPEx_AESCCM_GenerateAuthTAG
0095          they should be used after Encrypt/Decrypt operation.
0096 
0097 @endverbatim
0098   * @{
0099   */
0100 
0101 
0102 /**
0103   * @brief  generate the GCM authentication TAG.
0104   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
0105   *         the configuration information for CRYP module
0106   * @param  AuthTag: Pointer to the authentication buffer
0107   *         the AuthTag generated here is 128bits length, if the TAG length is
0108   *         less than 128bits, user should consider only the valid part of AuthTag
0109   *         buffer which correspond exactly to TAG length.
0110   * @param  Timeout: Timeout duration
0111   * @retval HAL status
0112   */
0113 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
0114 {
0115   uint32_t tickstart;
0116   uint64_t headerlength = (uint64_t)(hcryp->Init.HeaderSize) * 32U; /* Header length in bits */
0117   uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */
0118   uint32_t tagaddr = (uint32_t)AuthTag;
0119 
0120   /* Correct header length if Init.HeaderSize is actually in bytes */
0121   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE)
0122   {
0123     headerlength /= 4U;
0124   }
0125 
0126   if (hcryp->State == HAL_CRYP_STATE_READY)
0127   {
0128     /* Process locked */
0129     __HAL_LOCK(hcryp);
0130 
0131     /* Change the CRYP peripheral state */
0132     hcryp->State = HAL_CRYP_STATE_BUSY;
0133 
0134     /* Check if initialization phase has already been performed */
0135     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
0136     {
0137       /* Change the CRYP phase */
0138       hcryp->Phase = CRYPEx_PHASE_FINAL;
0139     }
0140     else /* Initialization phase has not been performed*/
0141     {
0142       /* Disable the Peripheral */
0143       __HAL_CRYP_DISABLE(hcryp);
0144 
0145       /* Sequence error code field */
0146       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
0147 
0148       /* Change the CRYP peripheral state */
0149       hcryp->State = HAL_CRYP_STATE_READY;
0150 
0151       /* Process unlocked */
0152       __HAL_UNLOCK(hcryp);
0153       return HAL_ERROR;
0154     }
0155 
0156     /* Disable CRYP to start the final phase */
0157     __HAL_CRYP_DISABLE(hcryp);
0158 
0159     /* Select final phase */
0160     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
0161 
0162     /*ALGODIR bit must be set to '0'.*/
0163     hcryp->Instance->CR &=  ~CRYP_CR_ALGODIR;
0164 
0165     /* Enable the CRYP peripheral */
0166     __HAL_CRYP_ENABLE(hcryp);
0167 
0168     /* Write the number of bits in header (64 bits) followed by the number of bits
0169     in the payload */
0170 #if !defined (CRYP_VER_2_2)
0171     /* STM32H7 rev.B and above : data has to be inserted normally (no swapping)*/
0172     if (hcryp->Version >= REV_ID_B)
0173 #endif /*End of not defined CRYP_VER_2_2*/
0174     {
0175       hcryp->Instance->DIN = 0U;
0176       hcryp->Instance->DIN = (uint32_t)(headerlength);
0177       hcryp->Instance->DIN = 0U;
0178       hcryp->Instance->DIN = (uint32_t)(inputlength);
0179     }
0180 #if !defined (CRYP_VER_2_2)
0181     else/* data has to be swapped according to the DATATYPE */
0182     {
0183       if (hcryp->Init.DataType == CRYP_BIT_SWAP)
0184       {
0185         hcryp->Instance->DIN = 0U;
0186         hcryp->Instance->DIN = __RBIT((uint32_t)(headerlength));
0187         hcryp->Instance->DIN = 0U;
0188         hcryp->Instance->DIN = __RBIT((uint32_t)(inputlength));
0189       }
0190       else if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
0191       {
0192         hcryp->Instance->DIN = 0U;
0193         hcryp->Instance->DIN = __REV((uint32_t)(headerlength));
0194         hcryp->Instance->DIN = 0U;
0195         hcryp->Instance->DIN = __REV((uint32_t)(inputlength));
0196       }
0197       else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
0198       {
0199         hcryp->Instance->DIN = 0U;
0200         hcryp->Instance->DIN = __ROR((uint32_t)headerlength, 16U);
0201         hcryp->Instance->DIN = 0U;
0202         hcryp->Instance->DIN = __ROR((uint32_t)inputlength, 16U);
0203       }
0204       else if (hcryp->Init.DataType == CRYP_NO_SWAP)
0205       {
0206         hcryp->Instance->DIN = 0U;
0207         hcryp->Instance->DIN = (uint32_t)(headerlength);
0208         hcryp->Instance->DIN = 0U;
0209         hcryp->Instance->DIN = (uint32_t)(inputlength);
0210       }
0211       else
0212       {
0213         /* Nothing to do */
0214       }
0215     }
0216 #endif /*End of not defined CRYP_VER_2_2*/
0217     /* Wait for OFNE flag to be raised */
0218     tickstart = HAL_GetTick();
0219     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
0220     {
0221       /* Check for the Timeout */
0222       if (Timeout != HAL_MAX_DELAY)
0223       {
0224         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
0225         {
0226           /* Disable the CRYP Peripheral Clock */
0227           __HAL_CRYP_DISABLE(hcryp);
0228 
0229           /* Change state */
0230           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
0231           hcryp->State = HAL_CRYP_STATE_READY;
0232 
0233           /* Process unlocked */
0234           __HAL_UNLOCK(hcryp);
0235           return HAL_ERROR;
0236         }
0237       }
0238     }
0239 
0240     /* Read the authentication TAG in the output FIFO */
0241     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
0242     tagaddr += 4U;
0243     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
0244     tagaddr += 4U;
0245     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
0246     tagaddr += 4U;
0247     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
0248 
0249     /* Disable the peripheral */
0250     __HAL_CRYP_DISABLE(hcryp);
0251 
0252     /* Change the CRYP peripheral state */
0253     hcryp->State = HAL_CRYP_STATE_READY;
0254 
0255     /* Process unlocked */
0256     __HAL_UNLOCK(hcryp);
0257   }
0258   else
0259   {
0260     /* Busy error code field */
0261     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
0262     return HAL_ERROR;
0263   }
0264   /* Return function status */
0265   return HAL_OK;
0266 }
0267 
0268 /**
0269   * @brief  AES CCM Authentication TAG generation.
0270   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
0271   *         the configuration information for CRYP module
0272   * @param  AuthTag: Pointer to the authentication buffer
0273   *         the AuthTag generated here is 128bits length, if the TAG length is
0274   *         less than 128bits, user should consider only the valid part of AuthTag
0275   *         buffer which correspond exactly to TAG length.
0276   * @param  Timeout: Timeout duration
0277   * @retval HAL status
0278   */
0279 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
0280 {
0281   uint32_t tagaddr = (uint32_t)AuthTag;
0282   uint32_t ctr0 [4] = {0};
0283   uint32_t ctr0addr = (uint32_t)ctr0;
0284   uint32_t tickstart;
0285 
0286   if (hcryp->State == HAL_CRYP_STATE_READY)
0287   {
0288     /* Process locked */
0289     __HAL_LOCK(hcryp);
0290 
0291     /* Change the CRYP peripheral state */
0292     hcryp->State = HAL_CRYP_STATE_BUSY;
0293 
0294     /* Check if initialization phase has already been performed */
0295     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
0296     {
0297       /* Change the CRYP phase */
0298       hcryp->Phase = CRYPEx_PHASE_FINAL;
0299     }
0300     else /* Initialization phase has not been performed*/
0301     {
0302       /* Disable the peripheral */
0303       __HAL_CRYP_DISABLE(hcryp);
0304 
0305       /* Sequence error code field */
0306       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
0307 
0308       /* Change the CRYP peripheral state */
0309       hcryp->State = HAL_CRYP_STATE_READY;
0310 
0311       /* Process unlocked */
0312       __HAL_UNLOCK(hcryp);
0313       return HAL_ERROR;
0314     }
0315 
0316     /* Disable CRYP to start the final phase */
0317     __HAL_CRYP_DISABLE(hcryp);
0318 
0319     /* Select final phase & ALGODIR bit must be set to '0'. */
0320     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH | CRYP_CR_ALGODIR, CRYP_PHASE_FINAL | CRYP_OPERATINGMODE_ENCRYPT);
0321 
0322     /* Enable the CRYP peripheral */
0323     __HAL_CRYP_ENABLE(hcryp);
0324 
0325     /* Write the counter block in the IN FIFO, CTR0 information from B0
0326     data has to be swapped according to the DATATYPE*/
0327     ctr0[0] = (hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
0328     ctr0[1] = hcryp->Init.B0[1];
0329     ctr0[2] = hcryp->Init.B0[2];
0330     ctr0[3] = hcryp->Init.B0[3] &  CRYP_CCM_CTR0_3;
0331 
0332 #if !defined (CRYP_VER_2_2)
0333     /*STM32H7 rev.B and above : data has to be inserted normally (no swapping)*/
0334     if (hcryp->Version >= REV_ID_B)
0335 #endif /*End of not defined CRYP_VER_2_2*/
0336     {
0337       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
0338       ctr0addr += 4U;
0339       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
0340       ctr0addr += 4U;
0341       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
0342       ctr0addr += 4U;
0343       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
0344     }
0345 #if !defined (CRYP_VER_2_2)
0346     else /* data has to be swapped according to the DATATYPE */
0347     {
0348       if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
0349       {
0350         hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
0351         ctr0addr += 4U;
0352         hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
0353         ctr0addr += 4U;
0354         hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
0355         ctr0addr += 4U;
0356         hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
0357       }
0358       else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
0359       {
0360         hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
0361         ctr0addr += 4U;
0362         hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
0363         ctr0addr += 4U;
0364         hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
0365         ctr0addr += 4U;
0366         hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
0367       }
0368       else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
0369       {
0370         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
0371         ctr0addr += 4U;
0372         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
0373         ctr0addr += 4U;
0374         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
0375         ctr0addr += 4U;
0376         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
0377       }
0378       else
0379       {
0380         hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
0381         ctr0addr += 4U;
0382         hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
0383         ctr0addr += 4U;
0384         hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
0385         ctr0addr += 4U;
0386         hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
0387       }
0388     }
0389 #endif /*End of not defined CRYP_VER_2_2*/
0390     /* Wait for OFNE flag to be raised */
0391     tickstart = HAL_GetTick();
0392     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
0393     {
0394       /* Check for the Timeout */
0395       if (Timeout != HAL_MAX_DELAY)
0396       {
0397         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
0398         {
0399           /* Disable the CRYP peripheral Clock */
0400           __HAL_CRYP_DISABLE(hcryp);
0401 
0402           /* Change state */
0403           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
0404           hcryp->State = HAL_CRYP_STATE_READY;
0405 
0406           /* Process unlocked */
0407           __HAL_UNLOCK(hcryp);
0408           return HAL_ERROR;
0409         }
0410       }
0411     }
0412 
0413     /* Read the Auth TAG in the IN FIFO */
0414     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
0415     tagaddr += 4U;
0416     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
0417     tagaddr += 4U;
0418     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
0419     tagaddr += 4U;
0420     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
0421 
0422     /* Change the CRYP peripheral state */
0423     hcryp->State = HAL_CRYP_STATE_READY;
0424 
0425     /* Process unlocked */
0426     __HAL_UNLOCK(hcryp);
0427 
0428     /* Disable CRYP  */
0429     __HAL_CRYP_DISABLE(hcryp);
0430   }
0431   else
0432   {
0433     /* Busy error code field */
0434     hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
0435     return HAL_ERROR;
0436   }
0437   /* Return function status */
0438   return HAL_OK;
0439 }
0440 
0441 /**
0442   * @}
0443   */
0444 
0445 
0446 #endif /* HAL_CRYP_MODULE_ENABLED */
0447 
0448 /**
0449   * @}
0450   */
0451 #endif /* CRYP */
0452 /**
0453   * @}
0454   */
0455 
0456 /**
0457   * @}
0458   */