stm32f4xx_hal_hash_ex.c 53 KB

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