]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil/ST_Library/stm32f7xx_hal_hash_ex.c
Final V8.2.1 release ready for tagging:
[freertos] / FreeRTOS / Demo / CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil / ST_Library / stm32f7xx_hal_hash_ex.c
diff --git a/FreeRTOS/Demo/CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil/ST_Library/stm32f7xx_hal_hash_ex.c b/FreeRTOS/Demo/CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil/ST_Library/stm32f7xx_hal_hash_ex.c
new file mode 100644 (file)
index 0000000..51b0c95
--- /dev/null
@@ -0,0 +1,1625 @@
+/**\r
+  ******************************************************************************\r
+  * @file    stm32f7xx_hal_hash_ex.c\r
+  * @author  MCD Application Team\r
+  * @version V1.0.0RC1\r
+  * @date    24-March-2015\r
+  * @brief   HASH HAL Extension module driver.\r
+  *          This file provides firmware functions to manage the following \r
+  *          functionalities of HASH peripheral:\r
+  *           + Extended HASH processing functions based on SHA224 Algorithm\r
+  *           + Extended HASH processing functions based on SHA256 Algorithm\r
+  *         \r
+  @verbatim\r
+  ==============================================================================\r
+                     ##### How to use this driver #####\r
+  ==============================================================================\r
+    [..]\r
+    The HASH HAL driver can be used as follows:\r
+    (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():\r
+        (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()\r
+        (##) In case of using processing APIs based on interrupts (e.g. HAL_HMACEx_SHA224_Start())\r
+            (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()\r
+            (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()\r
+            (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()\r
+        (##) In case of using DMA to control data transfer (e.g. HAL_HMACEx_SH224_Start_DMA())\r
+            (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()\r
+            (+++) Configure and enable one DMA stream one for managing data transfer from\r
+                memory to peripheral (input stream). Managing data transfer from\r
+                peripheral to memory can be performed only using CPU\r
+            (+++) Associate the initialized DMA handle to the HASH DMA handle\r
+                using  __HAL_LINKDMA()\r
+            (+++) Configure the priority and enable the NVIC for the transfer complete\r
+                interrupt on the DMA Stream: HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()\r
+    (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:\r
+        (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.\r
+        (##) For HMAC, the encryption key.\r
+        (##) For HMAC, the key size used for encryption.\r
+    (#)Three processing functions are available:\r
+        (##) Polling mode: processing APIs are blocking functions\r
+             i.e. they process the data and wait till the digest computation is finished\r
+             e.g. HAL_HASHEx_SHA224_Start()\r
+        (##) Interrupt mode: encryption and decryption APIs are not blocking functions\r
+                i.e. they process the data under interrupt\r
+                e.g. HAL_HASHEx_SHA224_Start_IT()\r
+        (##) DMA mode: processing APIs are not blocking functions and the CPU is\r
+             not used for data transfer i.e. the data transfer is ensured by DMA\r
+                e.g. HAL_HASHEx_SHA224_Start_DMA()\r
+    (#)When the processing function is called at first time after HAL_HASH_Init()\r
+       the HASH peripheral is initialized and processes the buffer in input.\r
+       After that, the digest computation is started.\r
+       When processing multi-buffer use the accumulate function to write the\r
+       data in the peripheral without starting the digest computation. In last \r
+       buffer use the start function to input the last buffer ans start the digest\r
+       computation.\r
+       (##) e.g. HAL_HASHEx_SHA224_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation\r
+       (##)  write (n-1)th data buffer in the peripheral without starting the digest computation\r
+       (##)  HAL_HASHEx_SHA224_Start() : write (n)th data buffer in the peripheral and start the digest computation\r
+    (#)In HMAC mode, there is no Accumulate API. Only Start API is available.\r
+    (#)In case of using DMA, call the DMA start processing e.g. HAL_HASHEx_SHA224_Start_DMA().\r
+       After that, call the finish function in order to get the digest value\r
+       e.g. HAL_HASHEx_SHA224_Finish()\r
+    (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.\r
+\r
+  @endverbatim\r
+  ******************************************************************************\r
+  * @attention\r
+  *\r
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>\r
+  *\r
+  * Redistribution and use in source and binary forms, with or without modification,\r
+  * are permitted provided that the following conditions are met:\r
+  *   1. Redistributions of source code must retain the above copyright notice,\r
+  *      this list of conditions and the following disclaimer.\r
+  *   2. Redistributions in binary form must reproduce the above copyright notice,\r
+  *      this list of conditions and the following disclaimer in the documentation\r
+  *      and/or other materials provided with the distribution.\r
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors\r
+  *      may be used to endorse or promote products derived from this software\r
+  *      without specific prior written permission.\r
+  *\r
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+  *\r
+  ******************************************************************************\r
+  */ \r
+\r
+/* Includes ------------------------------------------------------------------*/\r
+#include "stm32f7xx_hal.h"\r
+\r
+/** @addtogroup STM32F7xx_HAL_Driver\r
+  * @{\r
+  */\r
+\r
+/** @defgroup HASHEx HASHEx\r
+  * @brief HASH Extension HAL module driver.\r
+  * @{\r
+  */\r
+\r
+#ifdef HAL_HASH_MODULE_ENABLED\r
+\r
+#if defined(STM32F756xx)\r
+\r
+/* Private typedef -----------------------------------------------------------*/\r
+/* Private define ------------------------------------------------------------*/\r
+/* Private macro -------------------------------------------------------------*/\r
+/* Private variables ---------------------------------------------------------*/\r
+/* Private function prototypes -----------------------------------------------*/\r
+/** @addtogroup HASHEx_Private_Functions\r
+  * @{\r
+  */\r
+static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma);\r
+static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size);\r
+static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size);\r
+static void HASHEx_DMAError(DMA_HandleTypeDef *hdma);\r
+/**\r
+  * @}\r
+  */\r
+  \r
+/* Private functions ---------------------------------------------------------*/\r
+\r
+/** @addtogroup HASHEx_Private_Functions\r
+  * @{\r
+  */\r
+\r
+/**\r
+  * @brief  Writes the input buffer in data register.\r
+  * @param  pInBuffer: Pointer to input buffer\r
+  * @param  Size: The size of input buffer\r
+  * @retval None\r
+  */\r
+static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size)\r
+{\r
+  uint32_t buffercounter;\r
+  uint32_t inputaddr = (uint32_t) pInBuffer;\r
+  \r
+  for(buffercounter = 0; buffercounter < Size; buffercounter+=4)\r
+  {\r
+    HASH->DIN = *(uint32_t*)inputaddr;\r
+    inputaddr+=4;\r
+  }\r
+}\r
+\r
+/**\r
+  * @brief  Provides the message digest result.\r
+  * @param  pMsgDigest: Pointer to the message digest\r
+  * @param  Size: The size of the message digest in bytes\r
+  * @retval None\r
+  */\r
+static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size)\r
+{\r
+  uint32_t msgdigest = (uint32_t)pMsgDigest;\r
+  \r
+  switch(Size)\r
+  {\r
+  case 16:\r
+    /* Read the message digest */\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);\r
+    break;\r
+  case 20:\r
+    /* Read the message digest */\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);\r
+    break;\r
+  case 28:\r
+    /* Read the message digest */\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);\r
+    break;\r
+  case 32:\r
+    /* Read the message digest */\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);\r
+    msgdigest+=4;\r
+    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);\r
+    break;\r
+  default:\r
+    break;\r
+  }\r
+}\r
+\r
+/**\r
+  * @brief  DMA HASH Input Data complete callback. \r
+  * @param  hdma: DMA handle\r
+  * @retval None\r
+  */\r
+static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma)\r
+{\r
+  HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
+  uint32_t inputaddr = 0;\r
+  uint32_t buffersize = 0;\r
+  \r
+  if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)\r
+  {\r
+    /* Disable the DMA transfer */\r
+    HASH->CR &= (uint32_t)(~HASH_CR_DMAE);\r
+    \r
+    /* Change HASH peripheral state */\r
+    hhash->State = HAL_HASH_STATE_READY;\r
+    \r
+    /* Call Input data transfer complete callback */\r
+    HAL_HASH_InCpltCallback(hhash);\r
+  }\r
+  else\r
+  {\r
+    /* Increment Interrupt counter */\r
+    hhash->HashInCount++;\r
+    /* Disable the DMA transfer before starting the next transfer */\r
+    HASH->CR &= (uint32_t)(~HASH_CR_DMAE);\r
+    \r
+    if(hhash->HashInCount <= 2)\r
+    {\r
+      /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */\r
+      if(hhash->HashInCount == 1)\r
+      {\r
+        inputaddr = (uint32_t)hhash->pHashInBuffPtr;\r
+        buffersize = hhash->HashBuffSize;\r
+      }\r
+      /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */\r
+      else if(hhash->HashInCount == 2)\r
+      {\r
+        inputaddr = (uint32_t)hhash->Init.pKey;\r
+        buffersize = hhash->Init.KeySize;\r
+      }\r
+      /* Configure the number of valid bits in last word of the message */\r
+      HASH->STR |= 8 * (buffersize % 4);\r
+      \r
+      /* Set the HASH DMA transfer complete */\r
+      hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;\r
+      \r
+      /* Enable the DMA In DMA Stream */\r
+      HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4 ? (buffersize+3)/4:buffersize/4));\r
+      \r
+      /* Enable DMA requests */\r
+      HASH->CR |= (HASH_CR_DMAE);\r
+    }\r
+    else\r
+    {\r
+      /* Disable the DMA transfer */\r
+      HASH->CR &= (uint32_t)(~HASH_CR_DMAE);\r
+      \r
+      /* Reset the InCount */\r
+      hhash->HashInCount = 0;\r
+      \r
+      /* Change HASH peripheral state */\r
+      hhash->State = HAL_HASH_STATE_READY;\r
+      \r
+      /* Call Input data transfer complete callback */\r
+      HAL_HASH_InCpltCallback(hhash);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  * @brief  DMA HASH communication error callback. \r
+  * @param  hdma: DMA handle\r
+  * @retval None\r
+  */\r
+static void HASHEx_DMAError(DMA_HandleTypeDef *hdma)\r
+{\r
+  HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
+  hhash->State= HAL_HASH_STATE_READY;\r
+  HAL_HASH_ErrorCallback(hhash);\r
+}\r
+\r
+ /**\r
+  * @}\r
+  */\r
+  \r
+/* Exported functions --------------------------------------------------------*/\r
+/** @addtogroup HASHEx_Exported_Functions\r
+  * @{\r
+  */\r
+  \r
+/** @defgroup  HASHEx_Group1 HASH processing functions  \r
+ *  @brief   processing functions using polling mode \r
+ *\r
+@verbatim   \r
+ ===============================================================================\r
+              ##### HASH processing using polling mode functions #####\r
+ ===============================================================================  \r
+    [..]  This section provides functions allowing to calculate in polling mode\r
+          the hash value using one of the following algorithms:\r
+      (+) SHA224\r
+      (+) SHA256\r
+\r
+@endverbatim\r
+  * @{\r
+  */\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in SHA224 mode\r
+  *         then processes pInBuffer. The digest is available in pOutBuffer\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).\r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.\r
+  * @param  Timeout: Specify Timeout value   \r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HASHEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)\r
+{\r
+  uint32_t tickstart = 0;   \r
+  \r
+  /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Check if initialization phase has already been performed */\r
+  if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+  {\r
+    /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute \r
+       the message digest of a new message */\r
+    HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;\r
+  }\r
+  \r
+  /* Set the phase */\r
+  hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+  \r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(Size);\r
+  \r
+  /* Write input buffer in data register */\r
+  HASHEx_WriteData(pInBuffer, Size);\r
+  \r
+  /* Start the digest calculation */\r
+  __HAL_HASH_START_DIGEST();\r
+  \r
+  /* Get tick */\r
+  tickstart = HAL_GetTick();\r
+  \r
+  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)\r
+  {\r
+    /* Check for the Timeout */\r
+    if(Timeout != HAL_MAX_DELAY)\r
+    {\r
+      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))\r
+      {\r
+        /* Change state */\r
+        hhash->State = HAL_HASH_STATE_TIMEOUT;\r
+        \r
+        /* Process Unlocked */          \r
+        __HAL_UNLOCK(hhash);\r
+        \r
+        return HAL_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+  \r
+  /* Read the message digest */\r
+  HASHEx_GetDigest(pOutBuffer, 28);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_READY;\r
+  \r
+  /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.\r
+            The digest is available in pOutBuffer.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed). \r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.\r
+  * @param  Timeout: Specify Timeout value   \r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)\r
+{\r
+  uint32_t tickstart = 0;   \r
+  \r
+  /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Check if initialization phase has already been performed */\r
+  if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+  {\r
+    /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute \r
+       the message digest of a new message */\r
+    HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;\r
+  }\r
+  \r
+  /* Set the phase */\r
+  hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+  \r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(Size);\r
+  \r
+  /* Write input buffer in data register */\r
+  HASHEx_WriteData(pInBuffer, Size);\r
+  \r
+  /* Start the digest calculation */\r
+  __HAL_HASH_START_DIGEST();\r
+  \r
+  /* Get tick */\r
+  tickstart = HAL_GetTick();\r
+  \r
+  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)\r
+  {\r
+    /* Check for the Timeout */\r
+    if(Timeout != HAL_MAX_DELAY)\r
+    {\r
+      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))\r
+      {\r
+        /* Change state */\r
+        hhash->State = HAL_HASH_STATE_TIMEOUT;\r
+        \r
+        /* Process Unlocked */          \r
+        __HAL_UNLOCK(hhash);\r
+        \r
+        return HAL_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+  \r
+  /* Read the message digest */\r
+  HASHEx_GetDigest(pOutBuffer, 32);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_READY;\r
+\r
+  /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);  \r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in SHA224 mode\r
+  *         then processes pInBuffer. The digest is available in pOutBuffer\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).\r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HASHEx_SHA224_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)\r
+{\r
+  /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Check if initialization phase has already been performed */\r
+  if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+  {\r
+    /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute \r
+       the message digest of a new message */\r
+    HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;\r
+  }\r
+  \r
+  /* Set the phase */\r
+  hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+  \r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(Size);\r
+  \r
+  /* Write input buffer in data register */\r
+  HASHEx_WriteData(pInBuffer, Size);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_READY;\r
+  \r
+  /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.\r
+            The digest is available in pOutBuffer.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).\r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HASHEx_SHA256_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)\r
+{\r
+   /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Check if initialization phase has already been performed */\r
+  if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+  {\r
+    /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute \r
+       the message digest of a new message */\r
+    HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;\r
+  }\r
+  \r
+  /* Set the phase */\r
+  hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+  \r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(Size);\r
+  \r
+  /* Write input buffer in data register */\r
+  HASHEx_WriteData(pInBuffer, Size);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_READY;\r
+  \r
+  /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+\r
+/**\r
+  * @}\r
+  */\r
+\r
+/** @defgroup HASHEx_Group2 HMAC processing functions using polling mode \r
+ *  @brief   HMAC processing functions using polling mode . \r
+ *\r
+@verbatim   \r
+ ===============================================================================\r
+            ##### HMAC processing using polling mode functions #####\r
+ ===============================================================================  \r
+    [..]  This section provides functions allowing to calculate in polling mode\r
+          the HMAC value using one of the following algorithms:\r
+      (+) SHA224\r
+      (+) SHA256\r
+\r
+@endverbatim\r
+  * @{\r
+  */\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in HMAC SHA224 mode\r
+  *         then processes pInBuffer. The digest is available in pOutBuffer.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed). \r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.\r
+  * @param  Timeout: Timeout value \r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HMACEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)\r
+{\r
+  uint32_t tickstart = 0;   \r
+                                                  \r
+   /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Check if initialization phase has already been performed */\r
+  if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+  {\r
+    /* Check if key size is greater than 64 bytes */\r
+    if(hhash->Init.KeySize > 64)\r
+    {\r
+      /* Select the HMAC SHA224 mode */\r
+      HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);\r
+    }\r
+    else\r
+    {\r
+      /* Select the HMAC SHA224 mode */\r
+      HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);\r
+    }\r
+  }\r
+  \r
+  /* Set the phase */\r
+  hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+  \r
+  /************************** STEP 1 ******************************************/\r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);\r
+  \r
+  /* Write input buffer in data register */\r
+  HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);\r
+  \r
+  /* Start the digest calculation */\r
+  __HAL_HASH_START_DIGEST();\r
+  \r
+  /* Get tick */\r
+  tickstart = HAL_GetTick();\r
+  \r
+  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)\r
+  {\r
+    /* Check for the Timeout */\r
+    if(Timeout != HAL_MAX_DELAY)\r
+    {\r
+      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))\r
+      {\r
+        /* Change state */\r
+        hhash->State = HAL_HASH_STATE_TIMEOUT;\r
+        \r
+        /* Process Unlocked */          \r
+        __HAL_UNLOCK(hhash);\r
+        \r
+        return HAL_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+  /************************** STEP 2 ******************************************/\r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(Size);\r
+  \r
+  /* Write input buffer in data register */\r
+  HASHEx_WriteData(pInBuffer, Size);\r
+  \r
+  /* Start the digest calculation */\r
+  __HAL_HASH_START_DIGEST();\r
+  \r
+  /* Get tick */\r
+  tickstart = HAL_GetTick();\r
+  \r
+  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)\r
+  {\r
+    /* Check for the Timeout */\r
+    if(Timeout != HAL_MAX_DELAY)\r
+    {\r
+      if((HAL_GetTick() - tickstart ) > Timeout)\r
+      {\r
+        /* Change state */\r
+        hhash->State = HAL_HASH_STATE_TIMEOUT;\r
+        \r
+        /* Process Unlocked */          \r
+        __HAL_UNLOCK(hhash);\r
+        \r
+        return HAL_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+  /************************** STEP 3 ******************************************/\r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);\r
+  \r
+  /* Write input buffer in data register */\r
+  HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);\r
+  \r
+  /* Start the digest calculation */\r
+  __HAL_HASH_START_DIGEST();\r
+  \r
+  /* Get tick */\r
+  tickstart = HAL_GetTick();\r
+  \r
+  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)\r
+  {\r
+    /* Check for the Timeout */\r
+    if(Timeout != HAL_MAX_DELAY)\r
+    {\r
+      if((HAL_GetTick() - tickstart ) > Timeout)\r
+      {\r
+        /* Change state */\r
+        hhash->State = HAL_HASH_STATE_TIMEOUT;\r
+        \r
+        /* Process Unlocked */          \r
+        __HAL_UNLOCK(hhash);\r
+        \r
+        return HAL_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+  /* Read the message digest */\r
+  HASHEx_GetDigest(pOutBuffer, 28);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_READY;\r
+  \r
+  /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in HMAC SHA256 mode\r
+  *         then processes pInBuffer. The digest is available in pOutBuffer\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed). \r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.\r
+  * @param  Timeout: Timeout value \r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)\r
+{\r
+  uint32_t tickstart = 0;   \r
+  \r
+  /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Check if initialization phase has already been performed */\r
+  if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+  {\r
+    /* Check if key size is greater than 64 bytes */\r
+    if(hhash->Init.KeySize > 64)\r
+    {\r
+      /* Select the HMAC SHA256 mode */\r
+      HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY);\r
+    }\r
+    else\r
+    {\r
+      /* Select the HMAC SHA256 mode */\r
+      HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC);\r
+    }\r
+    /* Reset the HASH processor core, so that the HASH will be ready to compute \r
+       the message digest of a new message */\r
+    HASH->CR |= HASH_CR_INIT;\r
+  }\r
+  \r
+  /* Set the phase */\r
+  hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+  \r
+  /************************** STEP 1 ******************************************/\r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);\r
+  \r
+  /* Write input buffer in data register */\r
+  HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);\r
+  \r
+  /* Start the digest calculation */\r
+  __HAL_HASH_START_DIGEST();\r
+  \r
+  /* Get tick */\r
+  tickstart = HAL_GetTick();\r
+  \r
+  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)\r
+  {\r
+    /* Check for the Timeout */\r
+    if(Timeout != HAL_MAX_DELAY)\r
+    {\r
+      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))\r
+      {\r
+        /* Change state */\r
+        hhash->State = HAL_HASH_STATE_TIMEOUT;\r
+        \r
+        /* Process Unlocked */          \r
+        __HAL_UNLOCK(hhash);\r
+        \r
+        return HAL_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+  /************************** STEP 2 ******************************************/\r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(Size);\r
+  \r
+  /* Write input buffer in data register */\r
+  HASHEx_WriteData(pInBuffer, Size);\r
+  \r
+  /* Start the digest calculation */\r
+  __HAL_HASH_START_DIGEST();\r
+  \r
+  /* Get tick */\r
+  tickstart = HAL_GetTick();\r
+  \r
+  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)\r
+  {\r
+    /* Check for the Timeout */\r
+    if(Timeout != HAL_MAX_DELAY)\r
+    {\r
+      if((HAL_GetTick() - tickstart ) > Timeout)\r
+      {\r
+        /* Change state */\r
+        hhash->State = HAL_HASH_STATE_TIMEOUT;\r
+        \r
+        /* Process Unlocked */          \r
+        __HAL_UNLOCK(hhash);\r
+        \r
+        return HAL_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+  /************************** STEP 3 ******************************************/\r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);\r
+  \r
+  /* Write input buffer in data register */\r
+  HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);\r
+  \r
+  /* Start the digest calculation */\r
+  __HAL_HASH_START_DIGEST();\r
+  \r
+  /* Get tick */\r
+  tickstart = HAL_GetTick();\r
+  \r
+  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)\r
+  {\r
+    /* Check for the Timeout */\r
+    if(Timeout != HAL_MAX_DELAY)\r
+    {\r
+      if((HAL_GetTick() - tickstart ) > Timeout)\r
+      {\r
+        /* Change state */\r
+        hhash->State = HAL_HASH_STATE_TIMEOUT;\r
+        \r
+        /* Process Unlocked */          \r
+        __HAL_UNLOCK(hhash);\r
+        \r
+        return HAL_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+  /* Read the message digest */\r
+  HASHEx_GetDigest(pOutBuffer, 32);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_READY;\r
+  \r
+   /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+/**\r
+  * @}\r
+  */\r
+\r
+/** @defgroup HASHEx_Group3 HASH processing functions using interrupt mode\r
+ *  @brief   processing functions using interrupt mode. \r
+ *\r
+@verbatim   \r
+ ===============================================================================\r
+              ##### HASH processing using interrupt functions #####\r
+ ===============================================================================  \r
+    [..]  This section provides functions allowing to calculate in interrupt mode\r
+          the hash value using one of the following algorithms:\r
+      (+) SHA224\r
+      (+) SHA256\r
+\r
+@endverbatim\r
+  * @{\r
+  */\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in SHA224 mode then processes pInBuffer.\r
+  *         The digest is available in pOutBuffer.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).\r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.\r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)\r
+{\r
+  uint32_t inputaddr;\r
+  uint32_t buffercounter;\r
+  uint32_t inputcounter;\r
+  \r
+  /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  if(hhash->HashITCounter == 0)\r
+  {\r
+    hhash->HashITCounter = 1;\r
+  }\r
+  else\r
+  {\r
+    hhash->HashITCounter = 0;\r
+  }\r
+  if(hhash->State == HAL_HASH_STATE_READY)\r
+  {\r
+    /* Change the HASH state */\r
+    hhash->State = HAL_HASH_STATE_BUSY;\r
+    \r
+    hhash->HashInCount = Size;\r
+    hhash->pHashInBuffPtr = pInBuffer;\r
+    hhash->pHashOutBuffPtr = pOutBuffer;\r
+    \r
+    /* Check if initialization phase has already been performed */\r
+    if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+    {\r
+      /* Select the SHA224 mode */\r
+      HASH->CR |= HASH_ALGOSELECTION_SHA224;\r
+      /* Reset the HASH processor core, so that the HASH will be ready to compute \r
+         the message digest of a new message */\r
+      HASH->CR |= HASH_CR_INIT;\r
+    }\r
+    \r
+    /* Set the phase */\r
+    hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+    \r
+    /* Process Unlocked */\r
+    __HAL_UNLOCK(hhash);\r
+    \r
+    /* Enable Interrupts */\r
+    HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);\r
+    \r
+    /* Return function status */\r
+    return HAL_OK;\r
+  }\r
+  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))\r
+  {\r
+    /* Read the message digest */\r
+    HASHEx_GetDigest(hhash->pHashOutBuffPtr, 28);\r
+    if(hhash->HashInCount == 0)\r
+    {\r
+      /* Disable Interrupts */\r
+      HASH->IMR = 0;\r
+      /* Change the HASH state */\r
+      hhash->State = HAL_HASH_STATE_READY;\r
+      /* Call digest computation complete callback */\r
+      HAL_HASH_DgstCpltCallback(hhash);\r
+    }\r
+  }\r
+  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))\r
+  {\r
+    if(hhash->HashInCount > 64)\r
+    {\r
+      inputaddr = (uint32_t)hhash->pHashInBuffPtr;\r
+      /* Write the Input block in the Data IN register */\r
+      for(buffercounter = 0; buffercounter < 64; buffercounter+=4)\r
+      {\r
+        HASH->DIN = *(uint32_t*)inputaddr;\r
+        inputaddr+=4;\r
+      }\r
+      if(hhash->HashITCounter == 0)\r
+      {\r
+        HASH->DIN = *(uint32_t*)inputaddr;\r
+        if(hhash->HashInCount >= 68)\r
+        {\r
+          /* Decrement buffer counter */\r
+          hhash->HashInCount -= 68;\r
+          hhash->pHashInBuffPtr+= 68;\r
+        }\r
+        else\r
+        {\r
+          hhash->HashInCount -= 64;\r
+        }\r
+      }\r
+      else\r
+      {\r
+        /* Decrement buffer counter */\r
+        hhash->HashInCount -= 64;\r
+        hhash->pHashInBuffPtr+= 64;\r
+      }\r
+    }\r
+    else\r
+    {\r
+      /* Get the buffer address */\r
+      inputaddr = (uint32_t)hhash->pHashInBuffPtr;\r
+      /* Get the buffer counter */\r
+      inputcounter = hhash->HashInCount;\r
+      /* Disable Interrupts */\r
+      HASH->IMR &= ~(HASH_IT_DINI);\r
+      /* Configure the number of valid bits in last word of the message */\r
+      __HAL_HASH_SET_NBVALIDBITS(inputcounter);\r
+      \r
+      if((inputcounter > 4) && (inputcounter%4))\r
+      {\r
+        inputcounter = (inputcounter+4-inputcounter%4);\r
+      }\r
+      \r
+      /* Write the Input block in the Data IN register */\r
+      for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)\r
+      {\r
+        HASH->DIN = *(uint32_t*)inputaddr;\r
+        inputaddr+=4;\r
+      }\r
+      /* Start the digest calculation */\r
+      __HAL_HASH_START_DIGEST();\r
+      /* Reset buffer counter */\r
+      hhash->HashInCount = 0;\r
+    }\r
+    /* Call Input data transfer complete callback */\r
+    HAL_HASH_InCpltCallback(hhash);\r
+  }\r
+  \r
+  /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.\r
+  *         The digest is available in pOutBuffer.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).\r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.\r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)\r
+{\r
+  uint32_t inputaddr;\r
+  uint32_t buffercounter;\r
+  uint32_t inputcounter;\r
+  \r
+  /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  if(hhash->HashITCounter == 0)\r
+  {\r
+    hhash->HashITCounter = 1;\r
+  }\r
+  else\r
+  {\r
+    hhash->HashITCounter = 0;\r
+  }\r
+  if(hhash->State == HAL_HASH_STATE_READY)\r
+  {\r
+    /* Change the HASH state */\r
+    hhash->State = HAL_HASH_STATE_BUSY;\r
+    \r
+    hhash->HashInCount = Size;\r
+    hhash->pHashInBuffPtr = pInBuffer;\r
+    hhash->pHashOutBuffPtr = pOutBuffer;\r
+    \r
+    /* Check if initialization phase has already been performed */\r
+    if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+    {\r
+      /* Select the SHA256 mode */\r
+      HASH->CR |= HASH_ALGOSELECTION_SHA256;\r
+      /* Reset the HASH processor core, so that the HASH will be ready to compute \r
+         the message digest of a new message */\r
+      HASH->CR |= HASH_CR_INIT;\r
+    }\r
+    \r
+    /* Set the phase */\r
+    hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+    \r
+    /* Process Unlocked */\r
+    __HAL_UNLOCK(hhash);\r
+    \r
+    /* Enable Interrupts */\r
+    HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);\r
+    \r
+    /* Return function status */\r
+    return HAL_OK;\r
+  }\r
+  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))\r
+  {\r
+    /* Read the message digest */\r
+    HASHEx_GetDigest(hhash->pHashOutBuffPtr, 32);\r
+    if(hhash->HashInCount == 0)\r
+    {\r
+      /* Disable Interrupts */\r
+      HASH->IMR = 0;\r
+      /* Change the HASH state */\r
+      hhash->State = HAL_HASH_STATE_READY;\r
+      /* Call digest computation complete callback */\r
+      HAL_HASH_DgstCpltCallback(hhash);\r
+    }\r
+  }\r
+  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))\r
+  {\r
+    if(hhash->HashInCount > 64)\r
+    {\r
+      inputaddr = (uint32_t)hhash->pHashInBuffPtr;\r
+      /* Write the Input block in the Data IN register */\r
+      for(buffercounter = 0; buffercounter < 64; buffercounter+=4)\r
+      {\r
+        HASH->DIN = *(uint32_t*)inputaddr;\r
+        inputaddr+=4;\r
+      }\r
+      if(hhash->HashITCounter == 0)\r
+      {\r
+        HASH->DIN = *(uint32_t*)inputaddr;\r
+        \r
+        if(hhash->HashInCount >= 68)\r
+        {\r
+          /* Decrement buffer counter */\r
+          hhash->HashInCount -= 68;\r
+          hhash->pHashInBuffPtr+= 68;\r
+        }\r
+        else\r
+        {\r
+          hhash->HashInCount -= 64;\r
+        }\r
+      }\r
+      else\r
+      {\r
+        /* Decrement buffer counter */\r
+        hhash->HashInCount -= 64;\r
+        hhash->pHashInBuffPtr+= 64;\r
+      }\r
+    }\r
+    else\r
+    {\r
+      /* Get the buffer address */\r
+      inputaddr = (uint32_t)hhash->pHashInBuffPtr;\r
+      /* Get the buffer counter */\r
+      inputcounter = hhash->HashInCount;\r
+      /* Disable Interrupts */\r
+      HASH->IMR &= ~(HASH_IT_DINI);\r
+      /* Configure the number of valid bits in last word of the message */\r
+      __HAL_HASH_SET_NBVALIDBITS(inputcounter);\r
+      \r
+      if((inputcounter > 4) && (inputcounter%4))\r
+      {\r
+        inputcounter = (inputcounter+4-inputcounter%4);\r
+      }\r
+      \r
+      /* Write the Input block in the Data IN register */\r
+      for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)\r
+      {\r
+        HASH->DIN = *(uint32_t*)inputaddr;\r
+        inputaddr+=4;\r
+      }\r
+      /* Start the digest calculation */\r
+      __HAL_HASH_START_DIGEST();\r
+      /* Reset buffer counter */\r
+      hhash->HashInCount = 0;\r
+    }\r
+    /* Call Input data transfer complete callback */\r
+    HAL_HASH_InCpltCallback(hhash);\r
+  }\r
+  \r
+  /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+/**\r
+  * @brief This function handles HASH interrupt request.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @retval None\r
+  */\r
+void HAL_HASHEx_IRQHandler(HASH_HandleTypeDef *hhash)\r
+{\r
+  switch(HASH->CR & HASH_CR_ALGO)\r
+  {\r
+    \r
+    case HASH_ALGOSELECTION_SHA224:\r
+       HAL_HASHEx_SHA224_Start_IT(hhash, NULL, 0, NULL);\r
+    break;\r
+    \r
+    case HASH_ALGOSELECTION_SHA256:\r
+      HAL_HASHEx_SHA256_Start_IT(hhash, NULL, 0, NULL);\r
+    break;\r
+    \r
+    default:\r
+    break;\r
+  }\r
+}\r
+\r
+/**\r
+  * @}\r
+  */\r
+\r
+/** @defgroup HASHEx_Group4 HASH processing functions using DMA mode\r
+ *  @brief   processing functions using DMA mode. \r
+ *\r
+@verbatim   \r
+ ===============================================================================\r
+                ##### HASH processing using DMA functions #####\r
+ ===============================================================================  \r
+    [..]  This section provides functions allowing to calculate in DMA mode\r
+          the hash value using one of the following algorithms:\r
+      (+) SHA224\r
+      (+) SHA256\r
+\r
+@endverbatim\r
+  * @{\r
+  */\r
+\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in SHA224 mode then enables DMA to\r
+            control data transfer. Use HAL_HASH_SHA224_Finish() to get the digest.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).\r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)\r
+{\r
+  uint32_t inputaddr  = (uint32_t)pInBuffer;\r
+  \r
+   /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Check if initialization phase has already been performed */\r
+  if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+  {\r
+    /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute \r
+       the message digest of a new message */\r
+    HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;\r
+  }\r
+   \r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(Size);\r
+  \r
+  /* Set the phase */\r
+  hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+    \r
+  /* Set the HASH DMA transfer complete callback */\r
+  hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;\r
+  /* Set the DMA error callback */\r
+  hhash->hdmain->XferErrorCallback = HASHEx_DMAError;\r
+  \r
+  /* Enable the DMA In DMA Stream */\r
+  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));\r
+  \r
+  /* Enable DMA requests */\r
+  HASH->CR |= (HASH_CR_DMAE);\r
+  \r
+   /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+/**\r
+  * @brief  Returns the computed digest in SHA224\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.\r
+  * @param  Timeout: Timeout value    \r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HASHEx_SHA224_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)\r
+{\r
+  uint32_t tickstart = 0;   \r
+  \r
+  /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change HASH peripheral state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Get tick */\r
+  tickstart = HAL_GetTick();\r
+  \r
+  while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))\r
+  {\r
+    /* Check for the Timeout */\r
+    if(Timeout != HAL_MAX_DELAY)\r
+    {\r
+      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))\r
+      {\r
+        /* Change state */\r
+        hhash->State = HAL_HASH_STATE_TIMEOUT;\r
+        \r
+        /* Process Unlocked */          \r
+        __HAL_UNLOCK(hhash);\r
+        \r
+        return HAL_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+  \r
+  /* Read the message digest */\r
+  HASHEx_GetDigest(pOutBuffer, 28);\r
+      \r
+  /* Change HASH peripheral state */\r
+  hhash->State = HAL_HASH_STATE_READY;\r
+  \r
+   /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in SHA256 mode then enables DMA to\r
+            control data transfer. Use HAL_HASH_SHA256_Finish() to get the digest.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).\r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)\r
+{\r
+  uint32_t inputaddr  = (uint32_t)pInBuffer;\r
+  \r
+   /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Check if initialization phase has already been performed */\r
+  if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+  {\r
+    /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute \r
+       the message digest of a new message */\r
+    HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;\r
+  }\r
+  \r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(Size);\r
+  \r
+  /* Set the phase */\r
+  hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+    \r
+  /* Set the HASH DMA transfer complete callback */\r
+  hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;\r
+  /* Set the DMA error callback */\r
+  hhash->hdmain->XferErrorCallback = HASHEx_DMAError;\r
+  \r
+  /* Enable the DMA In DMA Stream */\r
+  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));\r
+  \r
+  /* Enable DMA requests */\r
+  HASH->CR |= (HASH_CR_DMAE);\r
+  \r
+   /* Process UnLock */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+/**\r
+  * @brief  Returns the computed digest in SHA256.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.\r
+  * @param  Timeout: Timeout value    \r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HASHEx_SHA256_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)\r
+{\r
+  uint32_t tickstart = 0;   \r
+  \r
+   /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change HASH peripheral state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Get tick */\r
+  tickstart = HAL_GetTick();\r
+  \r
+  while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))\r
+  {\r
+    /* Check for the Timeout */\r
+    if(Timeout != HAL_MAX_DELAY)\r
+    {\r
+      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))\r
+      {\r
+        /* Change state */\r
+        hhash->State = HAL_HASH_STATE_TIMEOUT;\r
+        \r
+        /* Process Unlocked */          \r
+        __HAL_UNLOCK(hhash);\r
+        \r
+        return HAL_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+  \r
+  /* Read the message digest */\r
+  HASHEx_GetDigest(pOutBuffer, 32);\r
+  \r
+  /* Change HASH peripheral state */\r
+  hhash->State = HAL_HASH_STATE_READY;\r
+  \r
+   /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+\r
+/**\r
+  * @}\r
+  */\r
+/** @defgroup HASHEx_Group5 HMAC processing functions using DMA mode \r
+ *  @brief   HMAC processing functions using DMA mode . \r
+ *\r
+@verbatim   \r
+ ===============================================================================\r
+                ##### HMAC processing using DMA functions #####\r
+ ===============================================================================  \r
+    [..]  This section provides functions allowing to calculate in DMA mode\r
+          the HMAC value using one of the following algorithms:\r
+      (+) SHA224\r
+      (+) SHA256\r
+\r
+@endverbatim\r
+  * @{\r
+  */\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in HMAC SHA224 mode\r
+  *         then enables DMA to control data transfer.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).\r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HMACEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)\r
+{\r
+  uint32_t inputaddr;\r
+  \r
+  /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Save buffer pointer and size in handle */\r
+  hhash->pHashInBuffPtr = pInBuffer;\r
+  hhash->HashBuffSize = Size;\r
+  hhash->HashInCount = 0;\r
+  \r
+  /* Check if initialization phase has already been performed */\r
+  if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+  {\r
+    /* Check if key size is greater than 64 bytes */\r
+    if(hhash->Init.KeySize > 64)\r
+    {\r
+      /* Select the HMAC SHA224 mode */\r
+      HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);\r
+    }\r
+    else\r
+    {\r
+      /* Select the HMAC SHA224 mode */\r
+      HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);\r
+    }\r
+  }\r
+  \r
+  /* Set the phase */\r
+  hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+  \r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);\r
+  \r
+  /* Get the key address */\r
+  inputaddr = (uint32_t)(hhash->Init.pKey);\r
+  \r
+  /* Set the HASH DMA transfer complete callback */\r
+  hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;\r
+  /* Set the DMA error callback */\r
+  hhash->hdmain->XferErrorCallback = HASHEx_DMAError;\r
+  \r
+  /* Enable the DMA In DMA Stream */\r
+  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));\r
+  /* Enable DMA requests */\r
+  HASH->CR |= (HASH_CR_DMAE);\r
+  \r
+  /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+/**\r
+  * @brief  Initializes the HASH peripheral in HMAC SHA256 mode\r
+  *         then enables DMA to control data transfer.\r
+  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains\r
+  *         the configuration information for HASH module\r
+  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).\r
+  * @param  Size: Length of the input buffer in bytes.\r
+  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.\r
+  * @retval HAL status\r
+  */\r
+HAL_StatusTypeDef HAL_HMACEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)\r
+{\r
+  uint32_t inputaddr;\r
+  \r
+  /* Process Locked */\r
+  __HAL_LOCK(hhash);\r
+  \r
+  /* Change the HASH state */\r
+  hhash->State = HAL_HASH_STATE_BUSY;\r
+  \r
+  /* Save buffer pointer and size in handle */\r
+  hhash->pHashInBuffPtr = pInBuffer;\r
+  hhash->HashBuffSize = Size;\r
+  hhash->HashInCount = 0;\r
+  \r
+  /* Check if initialization phase has already been performed */\r
+  if(hhash->Phase == HAL_HASH_PHASE_READY)\r
+  {\r
+    /* Check if key size is greater than 64 bytes */\r
+    if(hhash->Init.KeySize > 64)\r
+    {\r
+      /* Select the HMAC SHA256 mode */\r
+      HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY);\r
+    }\r
+    else\r
+    {\r
+      /* Select the HMAC SHA256 mode */\r
+      HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC);\r
+    }\r
+    /* Reset the HASH processor core, so that the HASH will be ready to compute \r
+       the message digest of a new message */\r
+    HASH->CR |= HASH_CR_INIT;\r
+  }\r
+  \r
+  /* Set the phase */\r
+  hhash->Phase = HAL_HASH_PHASE_PROCESS;\r
+  \r
+  /* Configure the number of valid bits in last word of the message */\r
+  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);\r
+  \r
+  /* Get the key address */\r
+  inputaddr = (uint32_t)(hhash->Init.pKey);\r
+  \r
+  /* Set the HASH DMA transfer complete callback */\r
+  hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;\r
+  /* Set the DMA error callback */\r
+  hhash->hdmain->XferErrorCallback = HASHEx_DMAError;\r
+  \r
+  /* Enable the DMA In DMA Stream */\r
+  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));\r
+  /* Enable DMA requests */\r
+  HASH->CR |= (HASH_CR_DMAE);\r
+  \r
+  /* Process Unlocked */\r
+  __HAL_UNLOCK(hhash);\r
+  \r
+  /* Return function status */\r
+  return HAL_OK;\r
+}\r
+\r
+/**\r
+  * @}\r
+  */\r
+\r
+/**\r
+  * @}\r
+  */\r
+#endif /* STM32F756xx */\r
+\r
+#endif /* HAL_HASH_MODULE_ENABLED */\r
+/**\r
+  * @}\r
+  */\r
+\r
+/**\r
+  * @}\r
+  */\r
+\r
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r