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