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