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