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