STM32F439xx HAL User Manual
stm32f4xx_hal_hash.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_hash.c
00004   * @author  MCD Application Team
00005   * @brief   HASH HAL module driver.
00006   *          This file provides firmware functions to manage the following 
00007   *          functionalities of the HASH peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + HASH/HMAC Processing functions by algorithm using polling mode
00010   *           + HASH/HMAC functions by algorithm using interrupt mode
00011   *           + HASH/HMAC functions by algorithm using DMA mode
00012   *           + Peripheral State functions
00013   *         
00014   @verbatim
00015   ==============================================================================
00016                      ##### How to use this driver #####
00017   ==============================================================================
00018     [..]
00019     The HASH HAL driver can be used as follows:
00020     (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
00021         (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
00022         (##) In case of using processing APIs based on interrupts (e.g. HAL_HMAC_SHA1_Start_IT())
00023             (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
00024             (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
00025             (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
00026         (##) In case of using DMA to control data transfer (e.g. HAL_HMAC_SHA1_Start_DMA())
00027             (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
00028             (+++) Configure and enable one DMA stream one for managing data transfer from
00029                 memory to peripheral (input stream). Managing data transfer from
00030                 peripheral to memory can be performed only using CPU
00031             (+++) Associate the initialized DMA handle to the HASH DMA handle
00032                 using  __HAL_LINKDMA()
00033             (+++) Configure the priority and enable the NVIC for the transfer complete
00034                 interrupt on the DMA Stream using HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
00035     (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
00036         (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
00037         (##) For HMAC, the encryption key.
00038         (##) For HMAC, the key size used for encryption.
00039     (#)Three processing functions are available:
00040         (##) Polling mode: processing APIs are blocking functions
00041              i.e. they process the data and wait till the digest computation is finished
00042              e.g. HAL_HASH_SHA1_Start()
00043         (##) Interrupt mode: encryption and decryption APIs are not blocking functions
00044                 i.e. they process the data under interrupt
00045                 e.g. HAL_HASH_SHA1_Start_IT()
00046         (##) DMA mode: processing APIs are not blocking functions and the CPU is
00047              not used for data transfer i.e. the data transfer is ensured by DMA
00048                 e.g. HAL_HASH_SHA1_Start_DMA()
00049     (#)When the processing function is called at first time after HAL_HASH_Init()
00050        the HASH peripheral is initialized and processes the buffer in input.
00051        After that, the digest computation is started.
00052        When processing multi-buffer use the accumulate function to write the
00053        data in the peripheral without starting the digest computation. In last 
00054        buffer use the start function to input the last buffer ans start the digest
00055        computation.
00056        (##) e.g. HAL_HASH_SHA1_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
00057        (##) write (n-1)th data buffer in the peripheral without starting the digest computation
00058        (##) HAL_HASH_SHA1_Start() : write (n)th data buffer in the peripheral and start the digest computation
00059     (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
00060     (#)In case of using DMA, call the DMA start processing e.g. HAL_HASH_SHA1_Start_DMA().
00061        After that, call the finish function in order to get the digest value
00062        e.g. HAL_HASH_SHA1_Finish()
00063     (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.
00064 
00065   @endverbatim
00066   ******************************************************************************
00067   * @attention
00068   *
00069   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00070   *
00071   * Redistribution and use in source and binary forms, with or without modification,
00072   * are permitted provided that the following conditions are met:
00073   *   1. Redistributions of source code must retain the above copyright notice,
00074   *      this list of conditions and the following disclaimer.
00075   *   2. Redistributions in binary form must reproduce the above copyright notice,
00076   *      this list of conditions and the following disclaimer in the documentation
00077   *      and/or other materials provided with the distribution.
00078   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00079   *      may be used to endorse or promote products derived from this software
00080   *      without specific prior written permission.
00081   *
00082   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00083   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00084   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00085   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00086   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00087   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00088   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00089   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00090   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00091   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00092   *
00093   ******************************************************************************
00094   */ 
00095 
00096 /* Includes ------------------------------------------------------------------*/
00097 #include "stm32f4xx_hal.h"
00098 
00099 /** @addtogroup STM32F4xx_HAL_Driver
00100   * @{
00101   */
00102 
00103 /** @defgroup HASH HASH
00104   * @brief HASH HAL module driver.
00105   * @{
00106   */
00107 
00108 #ifdef HAL_HASH_MODULE_ENABLED
00109 
00110 #if defined(STM32F415xx) || defined(STM32F417xx) || defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F479xx)
00111 
00112 /* Private typedef -----------------------------------------------------------*/
00113 /* Private define ------------------------------------------------------------*/
00114 /* Private macro -------------------------------------------------------------*/
00115 /* Private variables ---------------------------------------------------------*/
00116 /* Private function prototypes -----------------------------------------------*/
00117 /** @defgroup HASH_Private_Functions HASH Private Functions
00118   * @{
00119   */
00120 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
00121 static void HASH_DMAError(DMA_HandleTypeDef *hdma);
00122 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
00123 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size);
00124 /**
00125   * @}
00126   */
00127   
00128 /* Private functions ---------------------------------------------------------*/
00129 /** @addtogroup HASH_Private_Functions
00130   * @{
00131   */
00132 
00133 /**
00134   * @brief  DMA HASH Input Data complete callback. 
00135   * @param  hdma DMA handle
00136   * @retval None
00137   */
00138 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
00139 {
00140   HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
00141   uint32_t inputaddr = 0U;
00142   uint32_t buffersize = 0U;
00143   
00144   if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
00145   {
00146     /* Disable the DMA transfer */
00147     HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
00148     
00149     /* Change HASH peripheral state */
00150     hhash->State = HAL_HASH_STATE_READY;
00151     
00152     /* Call Input data transfer complete callback */
00153     HAL_HASH_InCpltCallback(hhash);
00154   }
00155   else
00156   {
00157     /* Increment Interrupt counter */
00158     hhash->HashInCount++;
00159     /* Disable the DMA transfer before starting the next transfer */
00160     HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
00161     
00162     if(hhash->HashInCount <= 2U)
00163     {
00164       /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
00165       if(hhash->HashInCount == 1U)
00166       {
00167         inputaddr = (uint32_t)hhash->pHashInBuffPtr;
00168         buffersize = hhash->HashBuffSize;
00169       }
00170       /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
00171       else if(hhash->HashInCount == 2U)
00172       {
00173         inputaddr = (uint32_t)hhash->Init.pKey;
00174         buffersize = hhash->Init.KeySize;
00175       }
00176       /* Configure the number of valid bits in last word of the message */
00177       MODIFY_REG(HASH->STR, HASH_STR_NBLW, 8U * (buffersize % 4U));
00178             
00179       /* Set the HASH DMA transfer complete */
00180       hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
00181       
00182       /* Enable the DMA In DMA Stream */
00183       HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4U ? (buffersize+3U)/4U:buffersize/4U));
00184       
00185       /* Enable DMA requests */
00186       HASH->CR |= (HASH_CR_DMAE);
00187     }
00188     else
00189     {
00190       /* Disable the DMA transfer */
00191       HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
00192       
00193       /* Reset the InCount */
00194       hhash->HashInCount = 0U;
00195       
00196       /* Change HASH peripheral state */
00197       hhash->State = HAL_HASH_STATE_READY;
00198       
00199       /* Call Input data transfer complete callback */
00200       HAL_HASH_InCpltCallback(hhash);
00201     }
00202   }
00203 }
00204 
00205 /**
00206   * @brief  DMA HASH communication error callback. 
00207   * @param  hdma DMA handle
00208   * @retval None
00209   */
00210 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
00211 {
00212   HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
00213   hhash->State= HAL_HASH_STATE_READY;
00214   HAL_HASH_ErrorCallback(hhash);
00215 }
00216 
00217 /**
00218   * @brief  Writes the input buffer in data register.
00219   * @param  pInBuffer Pointer to input buffer
00220   * @param  Size The size of input buffer
00221   * @retval None
00222   */
00223 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size)
00224 {
00225   uint32_t buffercounter;
00226   uint32_t inputaddr = (uint32_t) pInBuffer;
00227   
00228   for(buffercounter = 0U; buffercounter < Size; buffercounter+=4)
00229   {
00230     HASH->DIN = *(uint32_t*)inputaddr;
00231     inputaddr+=4U;
00232   }
00233 }
00234 
00235 /**
00236   * @brief  Provides the message digest result.
00237   * @param  pMsgDigest Pointer to the message digest
00238   * @param  Size The size of the message digest in bytes
00239   * @retval None
00240   */
00241 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
00242 {
00243   uint32_t msgdigest = (uint32_t)pMsgDigest;
00244   
00245   switch(Size)
00246   {
00247   case 16U:
00248     /* Read the message digest */
00249     *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
00250     msgdigest+=4U;
00251     *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
00252     msgdigest+=4U;
00253     *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
00254     msgdigest+=4U;
00255     *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
00256     break;
00257   case 20U:
00258     /* Read the message digest */
00259     *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
00260     msgdigest+=4U;
00261     *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
00262     msgdigest+=4U;
00263     *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
00264     msgdigest+=4U;
00265     *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
00266     msgdigest+=4U;
00267     *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
00268     break;
00269   case 28U:
00270     /* Read the message digest */
00271     *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
00272     msgdigest+=4U;
00273     *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
00274     msgdigest+=4U;
00275     *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
00276     msgdigest+=4U;
00277     *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
00278     msgdigest+=4U;
00279     *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
00280     msgdigest+=4U;
00281     *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5U]);
00282     msgdigest+=4U;
00283     *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6U]);
00284     break;
00285   case 32U:
00286     /* Read the message digest */
00287     *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
00288     msgdigest+=4U;
00289     *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
00290     msgdigest+=4U;
00291     *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
00292     msgdigest+=4U;
00293     *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
00294     msgdigest+=4U;
00295     *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
00296     msgdigest+=4U;
00297     *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5U]);
00298     msgdigest+=4U;
00299     *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6U]);
00300     msgdigest+=4U;
00301     *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7U]);
00302     break;
00303   default:
00304     break;
00305   }
00306 }
00307 
00308 /**
00309   * @}
00310   */
00311 
00312 /* Exported functions --------------------------------------------------------*/
00313 /** @addtogroup HASH_Exported_Functions
00314   * @{
00315   */
00316   
00317 
00318 /** @addtogroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions 
00319  *  @brief    Initialization and Configuration functions. 
00320  *
00321 @verbatim    
00322  ===============================================================================
00323               ##### Initialization and de-initialization functions #####
00324  ===============================================================================
00325     [..]  This section provides functions allowing to:
00326       (+) Initialize the HASH according to the specified parameters 
00327           in the HASH_InitTypeDef and creates the associated handle.
00328       (+) DeInitialize the HASH peripheral.
00329       (+) Initialize the HASH MSP.
00330       (+) DeInitialize HASH MSP. 
00331  
00332 @endverbatim
00333   * @{
00334   */
00335 
00336 /**
00337   * @brief  Initializes the HASH according to the specified parameters in the
00338             HASH_HandleTypeDef and creates the associated handle.
00339   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00340   *         the configuration information for HASH module
00341   * @retval HAL status
00342   */
00343 HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
00344 {
00345   /* Check the hash handle allocation */
00346   if(hhash == NULL)
00347   {
00348     return HAL_ERROR;
00349   }
00350 
00351   /* Check the parameters */
00352   assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
00353    
00354   if(hhash->State == HAL_HASH_STATE_RESET)
00355   {
00356     /* Allocate lock resource and initialize it */
00357     hhash->Lock = HAL_UNLOCKED;
00358     /* Init the low level hardware */
00359     HAL_HASH_MspInit(hhash);
00360   }
00361   
00362   /* Change the HASH state */
00363   hhash->State = HAL_HASH_STATE_BUSY;
00364   
00365   /* Reset HashInCount, HashBuffSize and HashITCounter */
00366   hhash->HashInCount = 0U;
00367   hhash->HashBuffSize = 0U;
00368   hhash->HashITCounter = 0U;
00369   
00370   /* Set the data type */
00371   HASH->CR |= (uint32_t) (hhash->Init.DataType);
00372   
00373   /* Change the HASH state */
00374   hhash->State = HAL_HASH_STATE_READY;
00375   
00376   /* Set the default HASH phase */
00377   hhash->Phase = HAL_HASH_PHASE_READY;
00378   
00379   /* Return function status */
00380   return HAL_OK;
00381 }
00382 
00383 /**
00384   * @brief  DeInitializes the HASH peripheral.
00385   * @note   This API must be called before starting a new processing. 
00386   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00387   *         the configuration information for HASH module
00388   * @retval HAL status
00389   */
00390 HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
00391 { 
00392   /* Check the HASH handle allocation */
00393   if(hhash == NULL)
00394   {
00395     return HAL_ERROR;
00396   }
00397   
00398   /* Change the HASH state */
00399   hhash->State = HAL_HASH_STATE_BUSY;
00400   
00401   /* Set the default HASH phase */
00402   hhash->Phase = HAL_HASH_PHASE_READY;
00403   
00404   /* Reset HashInCount, HashBuffSize and HashITCounter */
00405   hhash->HashInCount = 0U;
00406   hhash->HashBuffSize = 0U;
00407   hhash->HashITCounter = 0U;
00408   
00409   /* DeInit the low level hardware */
00410   HAL_HASH_MspDeInit(hhash);
00411   
00412   /* Change the HASH state */
00413   hhash->State = HAL_HASH_STATE_RESET;  
00414 
00415   /* Release Lock */
00416   __HAL_UNLOCK(hhash);
00417 
00418   /* Return function status */
00419   return HAL_OK;
00420 }
00421 
00422 /**
00423   * @brief  Initializes the HASH MSP.
00424   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00425   *         the configuration information for HASH module
00426   * @retval None
00427   */
00428 __weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
00429 {
00430   /* Prevent unused argument(s) compilation warning */
00431   UNUSED(hhash);
00432   /* NOTE: This function Should not be modified, when the callback is needed,
00433            the HAL_HASH_MspInit could be implemented in the user file
00434    */
00435 }
00436 
00437 /**
00438   * @brief  DeInitializes HASH MSP.
00439   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00440   *         the configuration information for HASH module
00441   * @retval None
00442   */
00443 __weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
00444 {
00445   /* Prevent unused argument(s) compilation warning */
00446   UNUSED(hhash);
00447   /* NOTE: This function Should not be modified, when the callback is needed,
00448            the HAL_HASH_MspDeInit could be implemented in the user file
00449    */
00450 }
00451 
00452 /**
00453   * @brief  Input data transfer complete callback.
00454   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00455   *         the configuration information for HASH module
00456   * @retval None
00457   */
00458  __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
00459 {
00460   /* Prevent unused argument(s) compilation warning */
00461   UNUSED(hhash);
00462   /* NOTE: This function Should not be modified, when the callback is needed,
00463            the HAL_HASH_InCpltCallback could be implemented in the user file
00464    */ 
00465 }
00466 
00467 /**
00468   * @brief  Data transfer Error callback.
00469   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00470   *         the configuration information for HASH module
00471   * @retval None
00472   */
00473  __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
00474 {
00475   /* Prevent unused argument(s) compilation warning */
00476   UNUSED(hhash);
00477   /* NOTE: This function Should not be modified, when the callback is needed,
00478            the HAL_HASH_ErrorCallback could be implemented in the user file
00479    */ 
00480 }
00481 
00482 /**
00483   * @brief  Digest computation complete callback. It is used only with interrupt.
00484   * @note   This callback is not relevant with DMA.
00485   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00486   *         the configuration information for HASH module
00487   * @retval None
00488   */
00489  __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
00490 {
00491   /* Prevent unused argument(s) compilation warning */
00492   UNUSED(hhash);
00493   /* NOTE: This function Should not be modified, when the callback is needed,
00494            the HAL_HASH_DgstCpltCallback could be implemented in the user file
00495    */ 
00496 }
00497 
00498 /**
00499   * @}
00500   */
00501 
00502 /** @defgroup HASH_Exported_Functions_Group2 HASH processing functions using polling mode 
00503  *  @brief   processing functions using polling mode 
00504  *
00505 @verbatim   
00506  ===============================================================================
00507               ##### HASH processing using polling mode functions#####
00508  ===============================================================================  
00509     [..]  This section provides functions allowing to calculate in polling mode
00510           the hash value using one of the following algorithms:
00511       (+) MD5
00512       (+) SHA1
00513 
00514 @endverbatim
00515   * @{
00516   */
00517 
00518 /**
00519   * @brief  Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
00520             The digest is available in pOutBuffer.
00521   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00522   *         the configuration information for HASH module
00523   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).
00524   * @param  Size Length of the input buffer in bytes.
00525   *          If the Size is multiple of 64 bytes, appending the input buffer is possible.
00526   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware
00527   *          and appending the input buffer is no more possible.
00528   * @param  pOutBuffer Pointer to the computed digest. Its size must be 16 bytes.
00529   * @param  Timeout Timeout value
00530   * @retval HAL status
00531   */
00532 HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
00533 {
00534   uint32_t tickstart = 0U;
00535   
00536   /* Process Locked */
00537   __HAL_LOCK(hhash);
00538   
00539   /* Change the HASH state */
00540   hhash->State = HAL_HASH_STATE_BUSY;
00541   
00542   /* Check if initialization phase has already been performed */
00543   if(hhash->Phase == HAL_HASH_PHASE_READY)
00544   {
00545     /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute 
00546        the message digest of a new message */
00547     HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
00548   }
00549   
00550   /* Set the phase */
00551   hhash->Phase = HAL_HASH_PHASE_PROCESS;
00552   
00553   /* Configure the number of valid bits in last word of the message */
00554   __HAL_HASH_SET_NBVALIDBITS(Size);
00555   
00556   /* Write input buffer in data register */
00557   HASH_WriteData(pInBuffer, Size);
00558   
00559   /* Start the digest calculation */
00560   __HAL_HASH_START_DIGEST();
00561   
00562   /* Get tick */
00563   tickstart = HAL_GetTick();
00564   
00565   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
00566   {
00567     /* Check for the Timeout */
00568     if(Timeout != HAL_MAX_DELAY)
00569     {
00570       if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00571       {
00572         /* Change state */
00573         hhash->State = HAL_HASH_STATE_TIMEOUT;
00574         
00575         /* Process Unlocked */
00576         __HAL_UNLOCK(hhash);
00577         
00578         return HAL_TIMEOUT;
00579       }
00580     }
00581   }
00582   
00583   /* Read the message digest */
00584   HASH_GetDigest(pOutBuffer, 16U);
00585   
00586   /* Change the HASH state */
00587   hhash->State = HAL_HASH_STATE_READY;
00588    
00589   /* Process Unlocked */
00590   __HAL_UNLOCK(hhash);
00591   
00592   /* Return function status */
00593   return HAL_OK;
00594 }
00595 
00596 /**
00597   * @brief  Initializes the HASH peripheral in MD5 mode then writes the pInBuffer.
00598   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00599   *         the configuration information for HASH module
00600   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).
00601   * @param  Size Length of the input buffer in bytes.
00602   *          If the Size is multiple of 64 bytes, appending the input buffer is possible.
00603   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware
00604   *          and appending the input buffer is no more possible.
00605   * @retval HAL status
00606   */
00607 HAL_StatusTypeDef HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
00608 {  
00609   /* Process Locked */
00610   __HAL_LOCK(hhash);
00611   
00612   /* Change the HASH state */
00613   hhash->State = HAL_HASH_STATE_BUSY;
00614   
00615   /* Check if initialization phase has already been performed */
00616   if(hhash->Phase == HAL_HASH_PHASE_READY)
00617   {
00618     /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute 
00619        the message digest of a new message */
00620     HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
00621   }
00622   
00623   /* Set the phase */
00624   hhash->Phase = HAL_HASH_PHASE_PROCESS;
00625   
00626   /* Configure the number of valid bits in last word of the message */
00627   __HAL_HASH_SET_NBVALIDBITS(Size);
00628   
00629   /* Write input buffer in data register */
00630   HASH_WriteData(pInBuffer, Size);
00631   
00632   /* Change the HASH state */
00633   hhash->State = HAL_HASH_STATE_READY;
00634   
00635   /* Process Unlocked */
00636   __HAL_UNLOCK(hhash);
00637   
00638   /* Return function status */
00639   return HAL_OK;
00640 }
00641 
00642 /**
00643   * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
00644             The digest is available in pOutBuffer.
00645   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00646   *         the configuration information for HASH module
00647   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).  
00648   * @param  Size Length of the input buffer in bytes.
00649   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
00650   * @param  pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
00651   * @param  Timeout Timeout value  
00652   * @retval HAL status
00653   */
00654 HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
00655 {
00656   uint32_t tickstart = 0U;   
00657 
00658   /* Process Locked */
00659   __HAL_LOCK(hhash);
00660   
00661   /* Change the HASH state */
00662   hhash->State = HAL_HASH_STATE_BUSY;
00663   
00664   /* Check if initialization phase has already been performed */
00665   if(hhash->Phase == HAL_HASH_PHASE_READY)
00666   {
00667     /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute 
00668        the message digest of a new message */
00669     HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
00670   }
00671   
00672   /* Set the phase */
00673   hhash->Phase = HAL_HASH_PHASE_PROCESS;
00674   
00675   /* Configure the number of valid bits in last word of the message */
00676   __HAL_HASH_SET_NBVALIDBITS(Size);
00677   
00678   /* Write input buffer in data register */
00679   HASH_WriteData(pInBuffer, Size);
00680   
00681   /* Start the digest calculation */
00682   __HAL_HASH_START_DIGEST();
00683   
00684   /* Get tick */
00685   tickstart = HAL_GetTick();
00686 
00687   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
00688     {
00689       /* Check for the Timeout */
00690       if(Timeout != HAL_MAX_DELAY)
00691       {
00692         if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00693         {
00694           /* Change state */
00695           hhash->State = HAL_HASH_STATE_TIMEOUT;
00696           
00697           /* Process Unlocked */
00698           __HAL_UNLOCK(hhash);
00699           
00700           return HAL_TIMEOUT;
00701         }
00702       }
00703     }
00704   
00705   /* Read the message digest */
00706   HASH_GetDigest(pOutBuffer, 20U);
00707   
00708   /* Change the HASH state */
00709   hhash->State = HAL_HASH_STATE_READY;
00710   
00711   /* Process Unlocked */
00712   __HAL_UNLOCK(hhash);
00713   
00714   /* Return function status */
00715   return HAL_OK;
00716 }
00717 
00718 /**
00719   * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
00720   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00721   *         the configuration information for HASH module
00722   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).
00723   * @param  Size Length of the input buffer in bytes.
00724   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
00725   * @note  Input buffer size in bytes must be a multiple of 4 otherwise the digest computation is corrupted.
00726   * @retval HAL status
00727   */
00728 HAL_StatusTypeDef HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
00729 {
00730   /* Check the parameters */
00731   assert_param(IS_HASH_SHA1_BUFFER_SIZE(Size));
00732 
00733   /* Process Locked */
00734   __HAL_LOCK(hhash);
00735   
00736   /* Change the HASH state */
00737   hhash->State = HAL_HASH_STATE_BUSY;
00738   
00739   /* Check if initialization phase has already been performed */
00740   if(hhash->Phase == HAL_HASH_PHASE_READY)
00741   {
00742     /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute 
00743        the message digest of a new message */
00744     HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
00745   }
00746   
00747   /* Set the phase */
00748   hhash->Phase = HAL_HASH_PHASE_PROCESS;
00749   
00750   /* Configure the number of valid bits in last word of the message */
00751   __HAL_HASH_SET_NBVALIDBITS(Size);
00752   
00753   /* Write input buffer in data register */
00754   HASH_WriteData(pInBuffer, Size);
00755   
00756   /* Change the HASH state */
00757   hhash->State = HAL_HASH_STATE_READY;
00758   
00759   /* Process Unlocked */
00760   __HAL_UNLOCK(hhash);
00761   
00762   /* Return function status */
00763   return HAL_OK;
00764 }
00765 
00766 /**
00767   * @}
00768   */
00769 
00770 /** @defgroup HASH_Exported_Functions_Group3 HASH processing functions using interrupt mode
00771  *  @brief   processing functions using interrupt mode. 
00772  *
00773 @verbatim   
00774  ===============================================================================
00775               ##### HASH processing using interrupt mode functions #####
00776  ===============================================================================  
00777     [..]  This section provides functions allowing to calculate in interrupt mode
00778           the hash value using one of the following algorithms:
00779       (+) MD5
00780       (+) SHA1
00781 
00782 @endverbatim
00783   * @{
00784   */
00785 
00786 /**
00787   * @brief  Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
00788   *         The digest is available in pOutBuffer.
00789   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00790   *         the configuration information for HASH module
00791   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).   
00792   * @param  Size Length of the input buffer in bytes.
00793   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
00794   * @param  pOutBuffer Pointer to the computed digest. Its size must be 16 bytes.
00795   * @retval HAL status
00796   */
00797 HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
00798 {
00799   uint32_t inputaddr;
00800   uint32_t outputaddr;
00801   uint32_t buffercounter;
00802   uint32_t inputcounter;
00803   
00804   /* Process Locked */
00805   __HAL_LOCK(hhash);
00806   
00807   if(hhash->State == HAL_HASH_STATE_READY)
00808   {
00809     /* Change the HASH state */
00810     hhash->State = HAL_HASH_STATE_BUSY;
00811     
00812     hhash->HashInCount = Size;
00813     hhash->pHashInBuffPtr = pInBuffer;
00814     hhash->pHashOutBuffPtr = pOutBuffer;
00815     
00816     /* Check if initialization phase has already been performed */
00817     if(hhash->Phase == HAL_HASH_PHASE_READY)
00818     {
00819       /* Select the SHA1 mode */
00820       HASH->CR |= HASH_ALGOSELECTION_MD5;
00821       /* Reset the HASH processor core, so that the HASH will be ready to compute 
00822          the message digest of a new message */
00823       HASH->CR |= HASH_CR_INIT;
00824     }
00825     /* Reset interrupt counter */
00826     hhash->HashITCounter = 0U;
00827     
00828     /* Set the phase */
00829     hhash->Phase = HAL_HASH_PHASE_PROCESS;
00830     
00831     /* Process Unlocked */
00832     __HAL_UNLOCK(hhash);
00833     
00834     /* Enable Interrupts */
00835     HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
00836     
00837     /* Return function status */
00838     return HAL_OK;
00839   }
00840   if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
00841   {
00842     outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
00843     /* Read the Output block from the Output FIFO */
00844     *(uint32_t*)(outputaddr) = __REV(HASH->HR[0U]);
00845     outputaddr+=4U;
00846     *(uint32_t*)(outputaddr) = __REV(HASH->HR[1U]);
00847     outputaddr+=4U;
00848     *(uint32_t*)(outputaddr) = __REV(HASH->HR[2U]);
00849     outputaddr+=4U;
00850     *(uint32_t*)(outputaddr) = __REV(HASH->HR[3U]);
00851     
00852     if(hhash->HashInCount == 0U)
00853     {
00854       /* Disable Interrupts */
00855       HASH->IMR = 0U;
00856       /* Change the HASH state */
00857       hhash->State = HAL_HASH_STATE_READY;
00858       /* Call digest computation complete callback */
00859       HAL_HASH_DgstCpltCallback(hhash);
00860       
00861       /* Process Unlocked */
00862       __HAL_UNLOCK(hhash);
00863       
00864       /* Return function status */
00865       return HAL_OK;
00866     }
00867   }
00868   if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
00869   {
00870     if(hhash->HashInCount >= 68U)
00871     {
00872       inputaddr = (uint32_t)hhash->pHashInBuffPtr;
00873       /* Write the Input block in the Data IN register */
00874       for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U)
00875       {
00876         HASH->DIN = *(uint32_t*)inputaddr;
00877         inputaddr+=4U;
00878       }
00879       if(hhash->HashITCounter == 0U)
00880       {
00881         HASH->DIN = *(uint32_t*)inputaddr;
00882 
00883         if(hhash->HashInCount >= 68U)
00884         {
00885           /* Decrement buffer counter */
00886           hhash->HashInCount -= 68U;
00887           hhash->pHashInBuffPtr+= 68U;
00888         }
00889         else
00890         {
00891           hhash->HashInCount = 0U;
00892           hhash->pHashInBuffPtr+= hhash->HashInCount;
00893         }
00894         /* Set Interrupt counter */
00895         hhash->HashITCounter = 1U;
00896       }
00897       else
00898       {
00899         /* Decrement buffer counter */
00900         hhash->HashInCount -= 64U;
00901         hhash->pHashInBuffPtr+= 64U;
00902       }
00903     }
00904     else
00905     {
00906       /* Get the buffer address */
00907       inputaddr = (uint32_t)hhash->pHashInBuffPtr;
00908       /* Get the buffer counter */
00909       inputcounter = hhash->HashInCount;
00910       /* Disable Interrupts */
00911       HASH->IMR &= ~(HASH_IT_DINI);
00912       /* Configure the number of valid bits in last word of the message */
00913       __HAL_HASH_SET_NBVALIDBITS(inputcounter);
00914       
00915       if((inputcounter > 4U) && (inputcounter%4U))
00916       {
00917         inputcounter = (inputcounter+4U-inputcounter%4U);
00918       }
00919       else if ((inputcounter < 4U) && (inputcounter != 0U))
00920       {
00921         inputcounter = 4U;
00922       }
00923       /* Write the Input block in the Data IN register */
00924       for(buffercounter = 0U; buffercounter < inputcounter/4U; buffercounter++)
00925       {
00926         HASH->DIN = *(uint32_t*)inputaddr;
00927         inputaddr+=4U;
00928       }
00929       /* Start the digest calculation */
00930       __HAL_HASH_START_DIGEST();
00931       /* Reset buffer counter */
00932       hhash->HashInCount = 0U;
00933       /* Call Input data transfer complete callback */
00934       HAL_HASH_InCpltCallback(hhash);
00935     }
00936   }
00937   
00938   /* Process Unlocked */
00939   __HAL_UNLOCK(hhash);
00940   
00941   /* Return function status */
00942   return HAL_OK;
00943 }
00944 
00945 /**
00946   * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
00947   *         The digest is available in pOutBuffer.
00948   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
00949   *         the configuration information for HASH module
00950   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed). 
00951   * @param  Size Length of the input buffer in bytes.
00952   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
00953   * @param  pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
00954   * @retval HAL status
00955   */
00956 HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
00957 {
00958   uint32_t inputaddr;
00959   uint32_t outputaddr;
00960   uint32_t buffercounter;
00961   uint32_t inputcounter;
00962   
00963   /* Process Locked */
00964   __HAL_LOCK(hhash);
00965   
00966   if(hhash->State == HAL_HASH_STATE_READY)
00967   {
00968     /* Change the HASH state */
00969     hhash->State = HAL_HASH_STATE_BUSY;
00970     
00971     hhash->HashInCount = Size;
00972     hhash->pHashInBuffPtr = pInBuffer;
00973     hhash->pHashOutBuffPtr = pOutBuffer;
00974     
00975     /* Check if initialization phase has already been performed */
00976     if(hhash->Phase == HAL_HASH_PHASE_READY)
00977     {
00978       /* Select the SHA1 mode */
00979       HASH->CR |= HASH_ALGOSELECTION_SHA1;
00980       /* Reset the HASH processor core, so that the HASH will be ready to compute 
00981          the message digest of a new message */
00982       HASH->CR |= HASH_CR_INIT;
00983     }
00984     /* Reset interrupt counter */
00985     hhash->HashITCounter = 0U;
00986     
00987     /* Set the phase */
00988     hhash->Phase = HAL_HASH_PHASE_PROCESS;
00989     
00990     /* Process Unlocked */
00991     __HAL_UNLOCK(hhash);
00992     
00993     /* Enable Interrupts */
00994     HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
00995     
00996     /* Return function status */
00997     return HAL_OK;
00998   }
00999   if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
01000   {
01001     outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
01002     /* Read the Output block from the Output FIFO */
01003     *(uint32_t*)(outputaddr) = __REV(HASH->HR[0U]);
01004     outputaddr+=4U;
01005     *(uint32_t*)(outputaddr) = __REV(HASH->HR[1U]);
01006     outputaddr+=4U;
01007     *(uint32_t*)(outputaddr) = __REV(HASH->HR[2U]);
01008     outputaddr+=4U;
01009     *(uint32_t*)(outputaddr) = __REV(HASH->HR[3U]);
01010     outputaddr+=4U;
01011     *(uint32_t*)(outputaddr) = __REV(HASH->HR[4U]);
01012     if(hhash->HashInCount == 0U)
01013     {
01014       /* Disable Interrupts */
01015       HASH->IMR = 0U;
01016       /* Change the HASH state */
01017       hhash->State = HAL_HASH_STATE_READY;
01018       /* Call digest computation complete callback */
01019       HAL_HASH_DgstCpltCallback(hhash);
01020       
01021       /* Process Unlocked */
01022       __HAL_UNLOCK(hhash);
01023       
01024       /* Return function status */
01025       return HAL_OK;
01026     }
01027   }
01028   if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
01029   {
01030     if(hhash->HashInCount >= 68U)
01031     {
01032       inputaddr = (uint32_t)hhash->pHashInBuffPtr;
01033       /* Write the Input block in the Data IN register */
01034       for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U)
01035       {
01036         HASH->DIN = *(uint32_t*)inputaddr;
01037         inputaddr+=4U;
01038       }
01039       if(hhash->HashITCounter == 0U)
01040       {
01041         HASH->DIN = *(uint32_t*)inputaddr;
01042         if(hhash->HashInCount >= 68U)
01043         {
01044           /* Decrement buffer counter */
01045           hhash->HashInCount -= 68U;
01046           hhash->pHashInBuffPtr+= 68U;
01047         }
01048         else
01049         {
01050           hhash->HashInCount = 0U;
01051           hhash->pHashInBuffPtr+= hhash->HashInCount;
01052         }
01053         /* Set Interrupt counter */
01054         hhash->HashITCounter = 1U;
01055       }
01056       else
01057       {
01058         /* Decrement buffer counter */
01059         hhash->HashInCount -= 64U;
01060         hhash->pHashInBuffPtr+= 64U;
01061       }
01062     }
01063     else
01064     {
01065       /* Get the buffer address */
01066       inputaddr = (uint32_t)hhash->pHashInBuffPtr;
01067       /* Get the buffer counter */
01068       inputcounter = hhash->HashInCount;
01069       /* Disable Interrupts */
01070       HASH->IMR &= ~(HASH_IT_DINI);
01071       /* Configure the number of valid bits in last word of the message */
01072       __HAL_HASH_SET_NBVALIDBITS(inputcounter);
01073       
01074       if((inputcounter > 4U) && (inputcounter%4U))
01075       {
01076         inputcounter = (inputcounter+4U-inputcounter%4U);
01077       }
01078       else if ((inputcounter < 4U) && (inputcounter != 0U))
01079       {
01080         inputcounter = 4U;
01081       }
01082       /* Write the Input block in the Data IN register */
01083       for(buffercounter = 0U; buffercounter < inputcounter/4U; buffercounter++)
01084       {
01085         HASH->DIN = *(uint32_t*)inputaddr;
01086         inputaddr+=4U;
01087       }
01088       /* Start the digest calculation */
01089       __HAL_HASH_START_DIGEST();
01090       /* Reset buffer counter */
01091       hhash->HashInCount = 0U;
01092       /* Call Input data transfer complete callback */
01093       HAL_HASH_InCpltCallback(hhash);
01094     }
01095   }
01096   
01097   /* Process Unlocked */
01098   __HAL_UNLOCK(hhash);
01099   
01100   /* Return function status */
01101   return HAL_OK;
01102 }
01103 
01104 /**
01105   * @brief This function handles HASH interrupt request.
01106   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
01107   *         the configuration information for HASH module
01108   * @retval None
01109   */
01110 void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
01111 {
01112   switch(HASH->CR & HASH_CR_ALGO)
01113   {
01114     case HASH_ALGOSELECTION_MD5:
01115        HAL_HASH_MD5_Start_IT(hhash, NULL, 0U, NULL);
01116     break;
01117     
01118     case HASH_ALGOSELECTION_SHA1:
01119       HAL_HASH_SHA1_Start_IT(hhash, NULL, 0U, NULL);
01120     break;
01121     
01122     default:
01123     break;
01124   }
01125 }
01126 
01127 /**
01128   * @}
01129   */
01130 
01131 /** @defgroup HASH_Exported_Functions_Group4 HASH processing functions using DMA mode
01132  *  @brief   processing functions using DMA mode. 
01133  *
01134 @verbatim   
01135  ===============================================================================
01136               ##### HASH processing using DMA mode functions #####
01137  ===============================================================================  
01138     [..]  This section provides functions allowing to calculate in DMA mode
01139           the hash value using one of the following algorithms:
01140       (+) MD5
01141       (+) SHA1
01142 
01143 @endverbatim
01144   * @{
01145   */
01146 
01147 /**
01148   * @brief  Initializes the HASH peripheral in MD5 mode then enables DMA to
01149             control data transfer. Use HAL_HASH_MD5_Finish() to get the digest.
01150   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
01151   *         the configuration information for HASH module
01152   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).
01153   * @param  Size Length of the input buffer in bytes.
01154   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
01155   * @retval HAL status
01156   */
01157 HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
01158 {
01159   uint32_t inputaddr  = (uint32_t)pInBuffer;
01160   
01161    /* Process Locked */
01162   __HAL_LOCK(hhash);
01163   
01164   /* Change the HASH state */
01165   hhash->State = HAL_HASH_STATE_BUSY;
01166   
01167   /* Check if initialization phase has already been performed */
01168   if(hhash->Phase == HAL_HASH_PHASE_READY)
01169   {
01170     /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute 
01171        the message digest of a new message */
01172     HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
01173   }
01174    
01175   /* Configure the number of valid bits in last word of the message */
01176   __HAL_HASH_SET_NBVALIDBITS(Size);
01177   
01178   /* Set the phase */
01179   hhash->Phase = HAL_HASH_PHASE_PROCESS;
01180     
01181   /* Set the HASH DMA transfer complete callback */
01182   hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
01183   /* Set the DMA error callback */
01184   hhash->hdmain->XferErrorCallback = HASH_DMAError;
01185   
01186   /* Enable the DMA In DMA Stream */
01187   HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4U ? (Size+3U)/4U:Size/4U));
01188   
01189   /* Enable DMA requests */
01190   HASH->CR |= (HASH_CR_DMAE);
01191   
01192    /* Process Unlocked */
01193   __HAL_UNLOCK(hhash);
01194   
01195   /* Return function status */
01196   return HAL_OK;
01197 }
01198 
01199 /**
01200   * @brief  Returns the computed digest in MD5 mode
01201   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
01202   *         the configuration information for HASH module
01203   * @param  pOutBuffer Pointer to the computed digest. Its size must be 16 bytes.
01204   * @param  Timeout Timeout value  
01205   * @retval HAL status
01206   */
01207 HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
01208 {
01209   uint32_t tickstart = 0U;   
01210   
01211    /* Process Locked */
01212   __HAL_LOCK(hhash);
01213   
01214   /* Change HASH peripheral state */
01215   hhash->State = HAL_HASH_STATE_BUSY;
01216   
01217   /* Get tick */
01218   tickstart = HAL_GetTick();
01219 
01220   while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
01221   {
01222     /* Check for the Timeout */
01223     if(Timeout != HAL_MAX_DELAY)
01224     {
01225       if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
01226       {
01227         /* Change state */
01228         hhash->State = HAL_HASH_STATE_TIMEOUT;
01229         
01230         /* Process Unlocked */
01231         __HAL_UNLOCK(hhash);
01232         
01233         return HAL_TIMEOUT;
01234       }
01235     }
01236   }
01237   
01238   /* Read the message digest */
01239   HASH_GetDigest(pOutBuffer, 16U);
01240       
01241   /* Change HASH peripheral state */
01242   hhash->State = HAL_HASH_STATE_READY;
01243   
01244    /* Process Unlocked */
01245   __HAL_UNLOCK(hhash);
01246   
01247   /* Return function status */
01248   return HAL_OK;
01249 }
01250 
01251 /**
01252   * @brief  Initializes the HASH peripheral in SHA1 mode then enables DMA to
01253             control data transfer. Use HAL_HASH_SHA1_Finish() to get the digest.
01254   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
01255   *         the configuration information for HASH module
01256   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).
01257   * @param  Size Length of the input buffer in bytes.
01258   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
01259   * @retval HAL status
01260   */
01261 HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
01262 {
01263   uint32_t inputaddr  = (uint32_t)pInBuffer;
01264   
01265    /* Process Locked */
01266   __HAL_LOCK(hhash);
01267   
01268   /* Change the HASH state */
01269   hhash->State = HAL_HASH_STATE_BUSY;
01270   
01271   /* Check if initialization phase has already been performed */
01272   if(hhash->Phase == HAL_HASH_PHASE_READY)
01273   {
01274     /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute 
01275        the message digest of a new message */
01276     HASH->CR |= HASH_ALGOSELECTION_SHA1;
01277     HASH->CR |= HASH_CR_INIT;
01278   }
01279   
01280   /* Configure the number of valid bits in last word of the message */
01281   __HAL_HASH_SET_NBVALIDBITS(Size);
01282   
01283   /* Set the phase */
01284   hhash->Phase = HAL_HASH_PHASE_PROCESS;
01285   
01286   /* Set the HASH DMA transfer complete callback */
01287   hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
01288   /* Set the DMA error callback */
01289   hhash->hdmain->XferErrorCallback = HASH_DMAError;
01290   
01291   /* Enable the DMA In DMA Stream */
01292   HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4U ? (Size+3U)/4U:Size/4U));
01293   
01294   /* Enable DMA requests */
01295   HASH->CR |= (HASH_CR_DMAE);
01296   
01297    /* Process Unlocked */
01298   __HAL_UNLOCK(hhash);
01299   
01300   /* Return function status */
01301   return HAL_OK;
01302 }
01303 
01304 /**
01305   * @brief  Returns the computed digest in SHA1 mode.
01306   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
01307   *         the configuration information for HASH module
01308   * @param  pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.  
01309   * @param  Timeout Timeout value    
01310   * @retval HAL status
01311   */
01312 HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
01313 {
01314   uint32_t tickstart = 0U;   
01315   
01316    /* Process Locked */
01317   __HAL_LOCK(hhash);
01318   
01319   /* Change HASH peripheral state */
01320   hhash->State = HAL_HASH_STATE_BUSY;
01321   
01322   /* Get tick */
01323   tickstart = HAL_GetTick();
01324   while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
01325   {
01326     /* Check for the Timeout */
01327     if(Timeout != HAL_MAX_DELAY)
01328     {
01329       if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
01330       {
01331         /* Change state */
01332         hhash->State = HAL_HASH_STATE_TIMEOUT;
01333         
01334         /* Process Unlocked */
01335         __HAL_UNLOCK(hhash);
01336         
01337         return HAL_TIMEOUT;
01338       }
01339     }
01340   }
01341   
01342   /* Read the message digest */
01343   HASH_GetDigest(pOutBuffer, 20U);
01344   
01345   /* Change HASH peripheral state */
01346   hhash->State = HAL_HASH_STATE_READY;
01347   
01348    /* Process UnLock */
01349   __HAL_UNLOCK(hhash);
01350   
01351   /* Return function status */
01352   return HAL_OK;
01353 }
01354 
01355 
01356 /**
01357   * @}
01358   */
01359 
01360 /** @defgroup HASH_Exported_Functions_Group5 HASH-MAC (HMAC) processing functions using polling mode 
01361  *  @brief   HMAC processing functions using polling mode . 
01362  *
01363 @verbatim   
01364  ===============================================================================
01365               ##### HMAC processing using polling mode functions #####
01366  ===============================================================================  
01367     [..]  This section provides functions allowing to calculate in polling mode
01368           the HMAC value using one of the following algorithms:
01369       (+) MD5
01370       (+) SHA1
01371 
01372 @endverbatim
01373   * @{
01374   */
01375 
01376 /**
01377   * @brief  Initializes the HASH peripheral in HMAC MD5 mode
01378   *         then processes pInBuffer. The digest is available in pOutBuffer
01379   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
01380   *         the configuration information for HASH module
01381   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).
01382   * @param  Size Length of the input buffer in bytes.
01383   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
01384   * @param  pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
01385   * @param  Timeout Timeout value  
01386   * @retval HAL status
01387   */
01388 HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
01389 {
01390   uint32_t tickstart = 0U;   
01391   
01392    /* Process Locked */
01393   __HAL_LOCK(hhash);
01394   
01395   /* Change the HASH state */
01396   hhash->State = HAL_HASH_STATE_BUSY;
01397   
01398   /* Check if initialization phase has already been performed */
01399   if(hhash->Phase == HAL_HASH_PHASE_READY)
01400   {
01401     /* Check if key size is greater than 64 bytes */
01402     if(hhash->Init.KeySize > 64U)
01403     {
01404       /* Select the HMAC MD5 mode */
01405       HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
01406     }
01407     else
01408     {
01409       /* Select the HMAC MD5 mode */
01410       HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
01411     }
01412   }
01413   
01414   /* Set the phase */
01415   hhash->Phase = HAL_HASH_PHASE_PROCESS;
01416   
01417   /************************** STEP 1 ******************************************/
01418   /* Configure the number of valid bits in last word of the message */
01419   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
01420   
01421   /* Write input buffer in data register */
01422   HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
01423   
01424   /* Start the digest calculation */
01425   __HAL_HASH_START_DIGEST();
01426   
01427   /* Get tick */
01428   tickstart = HAL_GetTick();
01429 
01430   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
01431   {
01432     /* Check for the Timeout */
01433     if(Timeout != HAL_MAX_DELAY)
01434     {
01435       if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
01436       {
01437         /* Change state */
01438         hhash->State = HAL_HASH_STATE_TIMEOUT;
01439         
01440         /* Process Unlocked */
01441         __HAL_UNLOCK(hhash);
01442         
01443         return HAL_TIMEOUT;
01444       }
01445     }
01446   }
01447   /************************** STEP 2 ******************************************/
01448   /* Configure the number of valid bits in last word of the message */
01449   __HAL_HASH_SET_NBVALIDBITS(Size);
01450   
01451   /* Write input buffer in data register */
01452   HASH_WriteData(pInBuffer, Size);
01453   
01454   /* Start the digest calculation */
01455   __HAL_HASH_START_DIGEST();
01456   
01457   /* Get tick */
01458   tickstart = HAL_GetTick();
01459   
01460   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
01461   {
01462     /* Check for the Timeout */
01463     if(Timeout != HAL_MAX_DELAY)
01464     {
01465       if((HAL_GetTick() - tickstart ) > Timeout)
01466       {
01467         /* Change state */
01468         hhash->State = HAL_HASH_STATE_TIMEOUT;
01469         
01470         /* Process Unlocked */
01471         __HAL_UNLOCK(hhash);
01472         
01473         return HAL_TIMEOUT;
01474       }
01475     }
01476   }
01477   /************************** STEP 3 ******************************************/
01478   /* Configure the number of valid bits in last word of the message */
01479   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
01480   
01481   /* Write input buffer in data register */
01482   HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
01483   
01484   /* Start the digest calculation */
01485   __HAL_HASH_START_DIGEST();
01486   
01487   /* Get tick */
01488   tickstart = HAL_GetTick();
01489   
01490   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
01491   {
01492     /* Check for the Timeout */
01493     if(Timeout != HAL_MAX_DELAY)
01494     {
01495       if((HAL_GetTick() - tickstart ) > Timeout)
01496       {
01497         /* Change state */
01498         hhash->State = HAL_HASH_STATE_TIMEOUT;
01499         
01500         /* Process Unlocked */
01501         __HAL_UNLOCK(hhash);
01502         
01503         return HAL_TIMEOUT;
01504       }
01505     }
01506   }
01507   
01508   /* Read the message digest */
01509   HASH_GetDigest(pOutBuffer, 16U);
01510   
01511   /* Change the HASH state */
01512   hhash->State = HAL_HASH_STATE_READY;
01513   
01514   /* Process Unlocked */
01515   __HAL_UNLOCK(hhash);
01516   
01517   /* Return function status */
01518   return HAL_OK;
01519 }
01520 
01521 /**
01522   * @brief  Initializes the HASH peripheral in HMAC SHA1 mode
01523   *         then processes pInBuffer. The digest is available in pOutBuffer.
01524   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
01525   *         the configuration information for HASH module
01526   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).
01527   * @param   Size Length of the input buffer in bytes.
01528   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
01529   * @param  pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
01530   * @param  Timeout Timeout value  
01531   * @retval HAL status
01532   */
01533 HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
01534 {
01535   uint32_t tickstart = 0U;   
01536   
01537   /* Process Locked */
01538   __HAL_LOCK(hhash);
01539   
01540   /* Change the HASH state */
01541   hhash->State = HAL_HASH_STATE_BUSY;
01542   
01543   /* Check if initialization phase has already been performed */
01544   if(hhash->Phase == HAL_HASH_PHASE_READY)
01545   {
01546     /* Check if key size is greater than 64 bytes */
01547     if(hhash->Init.KeySize > 64U)
01548     {
01549       /* Select the HMAC SHA1 mode */
01550       HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
01551     }
01552     else
01553     {
01554       /* Select the HMAC SHA1 mode */
01555       HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
01556     }
01557   }
01558   
01559   /* Set the phase */
01560   hhash->Phase = HAL_HASH_PHASE_PROCESS;
01561   
01562   /************************** STEP 1 ******************************************/
01563   /* Configure the number of valid bits in last word of the message */
01564   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
01565   
01566   /* Write input buffer in data register */
01567   HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
01568   
01569   /* Start the digest calculation */
01570   __HAL_HASH_START_DIGEST();
01571   
01572   /* Get tick */
01573   tickstart = HAL_GetTick();
01574   
01575   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
01576   {
01577     /* Check for the Timeout */
01578     if(Timeout != HAL_MAX_DELAY)
01579     {
01580       if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
01581       {
01582         /* Change state */
01583         hhash->State = HAL_HASH_STATE_TIMEOUT;
01584         
01585         /* Process Unlocked */
01586         __HAL_UNLOCK(hhash);
01587         
01588         return HAL_TIMEOUT;
01589       }
01590     }
01591   }
01592   /************************** STEP 2 ******************************************/
01593   /* Configure the number of valid bits in last word of the message */  
01594   __HAL_HASH_SET_NBVALIDBITS(Size);
01595   
01596   /* Write input buffer in data register */
01597   HASH_WriteData(pInBuffer, Size);
01598   
01599   /* Start the digest calculation */
01600   __HAL_HASH_START_DIGEST();
01601   
01602   /* Get tick */
01603   tickstart = HAL_GetTick();
01604   
01605   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
01606   {
01607     /* Check for the Timeout */
01608     if(Timeout != HAL_MAX_DELAY)
01609     {
01610       if((HAL_GetTick() - tickstart ) > Timeout)
01611       {
01612         /* Change state */
01613         hhash->State = HAL_HASH_STATE_TIMEOUT;
01614         
01615         /* Process Unlocked */
01616         __HAL_UNLOCK(hhash);
01617         
01618         return HAL_TIMEOUT;
01619       }
01620     }
01621   }
01622   /************************** STEP 3 ******************************************/
01623   /* Configure the number of valid bits in last word of the message */
01624   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
01625   
01626   /* Write input buffer in data register */
01627   HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
01628   
01629   /* Start the digest calculation */
01630   __HAL_HASH_START_DIGEST();
01631   
01632   /* Get tick */
01633   tickstart = HAL_GetTick();
01634 
01635   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
01636   {
01637     /* Check for the Timeout */
01638     if(Timeout != HAL_MAX_DELAY)
01639     {
01640       if((HAL_GetTick() - tickstart ) > Timeout)
01641       {
01642         /* Change state */
01643         hhash->State = HAL_HASH_STATE_TIMEOUT;
01644         
01645         /* Process Unlocked */
01646         __HAL_UNLOCK(hhash);
01647         
01648         return HAL_TIMEOUT;
01649       }
01650     }
01651   }
01652   /* Read the message digest */
01653   HASH_GetDigest(pOutBuffer, 20U);
01654   
01655   /* Change the HASH state */
01656   hhash->State = HAL_HASH_STATE_READY;
01657   
01658   /* Process Unlocked */
01659   __HAL_UNLOCK(hhash);
01660   
01661   /* Return function status */
01662   return HAL_OK;
01663 }
01664 
01665 /**
01666   * @}
01667   */
01668 
01669 /** @defgroup HASH_Exported_Functions_Group6 HASH-MAC (HMAC) processing functions using DMA mode 
01670  *  @brief   HMAC processing functions using DMA mode . 
01671  *
01672 @verbatim   
01673  ===============================================================================
01674                 ##### HMAC processing using DMA mode functions #####
01675  ===============================================================================  
01676     [..]  This section provides functions allowing to calculate in DMA mode
01677           the HMAC value using one of the following algorithms:
01678       (+) MD5
01679       (+) SHA1
01680 
01681 @endverbatim
01682   * @{
01683   */
01684 
01685 /**
01686   * @brief  Initializes the HASH peripheral in HMAC MD5 mode
01687   *         then enables DMA to control data transfer.
01688   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
01689   *         the configuration information for HASH module
01690   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).
01691   * @param  Size Length of the input buffer in bytes.
01692   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
01693   * @retval HAL status
01694   */
01695 HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
01696 {
01697   uint32_t inputaddr  = 0U;
01698   
01699    /* Process Locked */
01700   __HAL_LOCK(hhash);
01701   
01702   /* Change the HASH state */
01703   hhash->State = HAL_HASH_STATE_BUSY;
01704   
01705   /* Save buffer pointer and size in handle */
01706   hhash->pHashInBuffPtr = pInBuffer;
01707   hhash->HashBuffSize = Size;
01708   hhash->HashInCount = 0U;
01709   
01710   /* Check if initialization phase has already been performed */
01711   if(hhash->Phase == HAL_HASH_PHASE_READY)
01712   {
01713     /* Check if key size is greater than 64 bytes */
01714     if(hhash->Init.KeySize > 64U)
01715     {
01716       /* Select the HMAC MD5 mode */
01717       HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
01718     }
01719     else
01720     {
01721       /* Select the HMAC MD5 mode */
01722       HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
01723     }
01724   }
01725   
01726   /* Set the phase */
01727   hhash->Phase = HAL_HASH_PHASE_PROCESS;
01728   
01729   /* Configure the number of valid bits in last word of the message */
01730   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
01731   
01732   /* Get the key address */
01733   inputaddr = (uint32_t)(hhash->Init.pKey);
01734   
01735   /* Set the HASH DMA transfer complete callback */
01736   hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
01737   /* Set the DMA error callback */
01738   hhash->hdmain->XferErrorCallback = HASH_DMAError;
01739   
01740   /* Enable the DMA In DMA Stream */
01741   HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4U ? (hhash->Init.KeySize+3U)/4U:hhash->Init.KeySize/4U));
01742   /* Enable DMA requests */
01743   HASH->CR |= (HASH_CR_DMAE);
01744   
01745   /* Process Unlocked */
01746   __HAL_UNLOCK(hhash);
01747   
01748   /* Return function status */
01749   return HAL_OK;
01750 }
01751 
01752 /**
01753   * @brief  Initializes the HASH peripheral in HMAC SHA1 mode
01754   *         then enables DMA to control data transfer.
01755   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
01756   *         the configuration information for HASH module
01757   * @param  pInBuffer Pointer to the input buffer (buffer to be hashed).
01758   * @param  Size Length of the input buffer in bytes.
01759   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
01760   * @retval HAL status
01761   */
01762 HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
01763 {
01764   uint32_t inputaddr  = 0U;
01765   
01766   /* Process Locked */
01767   __HAL_LOCK(hhash);
01768   
01769   /* Change the HASH state */
01770   hhash->State = HAL_HASH_STATE_BUSY;
01771   
01772   /* Save buffer pointer and size in handle */
01773   hhash->pHashInBuffPtr = pInBuffer;
01774   hhash->HashBuffSize = Size;
01775   hhash->HashInCount = 0U;
01776   
01777   /* Check if initialization phase has already been performed */
01778   if(hhash->Phase == HAL_HASH_PHASE_READY)
01779   {
01780     /* Check if key size is greater than 64 bytes */
01781     if(hhash->Init.KeySize > 64U)
01782     {
01783       /* Select the HMAC SHA1 mode */
01784       HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
01785     }
01786     else
01787     {
01788       /* Select the HMAC SHA1 mode */
01789       HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
01790     }
01791   }
01792   
01793   /* Set the phase */
01794   hhash->Phase = HAL_HASH_PHASE_PROCESS;
01795   
01796   /* Configure the number of valid bits in last word of the message */
01797   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
01798   
01799   /* Get the key address */
01800   inputaddr = (uint32_t)(hhash->Init.pKey);
01801   
01802   /* Set the HASH DMA transfer complete callback */
01803   hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
01804   /* Set the DMA error callback */
01805   hhash->hdmain->XferErrorCallback = HASH_DMAError;
01806   
01807   /* Enable the DMA In DMA Stream */
01808   HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4U ? (hhash->Init.KeySize+3U)/4U:hhash->Init.KeySize/4U));
01809   /* Enable DMA requests */
01810   HASH->CR |= (HASH_CR_DMAE);
01811   
01812   /* Process Unlocked */
01813   __HAL_UNLOCK(hhash);
01814   
01815   /* Return function status */
01816   return HAL_OK;
01817 }
01818 
01819 /**
01820   * @}
01821   */
01822 
01823 /** @defgroup HASH_Exported_Functions_Group7 Peripheral State functions 
01824  *  @brief   Peripheral State functions. 
01825  *
01826 @verbatim   
01827  ===============================================================================
01828                       ##### Peripheral State functions #####
01829  ===============================================================================  
01830     [..]
01831     This subsection permits to get in run-time the status of the peripheral.
01832 
01833 @endverbatim
01834   * @{
01835   */
01836 
01837 /**
01838   * @brief return the HASH state
01839   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
01840   *         the configuration information for HASH module
01841   * @retval HAL state
01842   */
01843 HAL_HASH_StateTypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
01844 {
01845   return hhash->State;
01846 }
01847 
01848 /**
01849   * @}
01850   */
01851 
01852 /**
01853   * @}
01854   */
01855 
01856 #endif /* STM32F415xx || STM32F417xx || STM32F437xx || STM32F439xx || STM32F479xx */
01857 #endif /* HAL_HASH_MODULE_ENABLED */
01858 /**
01859   * @}
01860   */
01861 
01862 /**
01863   * @}
01864   */
01865 
01866 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/