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