38
|
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****/
|