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