--- /dev/null
+/**\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>© 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