STM32F439xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_hash_ex.c 00004 * @author MCD Application Team 00005 * @brief HASH HAL Extension module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of HASH peripheral: 00008 * + Extended HASH processing functions based on SHA224 Algorithm 00009 * + Extended HASH processing functions based on SHA256 Algorithm 00010 * 00011 @verbatim 00012 ============================================================================== 00013 ##### How to use this driver ##### 00014 ============================================================================== 00015 [..] 00016 The HASH HAL driver can be used as follows: 00017 (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit(): 00018 (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE() 00019 (##) In case of using processing APIs based on interrupts (e.g. HAL_HMACEx_SHA224_Start()) 00020 (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority() 00021 (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ() 00022 (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler() 00023 (##) In case of using DMA to control data transfer (e.g. HAL_HMACEx_SH224_Start_DMA()) 00024 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE() 00025 (+++) Configure and enable one DMA stream one for managing data transfer from 00026 memory to peripheral (input stream). Managing data transfer from 00027 peripheral to memory can be performed only using CPU 00028 (+++) Associate the initialized DMA handle to the HASH DMA handle 00029 using __HAL_LINKDMA() 00030 (+++) Configure the priority and enable the NVIC for the transfer complete 00031 interrupt on the DMA Stream: HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ() 00032 (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly: 00033 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit. 00034 (##) For HMAC, the encryption key. 00035 (##) For HMAC, the key size used for encryption. 00036 (#)Three processing functions are available: 00037 (##) Polling mode: processing APIs are blocking functions 00038 i.e. they process the data and wait till the digest computation is finished 00039 e.g. HAL_HASHEx_SHA224_Start() 00040 (##) Interrupt mode: encryption and decryption APIs are not blocking functions 00041 i.e. they process the data under interrupt 00042 e.g. HAL_HASHEx_SHA224_Start_IT() 00043 (##) DMA mode: processing APIs are not blocking functions and the CPU is 00044 not used for data transfer i.e. the data transfer is ensured by DMA 00045 e.g. HAL_HASHEx_SHA224_Start_DMA() 00046 (#)When the processing function is called at first time after HAL_HASH_Init() 00047 the HASH peripheral is initialized and processes the buffer in input. 00048 After that, the digest computation is started. 00049 When processing multi-buffer use the accumulate function to write the 00050 data in the peripheral without starting the digest computation. In last 00051 buffer use the start function to input the last buffer ans start the digest 00052 computation. 00053 (##) e.g. HAL_HASHEx_SHA224_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation 00054 (##) write (n-1)th data buffer in the peripheral without starting the digest computation 00055 (##) HAL_HASHEx_SHA224_Start() : write (n)th data buffer in the peripheral and start the digest computation 00056 (#)In HMAC mode, there is no Accumulate API. Only Start API is available. 00057 (#)In case of using DMA, call the DMA start processing e.g. HAL_HASHEx_SHA224_Start_DMA(). 00058 After that, call the finish function in order to get the digest value 00059 e.g. HAL_HASHEx_SHA224_Finish() 00060 (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral. 00061 00062 @endverbatim 00063 ****************************************************************************** 00064 * @attention 00065 * 00066 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00067 * 00068 * Redistribution and use in source and binary forms, with or without modification, 00069 * are permitted provided that the following conditions are met: 00070 * 1. Redistributions of source code must retain the above copyright notice, 00071 * this list of conditions and the following disclaimer. 00072 * 2. Redistributions in binary form must reproduce the above copyright notice, 00073 * this list of conditions and the following disclaimer in the documentation 00074 * and/or other materials provided with the distribution. 00075 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00076 * may be used to endorse or promote products derived from this software 00077 * without specific prior written permission. 00078 * 00079 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00080 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00081 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00082 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00083 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00084 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00085 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00086 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00087 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00088 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00089 * 00090 ****************************************************************************** 00091 */ 00092 00093 /* Includes ------------------------------------------------------------------*/ 00094 #include "stm32f4xx_hal.h" 00095 00096 /** @addtogroup STM32F4xx_HAL_Driver 00097 * @{ 00098 */ 00099 00100 /** @defgroup HASHEx HASHEx 00101 * @brief HASH Extension HAL module driver. 00102 * @{ 00103 */ 00104 00105 #ifdef HAL_HASH_MODULE_ENABLED 00106 00107 #if defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F479xx) 00108 00109 /* Private typedef -----------------------------------------------------------*/ 00110 /* Private define ------------------------------------------------------------*/ 00111 /* Private macro -------------------------------------------------------------*/ 00112 /* Private variables ---------------------------------------------------------*/ 00113 /* Private function prototypes -----------------------------------------------*/ 00114 /** @addtogroup HASHEx_Private_Functions 00115 * @{ 00116 */ 00117 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma); 00118 static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size); 00119 static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size); 00120 static void HASHEx_DMAError(DMA_HandleTypeDef *hdma); 00121 /** 00122 * @} 00123 */ 00124 00125 /* Private functions ---------------------------------------------------------*/ 00126 00127 /** @addtogroup HASHEx_Private_Functions 00128 * @{ 00129 */ 00130 00131 /** 00132 * @brief Writes the input buffer in data register. 00133 * @param pInBuffer Pointer to input buffer 00134 * @param Size The size of input buffer 00135 * @retval None 00136 */ 00137 static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size) 00138 { 00139 uint32_t buffercounter; 00140 uint32_t inputaddr = (uint32_t) pInBuffer; 00141 00142 for(buffercounter = 0U; buffercounter < Size; buffercounter+=4U) 00143 { 00144 HASH->DIN = *(uint32_t*)inputaddr; 00145 inputaddr+=4U; 00146 } 00147 } 00148 00149 /** 00150 * @brief Provides the message digest result. 00151 * @param pMsgDigest Pointer to the message digest 00152 * @param Size The size of the message digest in bytes 00153 * @retval None 00154 */ 00155 static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size) 00156 { 00157 uint32_t msgdigest = (uint32_t)pMsgDigest; 00158 00159 switch(Size) 00160 { 00161 case 16U: 00162 /* Read the message digest */ 00163 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]); 00164 msgdigest+=4U; 00165 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]); 00166 msgdigest+=4U; 00167 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]); 00168 msgdigest+=4U; 00169 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]); 00170 break; 00171 case 20U: 00172 /* Read the message digest */ 00173 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]); 00174 msgdigest+=4U; 00175 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]); 00176 msgdigest+=4U; 00177 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]); 00178 msgdigest+=4U; 00179 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]); 00180 msgdigest+=4U; 00181 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]); 00182 break; 00183 case 28U: 00184 /* Read the message digest */ 00185 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]); 00186 msgdigest+=4U; 00187 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]); 00188 msgdigest+=4U; 00189 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]); 00190 msgdigest+=4U; 00191 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]); 00192 msgdigest+=4U; 00193 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]); 00194 msgdigest+=4U; 00195 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5U]); 00196 msgdigest+=4U; 00197 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6U]); 00198 break; 00199 case 32U: 00200 /* Read the message digest */ 00201 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]); 00202 msgdigest+=4U; 00203 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]); 00204 msgdigest+=4U; 00205 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]); 00206 msgdigest+=4U; 00207 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]); 00208 msgdigest+=4U; 00209 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]); 00210 msgdigest+=4U; 00211 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5U]); 00212 msgdigest+=4U; 00213 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6U]); 00214 msgdigest+=4U; 00215 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7U]); 00216 break; 00217 default: 00218 break; 00219 } 00220 } 00221 00222 /** 00223 * @brief DMA HASH Input Data complete callback. 00224 * @param hdma DMA handle 00225 * @retval None 00226 */ 00227 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma) 00228 { 00229 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 00230 uint32_t inputaddr = 0U; 00231 uint32_t buffersize = 0U; 00232 00233 if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE) 00234 { 00235 /* Disable the DMA transfer */ 00236 HASH->CR &= (uint32_t)(~HASH_CR_DMAE); 00237 00238 /* Change HASH peripheral state */ 00239 hhash->State = HAL_HASH_STATE_READY; 00240 00241 /* Call Input data transfer complete callback */ 00242 HAL_HASH_InCpltCallback(hhash); 00243 } 00244 else 00245 { 00246 /* Increment Interrupt counter */ 00247 hhash->HashInCount++; 00248 /* Disable the DMA transfer before starting the next transfer */ 00249 HASH->CR &= (uint32_t)(~HASH_CR_DMAE); 00250 00251 if(hhash->HashInCount <= 2U) 00252 { 00253 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */ 00254 if(hhash->HashInCount == 1U) 00255 { 00256 inputaddr = (uint32_t)hhash->pHashInBuffPtr; 00257 buffersize = hhash->HashBuffSize; 00258 } 00259 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */ 00260 else if(hhash->HashInCount == 2U) 00261 { 00262 inputaddr = (uint32_t)hhash->Init.pKey; 00263 buffersize = hhash->Init.KeySize; 00264 } 00265 /* Configure the number of valid bits in last word of the message */ 00266 MODIFY_REG(HASH->STR, HASH_STR_NBLW, 8U * (buffersize % 4U)); 00267 00268 /* Set the HASH DMA transfer complete */ 00269 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt; 00270 00271 /* Enable the DMA In DMA Stream */ 00272 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4U ? (buffersize+3U)/4U:buffersize/4U)); 00273 00274 /* Enable DMA requests */ 00275 HASH->CR |= (HASH_CR_DMAE); 00276 } 00277 else 00278 { 00279 /* Disable the DMA transfer */ 00280 HASH->CR &= (uint32_t)(~HASH_CR_DMAE); 00281 00282 /* Reset the InCount */ 00283 hhash->HashInCount = 0U; 00284 00285 /* Change HASH peripheral state */ 00286 hhash->State = HAL_HASH_STATE_READY; 00287 00288 /* Call Input data transfer complete callback */ 00289 HAL_HASH_InCpltCallback(hhash); 00290 } 00291 } 00292 } 00293 00294 /** 00295 * @brief DMA HASH communication error callback. 00296 * @param hdma DMA handle 00297 * @retval None 00298 */ 00299 static void HASHEx_DMAError(DMA_HandleTypeDef *hdma) 00300 { 00301 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 00302 hhash->State= HAL_HASH_STATE_READY; 00303 HAL_HASH_ErrorCallback(hhash); 00304 } 00305 00306 /** 00307 * @} 00308 */ 00309 00310 /* Exported functions --------------------------------------------------------*/ 00311 /** @addtogroup HASHEx_Exported_Functions 00312 * @{ 00313 */ 00314 00315 /** @defgroup HASHEx_Group1 HASH processing functions 00316 * @brief processing functions using polling mode 00317 * 00318 @verbatim 00319 =============================================================================== 00320 ##### HASH processing using polling mode functions ##### 00321 =============================================================================== 00322 [..] This section provides functions allowing to calculate in polling mode 00323 the hash value using one of the following algorithms: 00324 (+) SHA224 00325 (+) SHA256 00326 00327 @endverbatim 00328 * @{ 00329 */ 00330 00331 /** 00332 * @brief Initializes the HASH peripheral in SHA224 mode 00333 * then processes pInBuffer. The digest is available in pOutBuffer 00334 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 00335 * the configuration information for HASH module 00336 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 00337 * @param Size Length of the input buffer in bytes. 00338 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 00339 * @param pOutBuffer Pointer to the computed digest. Its size must be 28 bytes. 00340 * @param Timeout Specify Timeout value 00341 * @retval HAL status 00342 */ 00343 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout) 00344 { 00345 uint32_t tickstart = 0U; 00346 00347 /* Process Locked */ 00348 __HAL_LOCK(hhash); 00349 00350 /* Change the HASH state */ 00351 hhash->State = HAL_HASH_STATE_BUSY; 00352 00353 /* Check if initialization phase has already been performed */ 00354 if(hhash->Phase == HAL_HASH_PHASE_READY) 00355 { 00356 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute 00357 the message digest of a new message */ 00358 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT; 00359 } 00360 00361 /* Set the phase */ 00362 hhash->Phase = HAL_HASH_PHASE_PROCESS; 00363 00364 /* Configure the number of valid bits in last word of the message */ 00365 __HAL_HASH_SET_NBVALIDBITS(Size); 00366 00367 /* Write input buffer in data register */ 00368 HASHEx_WriteData(pInBuffer, Size); 00369 00370 /* Start the digest calculation */ 00371 __HAL_HASH_START_DIGEST(); 00372 00373 /* Get tick */ 00374 tickstart = HAL_GetTick(); 00375 00376 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY) 00377 { 00378 /* Check for the Timeout */ 00379 if(Timeout != HAL_MAX_DELAY) 00380 { 00381 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00382 { 00383 /* Change state */ 00384 hhash->State = HAL_HASH_STATE_TIMEOUT; 00385 00386 /* Process Unlocked */ 00387 __HAL_UNLOCK(hhash); 00388 00389 return HAL_TIMEOUT; 00390 } 00391 } 00392 } 00393 00394 /* Read the message digest */ 00395 HASHEx_GetDigest(pOutBuffer, 28U); 00396 00397 /* Change the HASH state */ 00398 hhash->State = HAL_HASH_STATE_READY; 00399 00400 /* Process Unlocked */ 00401 __HAL_UNLOCK(hhash); 00402 00403 /* Return function status */ 00404 return HAL_OK; 00405 } 00406 00407 /** 00408 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer. 00409 The digest is available in pOutBuffer. 00410 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 00411 * the configuration information for HASH module 00412 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 00413 * @param Size Length of the input buffer in bytes. 00414 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 00415 * @param pOutBuffer Pointer to the computed digest. Its size must be 32 bytes. 00416 * @param Timeout Specify Timeout value 00417 * @retval HAL status 00418 */ 00419 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout) 00420 { 00421 uint32_t tickstart = 0U; 00422 00423 /* Process Locked */ 00424 __HAL_LOCK(hhash); 00425 00426 /* Change the HASH state */ 00427 hhash->State = HAL_HASH_STATE_BUSY; 00428 00429 /* Check if initialization phase has already been performed */ 00430 if(hhash->Phase == HAL_HASH_PHASE_READY) 00431 { 00432 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute 00433 the message digest of a new message */ 00434 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT; 00435 } 00436 00437 /* Set the phase */ 00438 hhash->Phase = HAL_HASH_PHASE_PROCESS; 00439 00440 /* Configure the number of valid bits in last word of the message */ 00441 __HAL_HASH_SET_NBVALIDBITS(Size); 00442 00443 /* Write input buffer in data register */ 00444 HASHEx_WriteData(pInBuffer, Size); 00445 00446 /* Start the digest calculation */ 00447 __HAL_HASH_START_DIGEST(); 00448 00449 /* Get tick */ 00450 tickstart = HAL_GetTick(); 00451 00452 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY) 00453 { 00454 /* Check for the Timeout */ 00455 if(Timeout != HAL_MAX_DELAY) 00456 { 00457 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00458 { 00459 /* Change state */ 00460 hhash->State = HAL_HASH_STATE_TIMEOUT; 00461 00462 /* Process Unlocked */ 00463 __HAL_UNLOCK(hhash); 00464 00465 return HAL_TIMEOUT; 00466 } 00467 } 00468 } 00469 00470 /* Read the message digest */ 00471 HASHEx_GetDigest(pOutBuffer, 32U); 00472 00473 /* Change the HASH state */ 00474 hhash->State = HAL_HASH_STATE_READY; 00475 00476 /* Process Unlocked */ 00477 __HAL_UNLOCK(hhash); 00478 00479 /* Return function status */ 00480 return HAL_OK; 00481 } 00482 00483 00484 /** 00485 * @brief Initializes the HASH peripheral in SHA224 mode 00486 * then processes pInBuffer. The digest is available in pOutBuffer 00487 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 00488 * the configuration information for HASH module 00489 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 00490 * @param Size Length of the input buffer in bytes. 00491 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 00492 * @retval HAL status 00493 */ 00494 HAL_StatusTypeDef HAL_HASHEx_SHA224_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) 00495 { 00496 /* Process Locked */ 00497 __HAL_LOCK(hhash); 00498 00499 /* Change the HASH state */ 00500 hhash->State = HAL_HASH_STATE_BUSY; 00501 00502 /* Check if initialization phase has already been performed */ 00503 if(hhash->Phase == HAL_HASH_PHASE_READY) 00504 { 00505 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute 00506 the message digest of a new message */ 00507 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT; 00508 } 00509 00510 /* Set the phase */ 00511 hhash->Phase = HAL_HASH_PHASE_PROCESS; 00512 00513 /* Configure the number of valid bits in last word of the message */ 00514 __HAL_HASH_SET_NBVALIDBITS(Size); 00515 00516 /* Write input buffer in data register */ 00517 HASHEx_WriteData(pInBuffer, Size); 00518 00519 /* Change the HASH state */ 00520 hhash->State = HAL_HASH_STATE_READY; 00521 00522 /* Process Unlocked */ 00523 __HAL_UNLOCK(hhash); 00524 00525 /* Return function status */ 00526 return HAL_OK; 00527 } 00528 00529 00530 /** 00531 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer. 00532 The digest is available in pOutBuffer. 00533 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 00534 * the configuration information for HASH module 00535 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 00536 * @param Size Length of the input buffer in bytes. 00537 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 00538 * @retval HAL status 00539 */ 00540 HAL_StatusTypeDef HAL_HASHEx_SHA256_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) 00541 { 00542 /* Process Locked */ 00543 __HAL_LOCK(hhash); 00544 00545 /* Change the HASH state */ 00546 hhash->State = HAL_HASH_STATE_BUSY; 00547 00548 /* Check if initialization phase has already been performed */ 00549 if(hhash->Phase == HAL_HASH_PHASE_READY) 00550 { 00551 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute 00552 the message digest of a new message */ 00553 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT; 00554 } 00555 00556 /* Set the phase */ 00557 hhash->Phase = HAL_HASH_PHASE_PROCESS; 00558 00559 /* Configure the number of valid bits in last word of the message */ 00560 __HAL_HASH_SET_NBVALIDBITS(Size); 00561 00562 /* Write input buffer in data register */ 00563 HASHEx_WriteData(pInBuffer, Size); 00564 00565 /* Change the HASH state */ 00566 hhash->State = HAL_HASH_STATE_READY; 00567 00568 /* Process Unlocked */ 00569 __HAL_UNLOCK(hhash); 00570 00571 /* Return function status */ 00572 return HAL_OK; 00573 } 00574 00575 00576 /** 00577 * @} 00578 */ 00579 00580 /** @defgroup HASHEx_Group2 HMAC processing functions using polling mode 00581 * @brief HMAC processing functions using polling mode . 00582 * 00583 @verbatim 00584 =============================================================================== 00585 ##### HMAC processing using polling mode functions ##### 00586 =============================================================================== 00587 [..] This section provides functions allowing to calculate in polling mode 00588 the HMAC value using one of the following algorithms: 00589 (+) SHA224 00590 (+) SHA256 00591 00592 @endverbatim 00593 * @{ 00594 */ 00595 00596 /** 00597 * @brief Initializes the HASH peripheral in HMAC SHA224 mode 00598 * then processes pInBuffer. The digest is available in pOutBuffer. 00599 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 00600 * the configuration information for HASH module 00601 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 00602 * @param Size Length of the input buffer in bytes. 00603 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 00604 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes. 00605 * @param Timeout Timeout value 00606 * @retval HAL status 00607 */ 00608 HAL_StatusTypeDef HAL_HMACEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout) 00609 { 00610 uint32_t tickstart = 0U; 00611 00612 /* Process Locked */ 00613 __HAL_LOCK(hhash); 00614 00615 /* Change the HASH state */ 00616 hhash->State = HAL_HASH_STATE_BUSY; 00617 00618 /* Check if initialization phase has already been performed */ 00619 if(hhash->Phase == HAL_HASH_PHASE_READY) 00620 { 00621 /* Check if key size is greater than 64 bytes */ 00622 if(hhash->Init.KeySize > 64U) 00623 { 00624 /* Select the HMAC SHA224 mode */ 00625 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT); 00626 } 00627 else 00628 { 00629 /* Select the HMAC SHA224 mode */ 00630 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT); 00631 } 00632 } 00633 00634 /* Set the phase */ 00635 hhash->Phase = HAL_HASH_PHASE_PROCESS; 00636 00637 /************************** STEP 1 ******************************************/ 00638 /* Configure the number of valid bits in last word of the message */ 00639 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); 00640 00641 /* Write input buffer in data register */ 00642 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize); 00643 00644 /* Start the digest calculation */ 00645 __HAL_HASH_START_DIGEST(); 00646 00647 /* Get tick */ 00648 tickstart = HAL_GetTick(); 00649 00650 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY) 00651 { 00652 /* Check for the Timeout */ 00653 if(Timeout != HAL_MAX_DELAY) 00654 { 00655 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00656 { 00657 /* Change state */ 00658 hhash->State = HAL_HASH_STATE_TIMEOUT; 00659 00660 /* Process Unlocked */ 00661 __HAL_UNLOCK(hhash); 00662 00663 return HAL_TIMEOUT; 00664 } 00665 } 00666 } 00667 /************************** STEP 2 ******************************************/ 00668 /* Configure the number of valid bits in last word of the message */ 00669 __HAL_HASH_SET_NBVALIDBITS(Size); 00670 00671 /* Write input buffer in data register */ 00672 HASHEx_WriteData(pInBuffer, Size); 00673 00674 /* Start the digest calculation */ 00675 __HAL_HASH_START_DIGEST(); 00676 00677 /* Get tick */ 00678 tickstart = HAL_GetTick(); 00679 00680 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY) 00681 { 00682 /* Check for the Timeout */ 00683 if(Timeout != HAL_MAX_DELAY) 00684 { 00685 if((HAL_GetTick() - tickstart ) > Timeout) 00686 { 00687 /* Change state */ 00688 hhash->State = HAL_HASH_STATE_TIMEOUT; 00689 00690 /* Process Unlocked */ 00691 __HAL_UNLOCK(hhash); 00692 00693 return HAL_TIMEOUT; 00694 } 00695 } 00696 } 00697 /************************** STEP 3 ******************************************/ 00698 /* Configure the number of valid bits in last word of the message */ 00699 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); 00700 00701 /* Write input buffer in data register */ 00702 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize); 00703 00704 /* Start the digest calculation */ 00705 __HAL_HASH_START_DIGEST(); 00706 00707 /* Get tick */ 00708 tickstart = HAL_GetTick(); 00709 00710 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY) 00711 { 00712 /* Check for the Timeout */ 00713 if(Timeout != HAL_MAX_DELAY) 00714 { 00715 if((HAL_GetTick() - tickstart ) > Timeout) 00716 { 00717 /* Change state */ 00718 hhash->State = HAL_HASH_STATE_TIMEOUT; 00719 00720 /* Process Unlocked */ 00721 __HAL_UNLOCK(hhash); 00722 00723 return HAL_TIMEOUT; 00724 } 00725 } 00726 } 00727 /* Read the message digest */ 00728 HASHEx_GetDigest(pOutBuffer, 28U); 00729 00730 /* Change the HASH state */ 00731 hhash->State = HAL_HASH_STATE_READY; 00732 00733 /* Process Unlocked */ 00734 __HAL_UNLOCK(hhash); 00735 00736 /* Return function status */ 00737 return HAL_OK; 00738 } 00739 00740 /** 00741 * @brief Initializes the HASH peripheral in HMAC SHA256 mode 00742 * then processes pInBuffer. The digest is available in pOutBuffer 00743 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 00744 * the configuration information for HASH module 00745 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 00746 * @param Size Length of the input buffer in bytes. 00747 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 00748 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes. 00749 * @param Timeout Timeout value 00750 * @retval HAL status 00751 */ 00752 HAL_StatusTypeDef HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout) 00753 { 00754 uint32_t tickstart = 0U; 00755 00756 /* Process Locked */ 00757 __HAL_LOCK(hhash); 00758 00759 /* Change the HASH state */ 00760 hhash->State = HAL_HASH_STATE_BUSY; 00761 00762 /* Check if initialization phase has already been performed */ 00763 if(hhash->Phase == HAL_HASH_PHASE_READY) 00764 { 00765 /* Check if key size is greater than 64 bytes */ 00766 if(hhash->Init.KeySize > 64U) 00767 { 00768 /* Select the HMAC SHA256 mode */ 00769 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY); 00770 } 00771 else 00772 { 00773 /* Select the HMAC SHA256 mode */ 00774 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC); 00775 } 00776 /* Reset the HASH processor core, so that the HASH will be ready to compute 00777 the message digest of a new message */ 00778 HASH->CR |= HASH_CR_INIT; 00779 } 00780 00781 /* Set the phase */ 00782 hhash->Phase = HAL_HASH_PHASE_PROCESS; 00783 00784 /************************** STEP 1 ******************************************/ 00785 /* Configure the number of valid bits in last word of the message */ 00786 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); 00787 00788 /* Write input buffer in data register */ 00789 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize); 00790 00791 /* Start the digest calculation */ 00792 __HAL_HASH_START_DIGEST(); 00793 00794 /* Get tick */ 00795 tickstart = HAL_GetTick(); 00796 00797 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY) 00798 { 00799 /* Check for the Timeout */ 00800 if(Timeout != HAL_MAX_DELAY) 00801 { 00802 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 00803 { 00804 /* Change state */ 00805 hhash->State = HAL_HASH_STATE_TIMEOUT; 00806 00807 /* Process Unlocked */ 00808 __HAL_UNLOCK(hhash); 00809 00810 return HAL_TIMEOUT; 00811 } 00812 } 00813 } 00814 /************************** STEP 2 ******************************************/ 00815 /* Configure the number of valid bits in last word of the message */ 00816 __HAL_HASH_SET_NBVALIDBITS(Size); 00817 00818 /* Write input buffer in data register */ 00819 HASHEx_WriteData(pInBuffer, Size); 00820 00821 /* Start the digest calculation */ 00822 __HAL_HASH_START_DIGEST(); 00823 00824 /* Get tick */ 00825 tickstart = HAL_GetTick(); 00826 00827 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY) 00828 { 00829 /* Check for the Timeout */ 00830 if(Timeout != HAL_MAX_DELAY) 00831 { 00832 if((HAL_GetTick() - tickstart ) > Timeout) 00833 { 00834 /* Change state */ 00835 hhash->State = HAL_HASH_STATE_TIMEOUT; 00836 00837 /* Process Unlocked */ 00838 __HAL_UNLOCK(hhash); 00839 00840 return HAL_TIMEOUT; 00841 } 00842 } 00843 } 00844 /************************** STEP 3 ******************************************/ 00845 /* Configure the number of valid bits in last word of the message */ 00846 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); 00847 00848 /* Write input buffer in data register */ 00849 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize); 00850 00851 /* Start the digest calculation */ 00852 __HAL_HASH_START_DIGEST(); 00853 00854 /* Get tick */ 00855 tickstart = HAL_GetTick(); 00856 00857 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY) 00858 { 00859 /* Check for the Timeout */ 00860 if(Timeout != HAL_MAX_DELAY) 00861 { 00862 if((HAL_GetTick() - tickstart ) > Timeout) 00863 { 00864 /* Change state */ 00865 hhash->State = HAL_HASH_STATE_TIMEOUT; 00866 00867 /* Process Unlocked */ 00868 __HAL_UNLOCK(hhash); 00869 00870 return HAL_TIMEOUT; 00871 } 00872 } 00873 } 00874 /* Read the message digest */ 00875 HASHEx_GetDigest(pOutBuffer, 32U); 00876 00877 /* Change the HASH state */ 00878 hhash->State = HAL_HASH_STATE_READY; 00879 00880 /* Process Unlocked */ 00881 __HAL_UNLOCK(hhash); 00882 00883 /* Return function status */ 00884 return HAL_OK; 00885 } 00886 00887 /** 00888 * @} 00889 */ 00890 00891 /** @defgroup HASHEx_Group3 HASH processing functions using interrupt mode 00892 * @brief processing functions using interrupt mode. 00893 * 00894 @verbatim 00895 =============================================================================== 00896 ##### HASH processing using interrupt functions ##### 00897 =============================================================================== 00898 [..] This section provides functions allowing to calculate in interrupt mode 00899 the hash value using one of the following algorithms: 00900 (+) SHA224 00901 (+) SHA256 00902 00903 @endverbatim 00904 * @{ 00905 */ 00906 00907 /** 00908 * @brief Initializes the HASH peripheral in SHA224 mode then processes pInBuffer. 00909 * The digest is available in pOutBuffer. 00910 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 00911 * the configuration information for HASH module 00912 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 00913 * @param Size Length of the input buffer in bytes. 00914 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 00915 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes. 00916 * @retval HAL status 00917 */ 00918 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer) 00919 { 00920 uint32_t inputaddr; 00921 uint32_t buffercounter; 00922 uint32_t inputcounter; 00923 00924 /* Process Locked */ 00925 __HAL_LOCK(hhash); 00926 00927 if(hhash->State == HAL_HASH_STATE_READY) 00928 { 00929 /* Change the HASH state */ 00930 hhash->State = HAL_HASH_STATE_BUSY; 00931 00932 hhash->HashInCount = Size; 00933 hhash->pHashInBuffPtr = pInBuffer; 00934 hhash->pHashOutBuffPtr = pOutBuffer; 00935 00936 /* Check if initialization phase has already been performed */ 00937 if(hhash->Phase == HAL_HASH_PHASE_READY) 00938 { 00939 /* Select the SHA224 mode */ 00940 HASH->CR |= HASH_ALGOSELECTION_SHA224; 00941 /* Reset the HASH processor core, so that the HASH will be ready to compute 00942 the message digest of a new message */ 00943 HASH->CR |= HASH_CR_INIT; 00944 } 00945 /* Reset interrupt counter */ 00946 hhash->HashITCounter = 0U; 00947 00948 /* Set the phase */ 00949 hhash->Phase = HAL_HASH_PHASE_PROCESS; 00950 00951 /* Process Unlocked */ 00952 __HAL_UNLOCK(hhash); 00953 00954 /* Enable Interrupts */ 00955 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI); 00956 00957 /* Return function status */ 00958 return HAL_OK; 00959 } 00960 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS)) 00961 { 00962 /* Read the message digest */ 00963 HASHEx_GetDigest(hhash->pHashOutBuffPtr, 28U); 00964 if(hhash->HashInCount == 0U) 00965 { 00966 /* Disable Interrupts */ 00967 HASH->IMR = 0U; 00968 /* Change the HASH state */ 00969 hhash->State = HAL_HASH_STATE_READY; 00970 /* Call digest computation complete callback */ 00971 HAL_HASH_DgstCpltCallback(hhash); 00972 00973 /* Process Unlocked */ 00974 __HAL_UNLOCK(hhash); 00975 00976 /* Return function status */ 00977 return HAL_OK; 00978 } 00979 } 00980 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) 00981 { 00982 if(hhash->HashInCount >= 68U) 00983 { 00984 inputaddr = (uint32_t)hhash->pHashInBuffPtr; 00985 /* Write the Input block in the Data IN register */ 00986 for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U) 00987 { 00988 HASH->DIN = *(uint32_t*)inputaddr; 00989 inputaddr+=4U; 00990 } 00991 if(hhash->HashITCounter == 0U) 00992 { 00993 HASH->DIN = *(uint32_t*)inputaddr; 00994 00995 if(hhash->HashInCount >= 68U) 00996 { 00997 /* Decrement buffer counter */ 00998 hhash->HashInCount -= 68U; 00999 hhash->pHashInBuffPtr+= 68U; 01000 } 01001 else 01002 { 01003 hhash->HashInCount = 0U; 01004 hhash->pHashInBuffPtr+= hhash->HashInCount; 01005 } 01006 /* Set Interrupt counter */ 01007 hhash->HashITCounter = 1U; 01008 } 01009 else 01010 { 01011 /* Decrement buffer counter */ 01012 hhash->HashInCount -= 64U; 01013 hhash->pHashInBuffPtr+= 64U; 01014 } 01015 } 01016 else 01017 { 01018 /* Get the buffer address */ 01019 inputaddr = (uint32_t)hhash->pHashInBuffPtr; 01020 /* Get the buffer counter */ 01021 inputcounter = hhash->HashInCount; 01022 /* Disable Interrupts */ 01023 HASH->IMR &= ~(HASH_IT_DINI); 01024 /* Configure the number of valid bits in last word of the message */ 01025 __HAL_HASH_SET_NBVALIDBITS(inputcounter); 01026 01027 if((inputcounter > 4U) && (inputcounter%4U)) 01028 { 01029 inputcounter = (inputcounter+4U-inputcounter%4U); 01030 } 01031 else if ((inputcounter < 4U) && (inputcounter != 0U)) 01032 { 01033 inputcounter = 4U; 01034 } 01035 /* Write the Input block in the Data IN register */ 01036 for(buffercounter = 0U; buffercounter < inputcounter/4U; buffercounter++) 01037 { 01038 HASH->DIN = *(uint32_t*)inputaddr; 01039 inputaddr+=4U; 01040 } 01041 /* Start the digest calculation */ 01042 __HAL_HASH_START_DIGEST(); 01043 /* Reset buffer counter */ 01044 hhash->HashInCount = 0U; 01045 /* Call Input data transfer complete callback */ 01046 HAL_HASH_InCpltCallback(hhash); 01047 } 01048 } 01049 01050 /* Process Unlocked */ 01051 __HAL_UNLOCK(hhash); 01052 01053 /* Return function status */ 01054 return HAL_OK; 01055 } 01056 01057 01058 /** 01059 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer. 01060 * The digest is available in pOutBuffer. 01061 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 01062 * the configuration information for HASH module 01063 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 01064 * @param Size Length of the input buffer in bytes. 01065 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 01066 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes. 01067 * @retval HAL status 01068 */ 01069 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer) 01070 { 01071 uint32_t inputaddr; 01072 uint32_t buffercounter; 01073 uint32_t inputcounter; 01074 01075 /* Process Locked */ 01076 __HAL_LOCK(hhash); 01077 01078 if(hhash->State == HAL_HASH_STATE_READY) 01079 { 01080 /* Change the HASH state */ 01081 hhash->State = HAL_HASH_STATE_BUSY; 01082 01083 hhash->HashInCount = Size; 01084 hhash->pHashInBuffPtr = pInBuffer; 01085 hhash->pHashOutBuffPtr = pOutBuffer; 01086 01087 /* Check if initialization phase has already been performed */ 01088 if(hhash->Phase == HAL_HASH_PHASE_READY) 01089 { 01090 /* Select the SHA256 mode */ 01091 HASH->CR |= HASH_ALGOSELECTION_SHA256; 01092 /* Reset the HASH processor core, so that the HASH will be ready to compute 01093 the message digest of a new message */ 01094 HASH->CR |= HASH_CR_INIT; 01095 } 01096 /* Reset interrupt counter */ 01097 hhash->HashITCounter = 0U; 01098 01099 /* Set the phase */ 01100 hhash->Phase = HAL_HASH_PHASE_PROCESS; 01101 01102 /* Process Unlocked */ 01103 __HAL_UNLOCK(hhash); 01104 01105 /* Enable Interrupts */ 01106 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI); 01107 01108 /* Return function status */ 01109 return HAL_OK; 01110 } 01111 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS)) 01112 { 01113 /* Read the message digest */ 01114 HASHEx_GetDigest(hhash->pHashOutBuffPtr, 32U); 01115 if(hhash->HashInCount == 0U) 01116 { 01117 /* Disable Interrupts */ 01118 HASH->IMR = 0U; 01119 /* Change the HASH state */ 01120 hhash->State = HAL_HASH_STATE_READY; 01121 /* Call digest computation complete callback */ 01122 HAL_HASH_DgstCpltCallback(hhash); 01123 01124 /* Process Unlocked */ 01125 __HAL_UNLOCK(hhash); 01126 01127 /* Return function status */ 01128 return HAL_OK; 01129 } 01130 } 01131 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) 01132 { 01133 if(hhash->HashInCount >= 68U) 01134 { 01135 inputaddr = (uint32_t)hhash->pHashInBuffPtr; 01136 /* Write the Input block in the Data IN register */ 01137 for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U) 01138 { 01139 HASH->DIN = *(uint32_t*)inputaddr; 01140 inputaddr+=4U; 01141 } 01142 if(hhash->HashITCounter == 0U) 01143 { 01144 HASH->DIN = *(uint32_t*)inputaddr; 01145 01146 if(hhash->HashInCount >= 68U) 01147 { 01148 /* Decrement buffer counter */ 01149 hhash->HashInCount -= 68U; 01150 hhash->pHashInBuffPtr+= 68U; 01151 } 01152 else 01153 { 01154 hhash->HashInCount = 0U; 01155 hhash->pHashInBuffPtr+= hhash->HashInCount; 01156 } 01157 /* Set Interrupt counter */ 01158 hhash->HashITCounter = 1U; 01159 } 01160 else 01161 { 01162 /* Decrement buffer counter */ 01163 hhash->HashInCount -= 64U; 01164 hhash->pHashInBuffPtr+= 64U; 01165 } 01166 } 01167 else 01168 { 01169 /* Get the buffer address */ 01170 inputaddr = (uint32_t)hhash->pHashInBuffPtr; 01171 /* Get the buffer counter */ 01172 inputcounter = hhash->HashInCount; 01173 /* Disable Interrupts */ 01174 HASH->IMR &= ~(HASH_IT_DINI); 01175 /* Configure the number of valid bits in last word of the message */ 01176 __HAL_HASH_SET_NBVALIDBITS(inputcounter); 01177 01178 if((inputcounter > 4U) && (inputcounter%4U)) 01179 { 01180 inputcounter = (inputcounter+4U-inputcounter%4U); 01181 } 01182 else if ((inputcounter < 4U) && (inputcounter != 0U)) 01183 { 01184 inputcounter = 4U; 01185 } 01186 /* Write the Input block in the Data IN register */ 01187 for(buffercounter = 0U; buffercounter < inputcounter/4U; buffercounter++) 01188 { 01189 HASH->DIN = *(uint32_t*)inputaddr; 01190 inputaddr+=4U; 01191 } 01192 /* Start the digest calculation */ 01193 __HAL_HASH_START_DIGEST(); 01194 /* Reset buffer counter */ 01195 hhash->HashInCount = 0U; 01196 /* Call Input data transfer complete callback */ 01197 HAL_HASH_InCpltCallback(hhash); 01198 } 01199 } 01200 01201 /* Process Unlocked */ 01202 __HAL_UNLOCK(hhash); 01203 01204 /* Return function status */ 01205 return HAL_OK; 01206 } 01207 01208 /** 01209 * @brief This function handles HASH interrupt request. 01210 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 01211 * the configuration information for HASH module 01212 * @retval None 01213 */ 01214 void HAL_HASHEx_IRQHandler(HASH_HandleTypeDef *hhash) 01215 { 01216 switch(HASH->CR & HASH_CR_ALGO) 01217 { 01218 01219 case HASH_ALGOSELECTION_SHA224: 01220 HAL_HASHEx_SHA224_Start_IT(hhash, NULL, 0U, NULL); 01221 break; 01222 01223 case HASH_ALGOSELECTION_SHA256: 01224 HAL_HASHEx_SHA256_Start_IT(hhash, NULL, 0U, NULL); 01225 break; 01226 01227 default: 01228 break; 01229 } 01230 } 01231 01232 /** 01233 * @} 01234 */ 01235 01236 /** @defgroup HASHEx_Group4 HASH processing functions using DMA mode 01237 * @brief processing functions using DMA mode. 01238 * 01239 @verbatim 01240 =============================================================================== 01241 ##### HASH processing using DMA functions ##### 01242 =============================================================================== 01243 [..] This section provides functions allowing to calculate in DMA mode 01244 the hash value using one of the following algorithms: 01245 (+) SHA224 01246 (+) SHA256 01247 01248 @endverbatim 01249 * @{ 01250 */ 01251 01252 01253 /** 01254 * @brief Initializes the HASH peripheral in SHA224 mode then enables DMA to 01255 control data transfer. Use HAL_HASH_SHA224_Finish() to get the digest. 01256 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 01257 * the configuration information for HASH module 01258 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 01259 * @param Size Length of the input buffer in bytes. 01260 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 01261 * @retval HAL status 01262 */ 01263 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) 01264 { 01265 uint32_t inputaddr = (uint32_t)pInBuffer; 01266 01267 /* Process Locked */ 01268 __HAL_LOCK(hhash); 01269 01270 /* Change the HASH state */ 01271 hhash->State = HAL_HASH_STATE_BUSY; 01272 01273 /* Check if initialization phase has already been performed */ 01274 if(hhash->Phase == HAL_HASH_PHASE_READY) 01275 { 01276 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute 01277 the message digest of a new message */ 01278 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT; 01279 } 01280 01281 /* Configure the number of valid bits in last word of the message */ 01282 __HAL_HASH_SET_NBVALIDBITS(Size); 01283 01284 /* Set the phase */ 01285 hhash->Phase = HAL_HASH_PHASE_PROCESS; 01286 01287 /* Set the HASH DMA transfer complete callback */ 01288 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt; 01289 /* Set the DMA error callback */ 01290 hhash->hdmain->XferErrorCallback = HASHEx_DMAError; 01291 01292 /* Enable the DMA In DMA Stream */ 01293 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4U ? (Size+3U)/4U:Size/4U)); 01294 01295 /* Enable DMA requests */ 01296 HASH->CR |= (HASH_CR_DMAE); 01297 01298 /* Process Unlocked */ 01299 __HAL_UNLOCK(hhash); 01300 01301 /* Return function status */ 01302 return HAL_OK; 01303 } 01304 01305 /** 01306 * @brief Returns the computed digest in SHA224 01307 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 01308 * the configuration information for HASH module 01309 * @param pOutBuffer Pointer to the computed digest. Its size must be 28 bytes. 01310 * @param Timeout Timeout value 01311 * @retval HAL status 01312 */ 01313 HAL_StatusTypeDef HAL_HASHEx_SHA224_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout) 01314 { 01315 uint32_t tickstart = 0U; 01316 01317 /* Process Locked */ 01318 __HAL_LOCK(hhash); 01319 01320 /* Change HASH peripheral state */ 01321 hhash->State = HAL_HASH_STATE_BUSY; 01322 01323 /* Get tick */ 01324 tickstart = HAL_GetTick(); 01325 01326 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS)) 01327 { 01328 /* Check for the Timeout */ 01329 if(Timeout != HAL_MAX_DELAY) 01330 { 01331 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 01332 { 01333 /* Change state */ 01334 hhash->State = HAL_HASH_STATE_TIMEOUT; 01335 01336 /* Process Unlocked */ 01337 __HAL_UNLOCK(hhash); 01338 01339 return HAL_TIMEOUT; 01340 } 01341 } 01342 } 01343 01344 /* Read the message digest */ 01345 HASHEx_GetDigest(pOutBuffer, 28U); 01346 01347 /* Change HASH peripheral state */ 01348 hhash->State = HAL_HASH_STATE_READY; 01349 01350 /* Process Unlocked */ 01351 __HAL_UNLOCK(hhash); 01352 01353 /* Return function status */ 01354 return HAL_OK; 01355 } 01356 01357 /** 01358 * @brief Initializes the HASH peripheral in SHA256 mode then enables DMA to 01359 control data transfer. Use HAL_HASH_SHA256_Finish() to get the digest. 01360 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 01361 * the configuration information for HASH module 01362 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 01363 * @param Size Length of the input buffer in bytes. 01364 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 01365 * @retval HAL status 01366 */ 01367 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) 01368 { 01369 uint32_t inputaddr = (uint32_t)pInBuffer; 01370 01371 /* Process Locked */ 01372 __HAL_LOCK(hhash); 01373 01374 /* Change the HASH state */ 01375 hhash->State = HAL_HASH_STATE_BUSY; 01376 01377 /* Check if initialization phase has already been performed */ 01378 if(hhash->Phase == HAL_HASH_PHASE_READY) 01379 { 01380 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute 01381 the message digest of a new message */ 01382 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT; 01383 } 01384 01385 /* Configure the number of valid bits in last word of the message */ 01386 __HAL_HASH_SET_NBVALIDBITS(Size); 01387 01388 /* Set the phase */ 01389 hhash->Phase = HAL_HASH_PHASE_PROCESS; 01390 01391 /* Set the HASH DMA transfer complete callback */ 01392 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt; 01393 /* Set the DMA error callback */ 01394 hhash->hdmain->XferErrorCallback = HASHEx_DMAError; 01395 01396 /* Enable the DMA In DMA Stream */ 01397 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4U ? (Size+3U)/4U:Size/4U)); 01398 01399 /* Enable DMA requests */ 01400 HASH->CR |= (HASH_CR_DMAE); 01401 01402 /* Process UnLock */ 01403 __HAL_UNLOCK(hhash); 01404 01405 /* Return function status */ 01406 return HAL_OK; 01407 } 01408 01409 /** 01410 * @brief Returns the computed digest in SHA256. 01411 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 01412 * the configuration information for HASH module 01413 * @param pOutBuffer Pointer to the computed digest. Its size must be 32 bytes. 01414 * @param Timeout Timeout value 01415 * @retval HAL status 01416 */ 01417 HAL_StatusTypeDef HAL_HASHEx_SHA256_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout) 01418 { 01419 uint32_t tickstart = 0U; 01420 01421 /* Process Locked */ 01422 __HAL_LOCK(hhash); 01423 01424 /* Change HASH peripheral state */ 01425 hhash->State = HAL_HASH_STATE_BUSY; 01426 01427 /* Get tick */ 01428 tickstart = HAL_GetTick(); 01429 01430 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS)) 01431 { 01432 /* Check for the Timeout */ 01433 if(Timeout != HAL_MAX_DELAY) 01434 { 01435 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) 01436 { 01437 /* Change state */ 01438 hhash->State = HAL_HASH_STATE_TIMEOUT; 01439 01440 /* Process Unlocked */ 01441 __HAL_UNLOCK(hhash); 01442 01443 return HAL_TIMEOUT; 01444 } 01445 } 01446 } 01447 01448 /* Read the message digest */ 01449 HASHEx_GetDigest(pOutBuffer, 32U); 01450 01451 /* Change HASH peripheral state */ 01452 hhash->State = HAL_HASH_STATE_READY; 01453 01454 /* Process Unlocked */ 01455 __HAL_UNLOCK(hhash); 01456 01457 /* Return function status */ 01458 return HAL_OK; 01459 } 01460 01461 01462 /** 01463 * @} 01464 */ 01465 /** @defgroup HASHEx_Group5 HMAC processing functions using DMA mode 01466 * @brief HMAC processing functions using DMA mode . 01467 * 01468 @verbatim 01469 =============================================================================== 01470 ##### HMAC processing using DMA functions ##### 01471 =============================================================================== 01472 [..] This section provides functions allowing to calculate in DMA mode 01473 the HMAC value using one of the following algorithms: 01474 (+) SHA224 01475 (+) SHA256 01476 01477 @endverbatim 01478 * @{ 01479 */ 01480 01481 /** 01482 * @brief Initializes the HASH peripheral in HMAC SHA224 mode 01483 * then enables DMA to control data transfer. 01484 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 01485 * the configuration information for HASH module 01486 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 01487 * @param Size Length of the input buffer in bytes. 01488 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 01489 * @retval HAL status 01490 */ 01491 HAL_StatusTypeDef HAL_HMACEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) 01492 { 01493 uint32_t inputaddr; 01494 01495 /* Process Locked */ 01496 __HAL_LOCK(hhash); 01497 01498 /* Change the HASH state */ 01499 hhash->State = HAL_HASH_STATE_BUSY; 01500 01501 /* Save buffer pointer and size in handle */ 01502 hhash->pHashInBuffPtr = pInBuffer; 01503 hhash->HashBuffSize = Size; 01504 hhash->HashInCount = 0U; 01505 01506 /* Check if initialization phase has already been performed */ 01507 if(hhash->Phase == HAL_HASH_PHASE_READY) 01508 { 01509 /* Check if key size is greater than 64 bytes */ 01510 if(hhash->Init.KeySize > 64U) 01511 { 01512 /* Select the HMAC SHA224 mode */ 01513 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT); 01514 } 01515 else 01516 { 01517 /* Select the HMAC SHA224 mode */ 01518 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT); 01519 } 01520 } 01521 01522 /* Set the phase */ 01523 hhash->Phase = HAL_HASH_PHASE_PROCESS; 01524 01525 /* Configure the number of valid bits in last word of the message */ 01526 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); 01527 01528 /* Get the key address */ 01529 inputaddr = (uint32_t)(hhash->Init.pKey); 01530 01531 /* Set the HASH DMA transfer complete callback */ 01532 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt; 01533 /* Set the DMA error callback */ 01534 hhash->hdmain->XferErrorCallback = HASHEx_DMAError; 01535 01536 /* Enable the DMA In DMA Stream */ 01537 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4U ? (hhash->Init.KeySize+3U)/4U:hhash->Init.KeySize/4U)); 01538 /* Enable DMA requests */ 01539 HASH->CR |= (HASH_CR_DMAE); 01540 01541 /* Process Unlocked */ 01542 __HAL_UNLOCK(hhash); 01543 01544 /* Return function status */ 01545 return HAL_OK; 01546 } 01547 01548 /** 01549 * @brief Initializes the HASH peripheral in HMAC SHA256 mode 01550 * then enables DMA to control data transfer. 01551 * @param hhash pointer to a HASH_HandleTypeDef structure that contains 01552 * the configuration information for HASH module 01553 * @param pInBuffer Pointer to the input buffer (buffer to be hashed). 01554 * @param Size Length of the input buffer in bytes. 01555 * If the Size is not multiple of 64 bytes, the padding is managed by hardware. 01556 * @retval HAL status 01557 */ 01558 HAL_StatusTypeDef HAL_HMACEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) 01559 { 01560 uint32_t inputaddr; 01561 01562 /* Process Locked */ 01563 __HAL_LOCK(hhash); 01564 01565 /* Change the HASH state */ 01566 hhash->State = HAL_HASH_STATE_BUSY; 01567 01568 /* Save buffer pointer and size in handle */ 01569 hhash->pHashInBuffPtr = pInBuffer; 01570 hhash->HashBuffSize = Size; 01571 hhash->HashInCount = 0U; 01572 01573 /* Check if initialization phase has already been performed */ 01574 if(hhash->Phase == HAL_HASH_PHASE_READY) 01575 { 01576 /* Check if key size is greater than 64 bytes */ 01577 if(hhash->Init.KeySize > 64U) 01578 { 01579 /* Select the HMAC SHA256 mode */ 01580 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY); 01581 } 01582 else 01583 { 01584 /* Select the HMAC SHA256 mode */ 01585 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC); 01586 } 01587 /* Reset the HASH processor core, so that the HASH will be ready to compute 01588 the message digest of a new message */ 01589 HASH->CR |= HASH_CR_INIT; 01590 } 01591 01592 /* Set the phase */ 01593 hhash->Phase = HAL_HASH_PHASE_PROCESS; 01594 01595 /* Configure the number of valid bits in last word of the message */ 01596 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); 01597 01598 /* Get the key address */ 01599 inputaddr = (uint32_t)(hhash->Init.pKey); 01600 01601 /* Set the HASH DMA transfer complete callback */ 01602 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt; 01603 /* Set the DMA error callback */ 01604 hhash->hdmain->XferErrorCallback = HASHEx_DMAError; 01605 01606 /* Enable the DMA In DMA Stream */ 01607 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4U ? (hhash->Init.KeySize+3U)/4U:hhash->Init.KeySize/4U)); 01608 /* Enable DMA requests */ 01609 HASH->CR |= (HASH_CR_DMAE); 01610 01611 /* Process Unlocked */ 01612 __HAL_UNLOCK(hhash); 01613 01614 /* Return function status */ 01615 return HAL_OK; 01616 } 01617 01618 /** 01619 * @} 01620 */ 01621 01622 /** 01623 * @} 01624 */ 01625 #endif /* STM32F437xx || STM32F439xx || STM32F479xx */ 01626 01627 #endif /* HAL_HASH_MODULE_ENABLED */ 01628 /** 01629 * @} 01630 */ 01631 01632 /** 01633 * @} 01634 */ 01635 01636 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/