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