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