]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_hash.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F4 / stm32f4xx_hal_hash.c
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_hash.c
4   * @author  MCD Application Team
5   * @version V1.1.0
6   * @date    19-June-2014
7   * @brief   HASH HAL module driver.
8   *          This file provides firmware functions to manage the following 
9   *          functionalities of the HASH peripheral:
10   *           + Initialization and de-initialization functions
11   *           + HASH/HMAC Processing functions by algorithm using polling mode
12   *           + HASH/HMAC functions by algorithm using interrupt mode
13   *           + HASH/HMAC functions by algorithm using DMA mode
14   *           + Peripheral State functions
15   *         
16   @verbatim
17   ==============================================================================
18                      ##### How to use this driver #####
19   ==============================================================================
20     [..]
21     The HASH HAL driver can be used as follows:
22     (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
23         (##) Enable the HASH interface clock using __HASH_CLK_ENABLE()
24         (##) In case of using processing APIs based on interrupts (e.g. HAL_HMAC_SHA1_Start_IT())
25             (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
26             (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
27             (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
28         (##) In case of using DMA to control data transfer (e.g. HAL_HMAC_SHA1_Start_DMA())
29             (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
30             (+++) Configure and enable one DMA stream one for managing data transfer from
31                 memory to peripheral (input stream). Managing data transfer from
32                 peripheral to memory can be performed only using CPU
33             (+++) Associate the initialized DMA handle to the HASH DMA handle
34                 using  __HAL_LINKDMA()
35             (+++) Configure the priority and enable the NVIC for the transfer complete
36                 interrupt on the DMA Stream using HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
37     (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
38         (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
39         (##) For HMAC, the encryption key.
40         (##) For HMAC, the key size used for encryption.
41     (#)Three processing functions are available:
42         (##) Polling mode: processing APIs are blocking functions
43              i.e. they process the data and wait till the digest computation is finished
44              e.g. HAL_HASH_SHA1_Start()
45         (##) Interrupt mode: encryption and decryption APIs are not blocking functions
46                 i.e. they process the data under interrupt
47                 e.g. HAL_HASH_SHA1_Start_IT()
48         (##) DMA mode: processing APIs are not blocking functions and the CPU is
49              not used for data transfer i.e. the data transfer is ensured by DMA
50                 e.g. HAL_HASH_SHA1_Start_DMA()
51     (#)When the processing function is called at first time after HAL_HASH_Init()
52        the HASH peripheral is initialized and processes the buffer in input.
53        After that, the digest computation is started.
54        When processing multi-buffer use the accumulate function to write the
55        data in the peripheral without starting the digest computation. In last 
56        buffer use the start function to input the last buffer ans start the digest
57        computation.
58        (##) e.g. HAL_HASH_SHA1_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
59        (##) write (n-1)th data buffer in the peripheral without starting the digest computation
60        (##) HAL_HASH_SHA1_Start() : write (n)th data buffer in the peripheral and start the digest computation
61     (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
62     (#)In case of using DMA, call the DMA start processing e.g. HAL_HASH_SHA1_Start_DMA().
63        After that, call the finish function in order to get the digest value
64        e.g. HAL_HASH_SHA1_Finish()
65     (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.
66
67   @endverbatim
68   ******************************************************************************
69   * @attention
70   *
71   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
72   *
73   * Redistribution and use in source and binary forms, with or without modification,
74   * are permitted provided that the following conditions are met:
75   *   1. Redistributions of source code must retain the above copyright notice,
76   *      this list of conditions and the following disclaimer.
77   *   2. Redistributions in binary form must reproduce the above copyright notice,
78   *      this list of conditions and the following disclaimer in the documentation
79   *      and/or other materials provided with the distribution.
80   *   3. Neither the name of STMicroelectronics nor the names of its contributors
81   *      may be used to endorse or promote products derived from this software
82   *      without specific prior written permission.
83   *
84   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
85   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
86   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
88   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
89   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
90   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
91   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
92   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
93   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94   *
95   ******************************************************************************
96   */ 
97
98 /* Includes ------------------------------------------------------------------*/
99 #include "stm32f4xx_hal.h"
100
101 /** @addtogroup STM32F4xx_HAL_Driver
102   * @{
103   */
104
105 /** @defgroup HASH 
106   * @brief HASH HAL module driver.
107   * @{
108   */
109
110 #ifdef HAL_HASH_MODULE_ENABLED
111
112 #if defined(STM32F415xx) || defined(STM32F417xx) || defined(STM32F437xx) || defined(STM32F439xx)
113
114 /* Private typedef -----------------------------------------------------------*/
115 /* Private define ------------------------------------------------------------*/
116 /* Private macro -------------------------------------------------------------*/
117 /* Private variables ---------------------------------------------------------*/
118 /* Private function prototypes -----------------------------------------------*/
119 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
120 static void HASH_DMAError(DMA_HandleTypeDef *hdma);
121 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
122 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size);
123
124 /* Private functions ---------------------------------------------------------*/
125
126 /** @defgroup HASH_Private_Functions
127   * @{
128   */
129
130 /** @defgroup HASH_Group1 Initialization and de-initialization functions 
131  *  @brief    Initialization and Configuration functions. 
132  *
133 @verbatim    
134  ===============================================================================
135               ##### Initialization and de-initialization functions #####
136  ===============================================================================
137     [..]  This section provides functions allowing to:
138       (+) Initialize the HASH according to the specified parameters 
139           in the HASH_InitTypeDef and creates the associated handle.
140       (+) DeInitialize the HASH peripheral.
141       (+) Initialize the HASH MSP.
142       (+) DeInitialize HASH MSP. 
143  
144 @endverbatim
145   * @{
146   */
147
148 /**
149   * @brief  Initializes the HASH according to the specified parameters in the
150             HASH_HandleTypeDef and creates the associated handle.
151   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
152   *         the configuration information for HASH module
153   * @retval HAL status
154   */
155 HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
156 {
157   /* Check the hash handle allocation */
158   if(hhash == HAL_NULL)
159   {
160     return HAL_ERROR;
161   }
162
163   /* Check the parameters */
164   assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
165    
166   if(hhash->State == HAL_HASH_STATE_RESET)
167   {
168     /* Init the low level hardware */
169     HAL_HASH_MspInit(hhash);
170   }
171   
172   /* Change the HASH state */
173   hhash->State = HAL_HASH_STATE_BUSY;
174   
175   /* Reset HashInCount, HashBuffSize and HashITCounter */
176   hhash->HashInCount = 0;
177   hhash->HashBuffSize = 0;
178   hhash->HashITCounter = 0;
179   
180   /* Set the data type */
181   HASH->CR |= (uint32_t) (hhash->Init.DataType);
182   
183   /* Change the HASH state */
184   hhash->State = HAL_HASH_STATE_READY;
185   
186   /* Set the default HASH phase */
187   hhash->Phase = HAL_HASH_PHASE_READY;
188   
189   /* Return function status */
190   return HAL_OK;
191 }
192
193 /**
194   * @brief  DeInitializes the HASH peripheral.
195   * @note   This API must be called before starting a new processing. 
196   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
197   *         the configuration information for HASH module
198   * @retval HAL status
199   */
200 HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
201
202   /* Check the HASH handle allocation */
203   if(hhash == HAL_NULL)
204   {
205     return HAL_ERROR;
206   }
207   
208   /* Change the HASH state */
209   hhash->State = HAL_HASH_STATE_BUSY;
210   
211   /* Set the default HASH phase */
212   hhash->Phase = HAL_HASH_PHASE_READY;
213   
214   /* Reset HashInCount, HashBuffSize and HashITCounter */
215   hhash->HashInCount = 0;
216   hhash->HashBuffSize = 0;
217   hhash->HashITCounter = 0;
218   
219   /* DeInit the low level hardware */
220   HAL_HASH_MspDeInit(hhash);
221   
222   /* Change the HASH state */
223   hhash->State = HAL_HASH_STATE_RESET;  
224
225   /* Release Lock */
226   __HAL_UNLOCK(hhash);
227
228   /* Return function status */
229   return HAL_OK;
230 }
231
232 /**
233   * @brief  Initializes the HASH MSP.
234   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
235   *         the configuration information for HASH module
236   * @retval None
237   */
238 __weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
239 {
240   /* NOTE: This function Should not be modified, when the callback is needed,
241            the HAL_HASH_MspInit could be implemented in the user file
242    */
243 }
244
245 /**
246   * @brief  DeInitializes HASH MSP.
247   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
248   *         the configuration information for HASH module
249   * @retval None
250   */
251 __weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
252 {
253   /* NOTE: This function Should not be modified, when the callback is needed,
254            the HAL_HASH_MspDeInit could be implemented in the user file
255    */
256 }
257
258 /**
259   * @brief  Input data transfer complete callback.
260   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
261   *         the configuration information for HASH module
262   * @retval None
263   */
264  __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
265 {
266   /* NOTE: This function Should not be modified, when the callback is needed,
267            the HAL_HASH_InCpltCallback could be implemented in the user file
268    */ 
269 }
270
271 /**
272   * @brief  Data transfer Error callback.
273   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
274   *         the configuration information for HASH module
275   * @retval None
276   */
277  __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
278 {
279   /* NOTE: This function Should not be modified, when the callback is needed,
280            the HAL_HASH_ErrorCallback could be implemented in the user file
281    */ 
282 }
283
284 /**
285   * @brief  Digest computation complete callback. It is used only with interrupt.
286   * @note   This callback is not relevant with DMA.
287   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
288   *         the configuration information for HASH module
289   * @retval None
290   */
291  __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
292 {
293   /* NOTE: This function Should not be modified, when the callback is needed,
294            the HAL_HASH_DgstCpltCallback could be implemented in the user file
295    */ 
296 }
297
298 /**
299   * @}
300   */
301
302 /** @defgroup HASH_Group2 HASH processing functions using polling mode 
303  *  @brief   processing functions using polling mode 
304  *
305 @verbatim   
306  ===============================================================================
307               ##### HASH processing using polling mode functions#####
308  ===============================================================================  
309     [..]  This section provides functions allowing to calculate in polling mode
310           the hash value using one of the following algorithms:
311       (+) MD5
312       (+) SHA1
313
314 @endverbatim
315   * @{
316   */
317
318 /**
319   * @brief  Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
320             The digest is available in pOutBuffer.
321   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
322   *         the configuration information for HASH module
323   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
324   * @param  Size: Length of the input buffer in bytes.
325   *          If the Size is multiple of 64 bytes, appending the input buffer is possible.
326   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware
327   *          and appending the input buffer is no more possible.
328   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
329   * @param  Timeout: Timeout value
330   * @retval HAL status
331   */
332 HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
333 {
334   uint32_t tickstart = 0;
335   
336   /* Process Locked */
337   __HAL_LOCK(hhash);
338   
339   /* Change the HASH state */
340   hhash->State = HAL_HASH_STATE_BUSY;
341   
342   /* Check if initialization phase has already been performed */
343   if(hhash->Phase == HAL_HASH_PHASE_READY)
344   {
345     /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute 
346        the message digest of a new message */
347     HASH->CR |= HASH_AlgoSelection_MD5 | HASH_CR_INIT;
348   }
349   
350   /* Set the phase */
351   hhash->Phase = HAL_HASH_PHASE_PROCESS;
352   
353   /* Configure the number of valid bits in last word of the message */
354   __HAL_HASH_SET_NBVALIDBITS(Size);
355   
356   /* Write input buffer in data register */
357   HASH_WriteData(pInBuffer, Size);
358   
359   /* Start the digest calculation */
360   __HAL_HASH_START_DIGEST();
361   
362   /* Get tick */
363   tickstart = HAL_GetTick();
364   
365   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
366   {
367     /* Check for the Timeout */
368     if(Timeout != HAL_MAX_DELAY)
369     {
370       if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
371       {
372         /* Change state */
373         hhash->State = HAL_HASH_STATE_TIMEOUT;
374         
375         /* Process Unlocked */
376         __HAL_UNLOCK(hhash);
377         
378         return HAL_TIMEOUT;
379       }
380     }
381   }
382   
383   /* Read the message digest */
384   HASH_GetDigest(pOutBuffer, 16);
385   
386   /* Change the HASH state */
387   hhash->State = HAL_HASH_STATE_READY;
388    
389   /* Process Unlocked */
390   __HAL_UNLOCK(hhash);
391   
392   /* Return function status */
393   return HAL_OK;
394 }
395
396 /**
397   * @brief  Initializes the HASH peripheral in MD5 mode then writes the pInBuffer.
398   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
399   *         the configuration information for HASH module
400   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
401   * @param  Size: Length of the input buffer in bytes.
402   *          If the Size is multiple of 64 bytes, appending the input buffer is possible.
403   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware
404   *          and appending the input buffer is no more possible.
405   * @retval HAL status
406   */
407 HAL_StatusTypeDef HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
408 {  
409   /* Process Locked */
410   __HAL_LOCK(hhash);
411   
412   /* Change the HASH state */
413   hhash->State = HAL_HASH_STATE_BUSY;
414   
415   /* Check if initialization phase has already been performed */
416   if(hhash->Phase == HAL_HASH_PHASE_READY)
417   {
418     /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute 
419        the message digest of a new message */
420     HASH->CR |= HASH_AlgoSelection_MD5 | HASH_CR_INIT;
421   }
422   
423   /* Set the phase */
424   hhash->Phase = HAL_HASH_PHASE_PROCESS;
425   
426   /* Configure the number of valid bits in last word of the message */
427   __HAL_HASH_SET_NBVALIDBITS(Size);
428   
429   /* Write input buffer in data register */
430   HASH_WriteData(pInBuffer, Size);
431   
432   /* Change the HASH state */
433   hhash->State = HAL_HASH_STATE_READY;
434   
435   /* Process Unlocked */
436   __HAL_UNLOCK(hhash);
437   
438   /* Return function status */
439   return HAL_OK;
440 }
441
442 /**
443   * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
444             The digest is available in pOutBuffer.
445   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
446   *         the configuration information for HASH module
447   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).  
448   * @param  Size: Length of the input buffer in bytes.
449   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
450   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
451   * @param  Timeout: Timeout value  
452   * @retval HAL status
453   */
454 HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
455 {
456   uint32_t tickstart = 0;   
457
458   /* Process Locked */
459   __HAL_LOCK(hhash);
460   
461   /* Change the HASH state */
462   hhash->State = HAL_HASH_STATE_BUSY;
463   
464   /* Check if initialization phase has already been performed */
465   if(hhash->Phase == HAL_HASH_PHASE_READY)
466   {
467     /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute 
468        the message digest of a new message */
469     HASH->CR |= HASH_AlgoSelection_SHA1 | HASH_CR_INIT;
470   }
471   
472   /* Set the phase */
473   hhash->Phase = HAL_HASH_PHASE_PROCESS;
474   
475   /* Configure the number of valid bits in last word of the message */
476   __HAL_HASH_SET_NBVALIDBITS(Size);
477   
478   /* Write input buffer in data register */
479   HASH_WriteData(pInBuffer, Size);
480   
481   /* Start the digest calculation */
482   __HAL_HASH_START_DIGEST();
483   
484   /* Get tick */
485   tickstart = HAL_GetTick();
486
487   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
488     {
489       /* Check for the Timeout */
490       if(Timeout != HAL_MAX_DELAY)
491       {
492         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
493         {
494           /* Change state */
495           hhash->State = HAL_HASH_STATE_TIMEOUT;
496           
497           /* Process Unlocked */
498           __HAL_UNLOCK(hhash);
499           
500           return HAL_TIMEOUT;
501         }
502       }
503     }
504   
505   /* Read the message digest */
506   HASH_GetDigest(pOutBuffer, 20);
507   
508   /* Change the HASH state */
509   hhash->State = HAL_HASH_STATE_READY;
510   
511   /* Process Unlocked */
512   __HAL_UNLOCK(hhash);
513   
514   /* Return function status */
515   return HAL_OK;
516 }
517
518 /**
519   * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
520             The digest is available in pOutBuffer.
521   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
522   *         the configuration information for HASH module
523   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
524   * @param  Size: Length of the input buffer in bytes.
525   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
526   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
527   * @retval HAL status
528   */
529 HAL_StatusTypeDef HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
530 {
531   /* Process Locked */
532   __HAL_LOCK(hhash);
533   
534   /* Change the HASH state */
535   hhash->State = HAL_HASH_STATE_BUSY;
536   
537   /* Check if initialization phase has already been performed */
538   if(hhash->Phase == HAL_HASH_PHASE_READY)
539   {
540     /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute 
541        the message digest of a new message */
542     HASH->CR |= HASH_AlgoSelection_SHA1 | HASH_CR_INIT;
543   }
544   
545   /* Set the phase */
546   hhash->Phase = HAL_HASH_PHASE_PROCESS;
547   
548   /* Configure the number of valid bits in last word of the message */
549   __HAL_HASH_SET_NBVALIDBITS(Size);
550   
551   /* Write input buffer in data register */
552   HASH_WriteData(pInBuffer, Size);
553   
554   /* Change the HASH state */
555   hhash->State = HAL_HASH_STATE_READY;
556   
557   /* Process Unlocked */
558   __HAL_UNLOCK(hhash);
559   
560   /* Return function status */
561   return HAL_OK;
562 }
563
564 /**
565   * @}
566   */
567
568 /** @defgroup HASH_Group3 HASH processing functions using interrupt mode
569  *  @brief   processing functions using interrupt mode. 
570  *
571 @verbatim   
572  ===============================================================================
573               ##### HASH processing using interrupt mode functions #####
574  ===============================================================================  
575     [..]  This section provides functions allowing to calculate in interrupt mode
576           the hash value using one of the following algorithms:
577       (+) MD5
578       (+) SHA1
579
580 @endverbatim
581   * @{
582   */
583
584 /**
585   * @brief  Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
586   *         The digest is available in pOutBuffer.
587   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
588   *         the configuration information for HASH module
589   * @param  pOutBuffer: Pointer to the Output buffer (hashed buffer).   
590   * @param  Size: Length of the input buffer in bytes.
591   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
592   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
593   * @retval HAL status
594   */
595 HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
596 {
597   uint32_t inputaddr;
598   uint32_t outputaddr;
599   uint32_t buffercounter;
600   uint32_t inputcounter;
601   
602   /* Process Locked */
603   __HAL_LOCK(hhash);
604   
605   if(hhash->HashITCounter == 0)
606   {
607     hhash->HashITCounter = 1;
608   }
609   else
610   {
611     hhash->HashITCounter = 0;
612   }
613   if(hhash->State == HAL_HASH_STATE_READY)
614   {
615     /* Change the HASH state */
616     hhash->State = HAL_HASH_STATE_BUSY;
617     
618     hhash->HashInCount = Size;
619     hhash->pHashInBuffPtr = pInBuffer;
620     hhash->pHashOutBuffPtr = pOutBuffer;
621     
622     /* Check if initialization phase has already been performed */
623     if(hhash->Phase == HAL_HASH_PHASE_READY)
624     {
625       /* Select the SHA1 mode */
626       HASH->CR |= HASH_AlgoSelection_MD5;
627       /* Reset the HASH processor core, so that the HASH will be ready to compute 
628          the message digest of a new message */
629       HASH->CR |= HASH_CR_INIT;
630     }
631     
632     /* Set the phase */
633     hhash->Phase = HAL_HASH_PHASE_PROCESS;
634     
635     /* Process Unlocked */
636     __HAL_UNLOCK(hhash);
637     
638     /* Enable Interrupts */
639     HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
640     
641     /* Return function status */
642     return HAL_OK;
643   }
644   if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
645   {
646     outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
647     /* Read the Output block from the Output FIFO */
648     *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
649     outputaddr+=4;
650     *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
651     outputaddr+=4;
652     *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
653     outputaddr+=4;
654     *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
655     
656     if(hhash->HashInCount == 0)
657     {
658       /* Disable Interrupts */
659       HASH->IMR = 0;
660       /* Change the HASH state */
661       hhash->State = HAL_HASH_STATE_READY;
662       /* Call digest computation complete callback */
663       HAL_HASH_DgstCpltCallback(hhash);
664     }
665   }
666   if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
667   {
668     if(hhash->HashInCount > 64)
669     {
670       inputaddr = (uint32_t)hhash->pHashInBuffPtr;
671       /* Write the Input block in the Data IN register */
672       for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
673       {
674         HASH->DIN = *(uint32_t*)inputaddr;
675       }
676       if(hhash->HashITCounter == 0)
677       {
678         HASH->DIN = *(uint32_t*)inputaddr;
679
680         if(hhash->HashInCount >= 68)
681         {
682           /* Decrement buffer counter */
683           hhash->HashInCount -= 68;
684           hhash->pHashInBuffPtr+= 68;
685         }
686         else
687         {
688           hhash->HashInCount -= 64;
689         }
690       }
691       else
692       {
693         /* Decrement buffer counter */
694         hhash->HashInCount -= 64;
695         hhash->pHashInBuffPtr+= 64;
696       }
697     }
698     else
699     {
700       /* Get the buffer address */
701       inputaddr = (uint32_t)hhash->pHashInBuffPtr;
702       /* Get the buffer counter */
703       inputcounter = hhash->HashInCount;
704       /* Disable Interrupts */
705       HASH->IMR &= ~(HASH_IT_DINI);
706       /* Configure the number of valid bits in last word of the message */
707       __HAL_HASH_SET_NBVALIDBITS(inputcounter);
708       
709       if((inputcounter > 4) && (inputcounter%4))
710       {
711         inputcounter = (inputcounter+4-inputcounter%4);
712       }
713       
714       /* Write the Input block in the Data IN register */
715       for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
716       {
717         HASH->DIN = *(uint32_t*)inputaddr;
718         inputaddr+=4;
719       }
720       /* Start the digest calculation */
721       __HAL_HASH_START_DIGEST();
722       /* Reset buffer counter */
723       hhash->HashInCount = 0;
724     }
725     /* Call Input data transfer complete callback */
726     HAL_HASH_InCpltCallback(hhash);
727   }
728   
729   /* Process Unlocked */
730   __HAL_UNLOCK(hhash);
731   
732   /* Return function status */
733   return HAL_OK;
734 }
735
736 /**
737   * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
738   *         The digest is available in pOutBuffer.
739   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
740   *         the configuration information for HASH module
741   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed). 
742   * @param  Size: Length of the input buffer in bytes.
743   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
744   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
745   * @retval HAL status
746   */
747 HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
748 {
749   uint32_t inputaddr;
750   uint32_t outputaddr;
751   uint32_t buffercounter;
752   uint32_t inputcounter;
753   
754   /* Process Locked */
755   __HAL_LOCK(hhash);
756   
757   if(hhash->HashITCounter == 0)
758   {
759     hhash->HashITCounter = 1;
760   }
761   else
762   {
763     hhash->HashITCounter = 0;
764   }
765   if(hhash->State == HAL_HASH_STATE_READY)
766   {
767     /* Change the HASH state */
768     hhash->State = HAL_HASH_STATE_BUSY;
769     
770     hhash->HashInCount = Size;
771     hhash->pHashInBuffPtr = pInBuffer;
772     hhash->pHashOutBuffPtr = pOutBuffer;
773     
774     /* Check if initialization phase has already been performed */
775     if(hhash->Phase == HAL_HASH_PHASE_READY)
776     {
777       /* Select the SHA1 mode */
778       HASH->CR |= HASH_AlgoSelection_SHA1;
779       /* Reset the HASH processor core, so that the HASH will be ready to compute 
780          the message digest of a new message */
781       HASH->CR |= HASH_CR_INIT;
782     }
783     
784     /* Set the phase */
785     hhash->Phase = HAL_HASH_PHASE_PROCESS;
786     
787     /* Process Unlocked */
788     __HAL_UNLOCK(hhash);
789     
790     /* Enable Interrupts */
791     HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
792     
793     /* Return function status */
794     return HAL_OK;
795   }
796   if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
797   {
798     outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
799     /* Read the Output block from the Output FIFO */
800     *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
801     outputaddr+=4;
802     *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
803     outputaddr+=4;
804     *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
805     outputaddr+=4;
806     *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
807     outputaddr+=4;
808     *(uint32_t*)(outputaddr) = __REV(HASH->HR[4]);
809     if(hhash->HashInCount == 0)
810     {
811       /* Disable Interrupts */
812       HASH->IMR = 0;
813       /* Change the HASH state */
814       hhash->State = HAL_HASH_STATE_READY;
815       /* Call digest computation complete callback */
816       HAL_HASH_DgstCpltCallback(hhash);
817     }
818   }
819   if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
820   {
821     if(hhash->HashInCount > 64)
822     {
823       inputaddr = (uint32_t)hhash->pHashInBuffPtr;
824       /* Write the Input block in the Data IN register */
825       for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
826       {
827         HASH->DIN = *(uint32_t*)inputaddr;
828         inputaddr+=4;
829       }
830       if(hhash->HashITCounter == 0)
831       {
832         HASH->DIN = *(uint32_t*)inputaddr;
833       
834         if(hhash->HashInCount >= 68)
835         {
836           /* Decrement buffer counter */
837           hhash->HashInCount -= 68;
838           hhash->pHashInBuffPtr+= 68;
839         }
840         else
841         {
842           hhash->HashInCount -= 64;
843         }
844       }
845       else
846       {
847         /* Decrement buffer counter */
848         hhash->HashInCount -= 64;
849         hhash->pHashInBuffPtr+= 64;
850       }
851     }
852     else
853     {
854       /* Get the buffer address */
855       inputaddr = (uint32_t)hhash->pHashInBuffPtr;
856       /* Get the buffer counter */
857       inputcounter = hhash->HashInCount;
858       /* Disable Interrupts */
859       HASH->IMR &= ~(HASH_IT_DINI);
860       /* Configure the number of valid bits in last word of the message */
861       __HAL_HASH_SET_NBVALIDBITS(inputcounter);
862       
863       if((inputcounter > 4) && (inputcounter%4))
864       {
865         inputcounter = (inputcounter+4-inputcounter%4);
866       }
867       
868       /* Write the Input block in the Data IN register */
869       for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
870       {
871         HASH->DIN = *(uint32_t*)inputaddr;
872         inputaddr+=4;
873       }
874       /* Start the digest calculation */
875       __HAL_HASH_START_DIGEST();
876       /* Reset buffer counter */
877       hhash->HashInCount = 0;
878     }
879     /* Call Input data transfer complete callback */
880     HAL_HASH_InCpltCallback(hhash);
881   }
882   
883   /* Process Unlocked */
884   __HAL_UNLOCK(hhash);
885   
886   /* Return function status */
887   return HAL_OK;
888 }
889
890 /**
891   * @brief This function handles HASH interrupt request.
892   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
893   *         the configuration information for HASH module
894   * @retval None
895   */
896 void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
897 {
898   switch(HASH->CR & HASH_CR_ALGO)
899   {
900     case HASH_AlgoSelection_MD5:
901        HAL_HASH_MD5_Start_IT(hhash, HAL_NULL, 0, HAL_NULL);
902     break;
903     
904     case HASH_AlgoSelection_SHA1:
905       HAL_HASH_SHA1_Start_IT(hhash, HAL_NULL, 0, HAL_NULL);
906     break;
907     
908     default:
909     break;
910   }
911 }
912
913 /**
914   * @}
915   */
916
917 /** @defgroup HASH_Group4 HASH processing functions using DMA mode
918  *  @brief   processing functions using DMA mode. 
919  *
920 @verbatim   
921  ===============================================================================
922               ##### HASH processing using DMA mode functions #####
923  ===============================================================================  
924     [..]  This section provides functions allowing to calculate in DMA mode
925           the hash value using one of the following algorithms:
926       (+) MD5
927       (+) SHA1
928
929 @endverbatim
930   * @{
931   */
932
933 /**
934   * @brief  Initializes the HASH peripheral in MD5 mode then enables DMA to
935             control data transfer. Use HAL_HASH_MD5_Finish() to get the digest.
936   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
937   *         the configuration information for HASH module
938   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
939   * @param  Size: Length of the input buffer in bytes.
940   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
941   * @retval HAL status
942   */
943 HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
944 {
945   uint32_t inputaddr  = (uint32_t)pInBuffer;
946   
947    /* Process Locked */
948   __HAL_LOCK(hhash);
949   
950   /* Change the HASH state */
951   hhash->State = HAL_HASH_STATE_BUSY;
952   
953   /* Check if initialization phase has already been performed */
954   if(hhash->Phase == HAL_HASH_PHASE_READY)
955   {
956     /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute 
957        the message digest of a new message */
958     HASH->CR |= HASH_AlgoSelection_MD5 | HASH_CR_INIT;
959   }
960    
961   /* Configure the number of valid bits in last word of the message */
962   __HAL_HASH_SET_NBVALIDBITS(Size);
963   
964   /* Set the phase */
965   hhash->Phase = HAL_HASH_PHASE_PROCESS;
966     
967   /* Set the HASH DMA transfer complete callback */
968   hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
969   /* Set the DMA error callback */
970   hhash->hdmain->XferErrorCallback = HASH_DMAError;
971   
972   /* Enable the DMA In DMA Stream */
973   HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
974   
975   /* Enable DMA requests */
976   HASH->CR |= (HASH_CR_DMAE);
977   
978    /* Process Unlocked */
979   __HAL_UNLOCK(hhash);
980   
981   /* Return function status */
982   return HAL_OK;
983 }
984
985 /**
986   * @brief  Returns the computed digest in MD5 mode
987   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
988   *         the configuration information for HASH module
989   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
990   * @param  Timeout: Timeout value  
991   * @retval HAL status
992   */
993 HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
994 {
995   uint32_t tickstart = 0;   
996   
997    /* Process Locked */
998   __HAL_LOCK(hhash);
999   
1000   /* Change HASH peripheral state */
1001   hhash->State = HAL_HASH_STATE_BUSY;
1002   
1003   /* Get tick */
1004   tickstart = HAL_GetTick();
1005
1006   while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1007   {
1008     /* Check for the Timeout */
1009     if(Timeout != HAL_MAX_DELAY)
1010     {
1011       if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1012       {
1013         /* Change state */
1014         hhash->State = HAL_HASH_STATE_TIMEOUT;
1015         
1016         /* Process Unlocked */
1017         __HAL_UNLOCK(hhash);
1018         
1019         return HAL_TIMEOUT;
1020       }
1021     }
1022   }
1023   
1024   /* Read the message digest */
1025   HASH_GetDigest(pOutBuffer, 16);
1026       
1027   /* Change HASH peripheral state */
1028   hhash->State = HAL_HASH_STATE_READY;
1029   
1030    /* Process Unlocked */
1031   __HAL_UNLOCK(hhash);
1032   
1033   /* Return function status */
1034   return HAL_OK;
1035 }
1036
1037 /**
1038   * @brief  Initializes the HASH peripheral in SHA1 mode then enables DMA to
1039             control data transfer. Use HAL_HASH_SHA1_Finish() to get the digest.
1040   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1041   *         the configuration information for HASH module
1042   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1043   * @param  Size: Length of the input buffer in bytes.
1044   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1045   * @retval HAL status
1046   */
1047 HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1048 {
1049   uint32_t inputaddr  = (uint32_t)pInBuffer;
1050   
1051    /* Process Locked */
1052   __HAL_LOCK(hhash);
1053   
1054   /* Change the HASH state */
1055   hhash->State = HAL_HASH_STATE_BUSY;
1056   
1057   /* Check if initialization phase has already been performed */
1058   if(hhash->Phase == HAL_HASH_PHASE_READY)
1059   {
1060     /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute 
1061        the message digest of a new message */
1062     HASH->CR |= HASH_AlgoSelection_SHA1;
1063     HASH->CR |= HASH_CR_INIT;
1064   }
1065   
1066   /* Configure the number of valid bits in last word of the message */
1067   __HAL_HASH_SET_NBVALIDBITS(Size);
1068   
1069   /* Set the phase */
1070   hhash->Phase = HAL_HASH_PHASE_PROCESS;
1071   
1072   /* Set the HASH DMA transfer complete callback */
1073   hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1074   /* Set the DMA error callback */
1075   hhash->hdmain->XferErrorCallback = HASH_DMAError;
1076   
1077   /* Enable the DMA In DMA Stream */
1078   HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
1079   
1080   /* Enable DMA requests */
1081   HASH->CR |= (HASH_CR_DMAE);
1082   
1083    /* Process Unlocked */
1084   __HAL_UNLOCK(hhash);
1085   
1086   /* Return function status */
1087   return HAL_OK;
1088 }
1089
1090 /**
1091   * @brief  Returns the computed digest in SHA1 mode.
1092   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1093   *         the configuration information for HASH module
1094   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.  
1095   * @param  Timeout: Timeout value    
1096   * @retval HAL status
1097   */
1098 HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1099 {
1100   uint32_t tickstart = 0;   
1101   
1102    /* Process Locked */
1103   __HAL_LOCK(hhash);
1104   
1105   /* Change HASH peripheral state */
1106   hhash->State = HAL_HASH_STATE_BUSY;
1107   
1108   /* Get tick */
1109   tickstart = HAL_GetTick();
1110   while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1111   {
1112     /* Check for the Timeout */
1113     if(Timeout != HAL_MAX_DELAY)
1114     {
1115       if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1116       {
1117         /* Change state */
1118         hhash->State = HAL_HASH_STATE_TIMEOUT;
1119         
1120         /* Process Unlocked */
1121         __HAL_UNLOCK(hhash);
1122         
1123         return HAL_TIMEOUT;
1124       }
1125     }
1126   }
1127   
1128   /* Read the message digest */
1129   HASH_GetDigest(pOutBuffer, 20);
1130   
1131   /* Change HASH peripheral state */
1132   hhash->State = HAL_HASH_STATE_READY;
1133   
1134    /* Process UnLock */
1135   __HAL_UNLOCK(hhash);
1136   
1137   /* Return function status */
1138   return HAL_OK;
1139 }
1140
1141
1142 /**
1143   * @}
1144   */
1145
1146 /** @defgroup HASH_Group5 HASH-MAC (HMAC) processing functions using polling mode 
1147  *  @brief   HMAC processing functions using polling mode . 
1148  *
1149 @verbatim   
1150  ===============================================================================
1151               ##### HMAC processing using polling mode functions #####
1152  ===============================================================================  
1153     [..]  This section provides functions allowing to calculate in polling mode
1154           the HMAC value using one of the following algorithms:
1155       (+) MD5
1156       (+) SHA1
1157
1158 @endverbatim
1159   * @{
1160   */
1161
1162 /**
1163   * @brief  Initializes the HASH peripheral in HMAC MD5 mode
1164   *         then processes pInBuffer. The digest is available in pOutBuffer
1165   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1166   *         the configuration information for HASH module
1167   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1168   * @param  Size: Length of the input buffer in bytes.
1169   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1170   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1171   * @param  Timeout: Timeout value  
1172   * @retval HAL status
1173   */
1174 HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1175 {
1176   uint32_t tickstart = 0;   
1177   
1178    /* Process Locked */
1179   __HAL_LOCK(hhash);
1180   
1181   /* Change the HASH state */
1182   hhash->State = HAL_HASH_STATE_BUSY;
1183   
1184   /* Check if initialization phase has already been performed */
1185   if(hhash->Phase == HAL_HASH_PHASE_READY)
1186   {
1187     /* Check if key size is greater than 64 bytes */
1188     if(hhash->Init.KeySize > 64)
1189     {
1190       /* Select the HMAC MD5 mode */
1191       HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey | HASH_CR_INIT);
1192     }
1193     else
1194     {
1195       /* Select the HMAC MD5 mode */
1196       HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HMAC | HASH_CR_INIT);
1197     }
1198   }
1199   
1200   /* Set the phase */
1201   hhash->Phase = HAL_HASH_PHASE_PROCESS;
1202   
1203   /************************** STEP 1 ******************************************/
1204   /* Configure the number of valid bits in last word of the message */
1205   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1206   
1207   /* Write input buffer in data register */
1208   HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1209   
1210   /* Start the digest calculation */
1211   __HAL_HASH_START_DIGEST();
1212   
1213   /* Get tick */
1214   tickstart = HAL_GetTick();
1215
1216   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1217   {
1218     /* Check for the Timeout */
1219     if(Timeout != HAL_MAX_DELAY)
1220     {
1221       if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1222       {
1223         /* Change state */
1224         hhash->State = HAL_HASH_STATE_TIMEOUT;
1225         
1226         /* Process Unlocked */
1227         __HAL_UNLOCK(hhash);
1228         
1229         return HAL_TIMEOUT;
1230       }
1231     }
1232   }
1233   /************************** STEP 2 ******************************************/
1234   /* Configure the number of valid bits in last word of the message */
1235   __HAL_HASH_SET_NBVALIDBITS(Size);
1236   
1237   /* Write input buffer in data register */
1238   HASH_WriteData(pInBuffer, Size);
1239   
1240   /* Start the digest calculation */
1241   __HAL_HASH_START_DIGEST();
1242   
1243   /* Get tick */
1244   tickstart = HAL_GetTick();
1245   
1246   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1247   {
1248     /* Check for the Timeout */
1249     if(Timeout != HAL_MAX_DELAY)
1250     {
1251       if((HAL_GetTick() - tickstart ) > Timeout)
1252       {
1253         /* Change state */
1254         hhash->State = HAL_HASH_STATE_TIMEOUT;
1255         
1256         /* Process Unlocked */
1257         __HAL_UNLOCK(hhash);
1258         
1259         return HAL_TIMEOUT;
1260       }
1261     }
1262   }
1263   /************************** STEP 3 ******************************************/
1264   /* Configure the number of valid bits in last word of the message */
1265   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1266   
1267   /* Write input buffer in data register */
1268   HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1269   
1270   /* Start the digest calculation */
1271   __HAL_HASH_START_DIGEST();
1272   
1273   /* Get tick */
1274   tickstart = HAL_GetTick();
1275   
1276   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1277   {
1278     /* Check for the Timeout */
1279     if(Timeout != HAL_MAX_DELAY)
1280     {
1281       if((HAL_GetTick() - tickstart ) > Timeout)
1282       {
1283         /* Change state */
1284         hhash->State = HAL_HASH_STATE_TIMEOUT;
1285         
1286         /* Process Unlocked */
1287         __HAL_UNLOCK(hhash);
1288         
1289         return HAL_TIMEOUT;
1290       }
1291     }
1292   }
1293   
1294   /* Read the message digest */
1295   HASH_GetDigest(pOutBuffer, 16);
1296   
1297   /* Change the HASH state */
1298   hhash->State = HAL_HASH_STATE_READY;
1299   
1300   /* Process Unlocked */
1301   __HAL_UNLOCK(hhash);
1302   
1303   /* Return function status */
1304   return HAL_OK;
1305 }
1306
1307 /**
1308   * @brief  Initializes the HASH peripheral in HMAC SHA1 mode
1309   *         then processes pInBuffer. The digest is available in pOutBuffer.
1310   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1311   *         the configuration information for HASH module
1312   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1313   * @param   Size: Length of the input buffer in bytes.
1314   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1315   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1316   * @param  Timeout: Timeout value  
1317   * @retval HAL status
1318   */
1319 HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1320 {
1321   uint32_t tickstart = 0;   
1322   
1323   /* Process Locked */
1324   __HAL_LOCK(hhash);
1325   
1326   /* Change the HASH state */
1327   hhash->State = HAL_HASH_STATE_BUSY;
1328   
1329   /* Check if initialization phase has already been performed */
1330   if(hhash->Phase == HAL_HASH_PHASE_READY)
1331   {
1332     /* Check if key size is greater than 64 bytes */
1333     if(hhash->Init.KeySize > 64)
1334     {
1335       /* Select the HMAC SHA1 mode */
1336       HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey | HASH_CR_INIT);
1337     }
1338     else
1339     {
1340       /* Select the HMAC SHA1 mode */
1341       HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HMAC | HASH_CR_INIT);
1342     }
1343   }
1344   
1345   /* Set the phase */
1346   hhash->Phase = HAL_HASH_PHASE_PROCESS;
1347   
1348   /************************** STEP 1 ******************************************/
1349   /* Configure the number of valid bits in last word of the message */
1350   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1351   
1352   /* Write input buffer in data register */
1353   HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1354   
1355   /* Start the digest calculation */
1356   __HAL_HASH_START_DIGEST();
1357   
1358   /* Get tick */
1359   tickstart = HAL_GetTick();
1360   
1361   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1362   {
1363     /* Check for the Timeout */
1364     if(Timeout != HAL_MAX_DELAY)
1365     {
1366       if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1367       {
1368         /* Change state */
1369         hhash->State = HAL_HASH_STATE_TIMEOUT;
1370         
1371         /* Process Unlocked */
1372         __HAL_UNLOCK(hhash);
1373         
1374         return HAL_TIMEOUT;
1375       }
1376     }
1377   }
1378   /************************** STEP 2 ******************************************/
1379   /* Configure the number of valid bits in last word of the message */  
1380   __HAL_HASH_SET_NBVALIDBITS(Size);
1381   
1382   /* Write input buffer in data register */
1383   HASH_WriteData(pInBuffer, Size);
1384   
1385   /* Start the digest calculation */
1386   __HAL_HASH_START_DIGEST();
1387   
1388   /* Get tick */
1389   tickstart = HAL_GetTick();
1390   
1391   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1392   {
1393     /* Check for the Timeout */
1394     if(Timeout != HAL_MAX_DELAY)
1395     {
1396       if((HAL_GetTick() - tickstart ) > Timeout)
1397       {
1398         /* Change state */
1399         hhash->State = HAL_HASH_STATE_TIMEOUT;
1400         
1401         /* Process Unlocked */
1402         __HAL_UNLOCK(hhash);
1403         
1404         return HAL_TIMEOUT;
1405       }
1406     }
1407   }
1408   /************************** STEP 3 ******************************************/
1409   /* Configure the number of valid bits in last word of the message */
1410   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1411   
1412   /* Write input buffer in data register */
1413   HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1414   
1415   /* Start the digest calculation */
1416   __HAL_HASH_START_DIGEST();
1417   
1418   /* Get tick */
1419   tickstart = HAL_GetTick();
1420
1421   while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1422   {
1423     /* Check for the Timeout */
1424     if(Timeout != HAL_MAX_DELAY)
1425     {
1426       if((HAL_GetTick() - tickstart ) > Timeout)
1427       {
1428         /* Change state */
1429         hhash->State = HAL_HASH_STATE_TIMEOUT;
1430         
1431         /* Process Unlocked */
1432         __HAL_UNLOCK(hhash);
1433         
1434         return HAL_TIMEOUT;
1435       }
1436     }
1437   }
1438   /* Read the message digest */
1439   HASH_GetDigest(pOutBuffer, 20);
1440   
1441   /* Change the HASH state */
1442   hhash->State = HAL_HASH_STATE_READY;
1443   
1444   /* Process Unlocked */
1445   __HAL_UNLOCK(hhash);
1446   
1447   /* Return function status */
1448   return HAL_OK;
1449 }
1450
1451 /**
1452   * @}
1453   */
1454
1455 /** @defgroup HASH_Group6 HASH-MAC (HMAC) processing functions using DMA mode 
1456  *  @brief   HMAC processing functions using DMA mode . 
1457  *
1458 @verbatim   
1459  ===============================================================================
1460                 ##### HMAC processing using DMA mode functions #####
1461  ===============================================================================  
1462     [..]  This section provides functions allowing to calculate in DMA mode
1463           the HMAC value using one of the following algorithms:
1464       (+) MD5
1465       (+) SHA1
1466
1467 @endverbatim
1468   * @{
1469   */
1470
1471 /**
1472   * @brief  Initializes the HASH peripheral in HMAC MD5 mode
1473   *         then enables DMA to control data transfer.
1474   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1475   *         the configuration information for HASH module
1476   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1477   * @param  Size: Length of the input buffer in bytes.
1478   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1479   * @retval HAL status
1480   */
1481 HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1482 {
1483   uint32_t inputaddr  = 0;
1484   
1485    /* Process Locked */
1486   __HAL_LOCK(hhash);
1487   
1488   /* Change the HASH state */
1489   hhash->State = HAL_HASH_STATE_BUSY;
1490   
1491   /* Save buffer pointer and size in handle */
1492   hhash->pHashInBuffPtr = pInBuffer;
1493   hhash->HashBuffSize = Size;
1494   hhash->HashInCount = 0;
1495   
1496   /* Check if initialization phase has already been performed */
1497   if(hhash->Phase == HAL_HASH_PHASE_READY)
1498   {
1499     /* Check if key size is greater than 64 bytes */
1500     if(hhash->Init.KeySize > 64)
1501     {
1502       /* Select the HMAC MD5 mode */
1503       HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey | HASH_CR_INIT);
1504     }
1505     else
1506     {
1507       /* Select the HMAC MD5 mode */
1508       HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HMAC | HASH_CR_INIT);
1509     }
1510   }
1511   
1512   /* Set the phase */
1513   hhash->Phase = HAL_HASH_PHASE_PROCESS;
1514   
1515   /* Configure the number of valid bits in last word of the message */
1516   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1517   
1518   /* Get the key address */
1519   inputaddr = (uint32_t)(hhash->Init.pKey);
1520   
1521   /* Set the HASH DMA transfer complete callback */
1522   hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1523   /* Set the DMA error callback */
1524   hhash->hdmain->XferErrorCallback = HASH_DMAError;
1525   
1526   /* Enable the DMA In DMA Stream */
1527   HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
1528   /* Enable DMA requests */
1529   HASH->CR |= (HASH_CR_DMAE);
1530   
1531   /* Process Unlocked */
1532   __HAL_UNLOCK(hhash);
1533   
1534   /* Return function status */
1535   return HAL_OK;
1536 }
1537
1538 /**
1539   * @brief  Initializes the HASH peripheral in HMAC SHA1 mode
1540   *         then enables DMA to control data transfer.
1541   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1542   *         the configuration information for HASH module
1543   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1544   * @param  Size: Length of the input buffer in bytes.
1545   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1546   * @retval HAL status
1547   */
1548 HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1549 {
1550   uint32_t inputaddr  = 0;
1551   
1552   /* Process Locked */
1553   __HAL_LOCK(hhash);
1554   
1555   /* Change the HASH state */
1556   hhash->State = HAL_HASH_STATE_BUSY;
1557   
1558   /* Save buffer pointer and size in handle */
1559   hhash->pHashInBuffPtr = pInBuffer;
1560   hhash->HashBuffSize = Size;
1561   hhash->HashInCount = 0;
1562   
1563   /* Check if initialization phase has already been performed */
1564   if(hhash->Phase == HAL_HASH_PHASE_READY)
1565   {
1566     /* Check if key size is greater than 64 bytes */
1567     if(hhash->Init.KeySize > 64)
1568     {
1569       /* Select the HMAC SHA1 mode */
1570       HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey | HASH_CR_INIT);
1571     }
1572     else
1573     {
1574       /* Select the HMAC SHA1 mode */
1575       HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HMAC | HASH_CR_INIT);
1576     }
1577   }
1578   
1579   /* Set the phase */
1580   hhash->Phase = HAL_HASH_PHASE_PROCESS;
1581   
1582   /* Configure the number of valid bits in last word of the message */
1583   __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1584   
1585   /* Get the key address */
1586   inputaddr = (uint32_t)(hhash->Init.pKey);
1587   
1588   /* Set the HASH DMA transfer complete callback */
1589   hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1590   /* Set the DMA error callback */
1591   hhash->hdmain->XferErrorCallback = HASH_DMAError;
1592   
1593   /* Enable the DMA In DMA Stream */
1594   HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
1595   /* Enable DMA requests */
1596   HASH->CR |= (HASH_CR_DMAE);
1597   
1598   /* Process Unlocked */
1599   __HAL_UNLOCK(hhash);
1600   
1601   /* Return function status */
1602   return HAL_OK;
1603 }
1604
1605 /**
1606   * @}
1607   */
1608
1609 /** @defgroup HASH_Group7 Peripheral State functions 
1610  *  @brief   Peripheral State functions. 
1611  *
1612 @verbatim   
1613  ===============================================================================
1614                       ##### Peripheral State functions #####
1615  ===============================================================================  
1616     [..]
1617     This subsection permits to get in run-time the status of the peripheral.
1618
1619 @endverbatim
1620   * @{
1621   */
1622
1623 /**
1624   * @brief return the HASH state
1625   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1626   *         the configuration information for HASH module
1627   * @retval HAL state
1628   */
1629 HAL_HASH_STATETypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
1630 {
1631   return hhash->State;
1632 }
1633
1634 /**
1635   * @}
1636   */
1637
1638 /**
1639   * @brief  DMA HASH Input Data complete callback. 
1640   * @param  hdma: DMA handle
1641   * @retval None
1642   */
1643 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
1644 {
1645   HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1646   uint32_t inputaddr = 0;
1647   uint32_t buffersize = 0;
1648   
1649   if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
1650   {
1651     /* Disable the DMA transfer */
1652     HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
1653     
1654     /* Change HASH peripheral state */
1655     hhash->State = HAL_HASH_STATE_READY;
1656     
1657     /* Call Input data transfer complete callback */
1658     HAL_HASH_InCpltCallback(hhash);
1659   }
1660   else
1661   {
1662     /* Increment Interrupt counter */
1663     hhash->HashInCount++;
1664     /* Disable the DMA transfer before starting the next transfer */
1665     HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
1666     
1667     if(hhash->HashInCount <= 2)
1668     {
1669       /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
1670       if(hhash->HashInCount == 1)
1671       {
1672         inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1673         buffersize = hhash->HashBuffSize;
1674       }
1675       /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
1676       else if(hhash->HashInCount == 2)
1677       {
1678         inputaddr = (uint32_t)hhash->Init.pKey;
1679         buffersize = hhash->Init.KeySize;
1680       }
1681       /* Configure the number of valid bits in last word of the message */
1682       HASH->STR |= 8 * (buffersize % 4);
1683       
1684       /* Set the HASH DMA transfer complete */
1685       hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1686       
1687       /* Enable the DMA In DMA Stream */
1688       HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4 ? (buffersize+3)/4:buffersize/4));
1689       
1690       /* Enable DMA requests */
1691       HASH->CR |= (HASH_CR_DMAE);
1692     }
1693     else
1694     {
1695       /* Disable the DMA transfer */
1696       HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
1697       
1698       /* Reset the InCount */
1699       hhash->HashInCount = 0;
1700       
1701       /* Change HASH peripheral state */
1702       hhash->State = HAL_HASH_STATE_READY;
1703       
1704       /* Call Input data transfer complete callback */
1705       HAL_HASH_InCpltCallback(hhash);
1706     }
1707   }
1708 }
1709
1710 /**
1711   * @brief  DMA HASH communication error callback. 
1712   * @param  hdma: DMA handle
1713   * @retval None
1714   */
1715 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
1716 {
1717   HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1718   hhash->State= HAL_HASH_STATE_READY;
1719   HAL_HASH_ErrorCallback(hhash);
1720 }
1721
1722 /**
1723   * @brief  Writes the input buffer in data register.
1724   * @param  pInBuffer: Pointer to input buffer
1725   * @param  Size: The size of input buffer
1726   * @retval None
1727   */
1728 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size)
1729 {
1730   uint32_t buffercounter;
1731   uint32_t inputaddr = (uint32_t) pInBuffer;
1732   
1733   for(buffercounter = 0; buffercounter < Size; buffercounter+=4)
1734   {
1735     HASH->DIN = *(uint32_t*)inputaddr;
1736     inputaddr+=4;
1737   }
1738 }
1739
1740 /**
1741   * @brief  Provides the message digest result.
1742   * @param  pMsgDigest: Pointer to the message digest
1743   * @param  Size: The size of the message digest in bytes
1744   * @retval None
1745   */
1746 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
1747 {
1748   uint32_t msgdigest = (uint32_t)pMsgDigest;
1749   
1750   switch(Size)
1751   {
1752   case 16:
1753     /* Read the message digest */
1754     *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1755     msgdigest+=4;
1756     *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1757     msgdigest+=4;
1758     *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1759     msgdigest+=4;
1760     *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1761     break;
1762   case 20:
1763     /* Read the message digest */
1764     *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1765     msgdigest+=4;
1766     *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1767     msgdigest+=4;
1768     *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1769     msgdigest+=4;
1770     *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1771     msgdigest+=4;
1772     *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1773     break;
1774   case 28:
1775     /* Read the message digest */
1776     *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1777     msgdigest+=4;
1778     *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1779     msgdigest+=4;
1780     *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1781     msgdigest+=4;
1782     *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1783     msgdigest+=4;
1784     *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1785     msgdigest+=4;
1786     *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
1787     msgdigest+=4;
1788     *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
1789     break;
1790   case 32:
1791     /* Read the message digest */
1792     *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1793     msgdigest+=4;
1794     *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1795     msgdigest+=4;
1796     *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1797     msgdigest+=4;
1798     *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1799     msgdigest+=4;
1800     *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1801     msgdigest+=4;
1802     *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
1803     msgdigest+=4;
1804     *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
1805     msgdigest+=4;
1806     *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
1807     break;
1808   default:
1809     break;
1810   }
1811 }
1812
1813 /**
1814   * @}
1815   */
1816 #endif /* STM32F415xx || STM32F417xx || STM32F437xx || STM32F439xx */
1817 #endif /* HAL_HASH_MODULE_ENABLED */
1818 /**
1819   * @}
1820   */
1821
1822 /**
1823   * @}
1824   */
1825
1826 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/