shamd5.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092
  1. //*****************************************************************************
  2. //
  3. // shamd5.c - Driver for the SHA/MD5 module.
  4. //
  5. // Copyright (c) 2012-2020 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions
  10. // are met:
  11. //
  12. // Redistributions of source code must retain the above copyright
  13. // notice, this list of conditions and the following disclaimer.
  14. //
  15. // Redistributions in binary form must reproduce the above copyright
  16. // notice, this list of conditions and the following disclaimer in the
  17. // documentation and/or other materials provided with the
  18. // distribution.
  19. //
  20. // Neither the name of Texas Instruments Incorporated nor the names of
  21. // its contributors may be used to endorse or promote products derived
  22. // from this software without specific prior written permission.
  23. //
  24. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  28. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  30. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  34. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. // This is part of revision 2.2.0.295 of the Tiva Peripheral Driver Library.
  37. //
  38. //*****************************************************************************
  39. #include <stdbool.h>
  40. #include <stdint.h>
  41. #include "inc/hw_ints.h"
  42. #include "inc/hw_memmap.h"
  43. #include "inc/hw_nvic.h"
  44. #include "inc/hw_shamd5.h"
  45. #include "inc/hw_types.h"
  46. #include "driverlib/debug.h"
  47. #include "driverlib/interrupt.h"
  48. #include "driverlib/shamd5.h"
  49. //*****************************************************************************
  50. //
  51. //! \addtogroup shamd5_api
  52. //! @{
  53. //
  54. //*****************************************************************************
  55. //*****************************************************************************
  56. //
  57. //! Resets the SHA/MD5 module.
  58. //!
  59. //! \param ui32Base is the base address of the SHA/MD5 module.
  60. //!
  61. //! This function performs a soft-reset of the SHA/MD5 module using the
  62. //! SYSCONFIG register.
  63. //!
  64. //! \return None.
  65. //
  66. //*****************************************************************************
  67. void
  68. SHAMD5Reset(uint32_t ui32Base)
  69. {
  70. //
  71. // Check the arguments.
  72. //
  73. ASSERT(ui32Base == SHAMD5_BASE);
  74. //
  75. // Set the soft-reset bit.
  76. //
  77. HWREG(ui32Base + SHAMD5_O_SYSCONFIG) |= SHAMD5_SYSCONFIG_SOFTRESET;
  78. //
  79. // Wait for the reset to complete.
  80. //
  81. while((HWREG(ui32Base + SHAMD5_O_SYSSTATUS) &
  82. SHAMD5_SYSSTATUS_RESETDONE) == 0)
  83. {
  84. }
  85. //
  86. // Force idle mode.
  87. //
  88. HWREG(ui32Base + SHAMD5_O_SYSCONFIG) =
  89. ((HWREG(ui32Base + SHAMD5_O_SYSCONFIG) & ~SHAMD5_SYSCONFIG_SIDLE_M) |
  90. SHAMD5_SYSCONFIG_SIDLE_FORCE);
  91. }
  92. //*****************************************************************************
  93. //
  94. //! Enables the uDMA requests in the SHA/MD5 module.
  95. //!
  96. //! \param ui32Base is the base address of the SHA/MD5 module.
  97. //!
  98. //! This function configures the DMA options of the SHA/MD5 module.
  99. //!
  100. //! \return None
  101. //
  102. //*****************************************************************************
  103. void
  104. SHAMD5DMAEnable(uint32_t ui32Base)
  105. {
  106. //
  107. // Check the arguments.
  108. //
  109. ASSERT(ui32Base == SHAMD5_BASE);
  110. //
  111. // Write the new configuration into the register.
  112. //
  113. HWREG(ui32Base + SHAMD5_O_SYSCONFIG) |=
  114. SHAMD5_SYSCONFIG_SADVANCED | SHAMD5_SYSCONFIG_DMA_EN;
  115. }
  116. //*****************************************************************************
  117. //
  118. //! Disables the uDMA requests in the SHA/MD5 module.
  119. //!
  120. //! \param ui32Base is the base address of the SHA/MD5 module.
  121. //!
  122. //! This function configures the DMA options of the SHA/MD5 module.
  123. //!
  124. //! \return None
  125. //
  126. //*****************************************************************************
  127. void
  128. SHAMD5DMADisable(uint32_t ui32Base)
  129. {
  130. //
  131. // Check the arguments.
  132. //
  133. ASSERT(ui32Base == SHAMD5_BASE);
  134. //
  135. // Write the new configuration into the register.
  136. //
  137. HWREG(ui32Base + SHAMD5_O_SYSCONFIG) &=
  138. ~(SHAMD5_SYSCONFIG_SADVANCED | SHAMD5_SYSCONFIG_DMA_EN);
  139. }
  140. //*****************************************************************************
  141. //
  142. //! Get the interrupt status of the SHA/MD5 module.
  143. //!
  144. //! \param ui32Base is the base address of the SHA/MD5 module.
  145. //! \param bMasked is \b false if the raw interrupt status is required and
  146. //! \b true if the masked interrupt status is required.
  147. //!
  148. //! This function returns the current value of the IRQSTATUS register. The
  149. //! value will be a logical OR of the following:
  150. //!
  151. //! - \b SHAMD5_INT_CONTEXT_READY - Context input registers are ready.
  152. //! - \b SHAMD5_INT_PARTHASH_READY - Context output registers are ready after
  153. //! a context switch.
  154. //! - \b SHAMD5_INT_INPUT_READY - Data FIFO is ready to receive data.
  155. //! - \b SHAMD5_INT_OUTPUT_READY - Context output registers are ready.
  156. //!
  157. //! \return Interrupt status
  158. //
  159. //*****************************************************************************
  160. uint32_t
  161. SHAMD5IntStatus(uint32_t ui32Base, bool bMasked)
  162. {
  163. uint32_t ui32Status, ui32Enable, ui32Temp;
  164. //
  165. // Check the arguments.
  166. //
  167. ASSERT(ui32Base == SHAMD5_BASE);
  168. //
  169. // Return the value of the IRQSTATUS register.
  170. //
  171. ui32Status = HWREG(ui32Base + SHAMD5_O_IRQSTATUS);
  172. if(bMasked)
  173. {
  174. ui32Enable = HWREG(ui32Base + SHAMD5_O_IRQENABLE);
  175. ui32Temp = HWREG(ui32Base + SHAMD5_O_DMAMIS);
  176. return((ui32Status & ui32Enable) |
  177. ((ui32Temp & 0x00000001) << 19) |
  178. ((ui32Temp & 0x00000002) << 16) |
  179. ((ui32Temp & 0x00000004) << 14));
  180. }
  181. else
  182. {
  183. ui32Temp = HWREG(ui32Base + SHAMD5_O_DMARIS);
  184. return(ui32Status |
  185. ((ui32Temp & 0x00000001) << 19) |
  186. ((ui32Temp & 0x00000002) << 16) |
  187. ((ui32Temp & 0x00000004) << 14));
  188. }
  189. }
  190. //*****************************************************************************
  191. //
  192. //! Enable interrupt sources in the SHA/MD5 module.
  193. //!
  194. //! \param ui32Base is the base address of the SHA/MD5 module.
  195. //! \param ui32IntFlags contains desired interrupts to enable.
  196. //!
  197. //! This function enables interrupt sources in the SHA/MD5 module.
  198. //! ui32IntFlags must be a logical OR of one or more of the following
  199. //! values:
  200. //!
  201. //! - \b SHAMD5_INT_CONTEXT_READY - Context input registers are ready.
  202. //! - \b SHAMD5_INT_PARTHASH_READY - Context output registers are ready after
  203. //! a context switch.
  204. //! - \b SHAMD5_INT_INPUT_READY - Data FIFO is ready to receive data.
  205. //! - \b SHAMD5_INT_OUTPUT_READY - Context output registers are ready.
  206. //!
  207. //! \return None.
  208. //
  209. //*****************************************************************************
  210. void
  211. SHAMD5IntEnable(uint32_t ui32Base, uint32_t ui32IntFlags)
  212. {
  213. //
  214. // Check the arguments.
  215. //
  216. ASSERT(ui32Base == SHAMD5_BASE);
  217. ASSERT((ui32IntFlags == SHAMD5_INT_CONTEXT_READY) ||
  218. (ui32IntFlags == SHAMD5_INT_PARTHASH_READY) ||
  219. (ui32IntFlags == SHAMD5_INT_INPUT_READY) ||
  220. (ui32IntFlags == SHAMD5_INT_OUTPUT_READY));
  221. //
  222. // Enable the interrupt sources.
  223. //
  224. HWREG(ui32Base + SHAMD5_O_DMAIM) |= (((ui32IntFlags & 0x00010000) >> 14) |
  225. ((ui32IntFlags & 0x00020000) >> 16) |
  226. ((ui32IntFlags & 0x00040000) >> 19));
  227. HWREG(ui32Base + SHAMD5_O_IRQENABLE) |= ui32IntFlags & 0x0000ffff;
  228. //
  229. // Enable all interrupts.
  230. //
  231. HWREG(ui32Base + SHAMD5_O_SYSCONFIG) |= SHAMD5_SYSCONFIG_IT_EN;
  232. }
  233. //*****************************************************************************
  234. //
  235. //! Disable interrupt sources in the SHA/MD5 module.
  236. //!
  237. //! \param ui32Base is the base address of the SHA/MD5 module.
  238. //! \param ui32IntFlags contains desired interrupts to disable.
  239. //!
  240. //! \e ui32IntFlags must be a logical OR of one or more of the following
  241. //! values:
  242. //!
  243. //! - \b SHAMD5_INT_CONTEXT_READY - Context input registers are ready.
  244. //! - \b SHAMD5_INT_PARTHASH_READY - Context output registers are ready after
  245. //! a context switch.
  246. //! - \b SHAMD5_INT_INPUT_READY - Data FIFO is ready to receive data.
  247. //! - \b SHAMD5_INT_OUTPUT_READY - Context output registers are ready.
  248. //!
  249. //! \return None.
  250. //
  251. //*****************************************************************************
  252. void
  253. SHAMD5IntDisable(uint32_t ui32Base, uint32_t ui32IntFlags)
  254. {
  255. //
  256. // Check the arguments.
  257. //
  258. ASSERT(ui32Base == SHAMD5_BASE);
  259. ASSERT((ui32IntFlags == SHAMD5_INT_CONTEXT_READY) ||
  260. (ui32IntFlags == SHAMD5_INT_PARTHASH_READY) ||
  261. (ui32IntFlags == SHAMD5_INT_INPUT_READY) ||
  262. (ui32IntFlags == SHAMD5_INT_OUTPUT_READY));
  263. //
  264. // Clear the corresponding flags disabling the interrupt sources.
  265. //
  266. HWREG(ui32Base + SHAMD5_O_DMAIM) &= ~(((ui32IntFlags & 0x00010000) >> 14) |
  267. ((ui32IntFlags & 0x00020000) >> 16) |
  268. ((ui32IntFlags & 0x00040000) >> 19));
  269. HWREG(ui32Base + SHAMD5_O_IRQENABLE) &= ~(ui32IntFlags & 0x0000ffff);
  270. //
  271. // If there are no interrupts enabled, then disable all interrupts.
  272. //
  273. if(HWREG(ui32Base + SHAMD5_O_IRQENABLE) == 0x0)
  274. {
  275. HWREG(ui32Base + SHAMD5_O_SYSCONFIG) &= ~SHAMD5_SYSCONFIG_IT_EN;
  276. }
  277. }
  278. //*****************************************************************************
  279. //
  280. //! Clears interrupt sources in the SHA/MD5 module.
  281. //!
  282. //! \param ui32Base is the base address of the SHA/MD5 module.
  283. //! \param ui32IntFlags contains desired interrupts to disable.
  284. //!
  285. //! \e ui32IntFlags must be a logical OR of one or more of the following
  286. //! values:
  287. //!
  288. //! - \b SHAMD5_INT_CONTEXT_READY - Context input registers are ready.
  289. //! - \b SHAMD5_INT_PARTHASH_READY - Context output registers are ready after
  290. //! a context switch.
  291. //! - \b SHAMD5_INT_INPUT_READY - Data FIFO is ready to receive data.
  292. //! - \b SHAMD5_INT_OUTPUT_READY - Context output registers are ready.
  293. //!
  294. //! \return None.
  295. //
  296. //*****************************************************************************
  297. void
  298. SHAMD5IntClear(uint32_t ui32Base, uint32_t ui32IntFlags)
  299. {
  300. //
  301. // Check the arguments.
  302. //
  303. ASSERT(ui32Base == SHAMD5_BASE);
  304. ASSERT((ui32IntFlags == SHAMD5_INT_CONTEXT_READY) ||
  305. (ui32IntFlags == SHAMD5_INT_PARTHASH_READY) ||
  306. (ui32IntFlags == SHAMD5_INT_INPUT_READY) ||
  307. (ui32IntFlags == SHAMD5_INT_OUTPUT_READY));
  308. //
  309. // Clear the corresponding flags disabling the interrupt sources.
  310. //
  311. HWREG(ui32Base + SHAMD5_O_DMAIC) = (((ui32IntFlags & 0x00010000) >> 14) |
  312. ((ui32IntFlags & 0x00020000) >> 16) |
  313. ((ui32IntFlags & 0x00040000) >> 19));
  314. }
  315. //*****************************************************************************
  316. //
  317. //! Registers an interrupt handler for the SHA/MD5 module.
  318. //!
  319. //! \param ui32Base is the base address of the SHA/MD5 module.
  320. //! \param pfnHandler is a pointer to the function to be called when the
  321. //! enabled SHA/MD5 interrupts occur.
  322. //!
  323. //! This function registers the interrupt handler in the interrupt vector
  324. //! table, and enables SHA/MD5 interrupts on the interrupt controller;
  325. //! specific SHA/MD5 interrupt sources must be enabled using
  326. //! SHAMD5IntEnable(). The interrupt handler being registered must clear
  327. //! the source of the interrupt using SHAMD5IntClear().
  328. //!
  329. //! If the application is using a static interrupt vector table stored in
  330. //! flash, then it is not necessary to register the interrupt handler this way.
  331. //! Instead, IntEnable() should be used to enable SHA/MD5 interrupts on the
  332. //! interrupt controller.
  333. //!
  334. //! \sa IntRegister() for important information about registering interrupt
  335. //! handlers.
  336. //!
  337. //! \return None.
  338. //
  339. //*****************************************************************************
  340. void
  341. SHAMD5IntRegister(uint32_t ui32Base, void (*pfnHandler)(void))
  342. {
  343. //
  344. // Check the arguments.
  345. //
  346. ASSERT(ui32Base == SHAMD5_BASE);
  347. //
  348. // Register the interrupt handler.
  349. //
  350. IntRegister(INT_SHA0_TM4C129, pfnHandler);
  351. //
  352. // Enable the interrupt
  353. //
  354. IntEnable(INT_SHA0_TM4C129);
  355. }
  356. //*****************************************************************************
  357. //
  358. //! Unregisters an interrupt handler for the SHA/MD5 module.
  359. //!
  360. //! \param ui32Base is the base address of the SHA/MD5 module.
  361. //!
  362. //! This function unregisters the previously registered interrupt handler and
  363. //! disables the interrupt in the interrupt controller.
  364. //!
  365. //! \sa IntRegister() for important information about registering interrupt
  366. //! handlers.
  367. //!
  368. //! \return None.
  369. //
  370. //*****************************************************************************
  371. void
  372. SHAMD5IntUnregister(uint32_t ui32Base)
  373. {
  374. //
  375. // Check the arguments.
  376. //
  377. ASSERT(ui32Base == SHAMD5_BASE);
  378. //
  379. // Disable the interrupt.
  380. //
  381. IntDisable(INT_SHA0_TM4C129);
  382. //
  383. // Unregister the interrupt handler.
  384. //
  385. IntUnregister(INT_SHA0_TM4C129);
  386. }
  387. //*****************************************************************************
  388. //
  389. //! Write the hash length to the SHA/MD5 module.
  390. //!
  391. //! \param ui32Base is the base address of the SHA/MD5 module.
  392. //! \param ui32Length is the hash length in bytes.
  393. //!
  394. //! This function writes the length of the hash data of the current operation
  395. //! to the SHA/MD5 module. The value must be a multiple of 64 if the close
  396. //! hash is not set in the mode register.
  397. //!
  398. //! \note When this register is written, hash processing is triggered.
  399. //!
  400. //! \return None.
  401. //
  402. //*****************************************************************************
  403. void
  404. SHAMD5HashLengthSet(uint32_t ui32Base, uint32_t ui32Length)
  405. {
  406. //
  407. // Check the arguments.
  408. //
  409. ASSERT(ui32Base == SHAMD5_BASE);
  410. //
  411. // Set the LENGTH register and start processing.
  412. //
  413. HWREG(ui32Base + SHAMD5_O_LENGTH) = ui32Length;
  414. }
  415. //*****************************************************************************
  416. //
  417. //! Writes the mode in the SHA/MD5 module.
  418. //!
  419. //! \param ui32Base is the base address of the SHA/MD5 module.
  420. //! \param ui32Mode is the mode of the SHA/MD5 module.
  421. //!
  422. //! This function writes the mode register configuring the SHA/MD5 module.
  423. //!
  424. //! The ui32Mode parameter is a bit-wise OR of values:
  425. //!
  426. //! - \b SHAMD5_ALGO_MD5 - Regular hash with MD5
  427. //! - \b SHAMD5_ALGO_SHA1 - Regular hash with SHA-1
  428. //! - \b SHAMD5_ALGO_SHA224 - Regular hash with SHA-224
  429. //! - \b SHAMD5_ALGO_SHA256 - Regular hash with SHA-256
  430. //! - \b SHAMD5_ALGO_HMAC_MD5 - HMAC with MD5
  431. //! - \b SHAMD5_ALGO_HMAC_SHA1 - HMAC with SHA-1
  432. //! - \b SHAMD5_ALGO_HMAC_SHA224 - HMAC with SHA-224
  433. //! - \b SHAMD5_ALGO_HMAC_SHA256 - HMAC with SHA-256
  434. //!
  435. //! \return None
  436. //
  437. //*****************************************************************************
  438. void
  439. SHAMD5ConfigSet(uint32_t ui32Base, uint32_t ui32Mode)
  440. {
  441. //
  442. // Check the arguments.
  443. //
  444. ASSERT(ui32Base == SHAMD5_BASE);
  445. ASSERT((ui32Mode == SHAMD5_ALGO_MD5) ||
  446. (ui32Mode == SHAMD5_ALGO_SHA1) ||
  447. (ui32Mode == SHAMD5_ALGO_SHA224) ||
  448. (ui32Mode == SHAMD5_ALGO_SHA256) ||
  449. (ui32Mode == SHAMD5_ALGO_HMAC_MD5) ||
  450. (ui32Mode == SHAMD5_ALGO_HMAC_SHA1) ||
  451. (ui32Mode == SHAMD5_ALGO_HMAC_SHA224) ||
  452. (ui32Mode == SHAMD5_ALGO_HMAC_SHA256));
  453. //
  454. // Write the value in the MODE register.
  455. //
  456. HWREG(ui32Base + SHAMD5_O_MODE) = ui32Mode;
  457. }
  458. //*****************************************************************************
  459. //
  460. //! Perform a non-blocking write of 16 words of data to the SHA/MD5 module.
  461. //!
  462. //! \param ui32Base is the base address of the SHA/MD5 module.
  463. //! \param pui32Src is the pointer to the 16-word array of data that will be
  464. //! written.
  465. //!
  466. //! This function writes 16 words of data into the data register regardless
  467. //! of whether or not the module is ready to accept the data.
  468. //!
  469. //! \return This function returns true if the write completed successfully.
  470. //! It returns false if the module was not ready.
  471. //
  472. //*****************************************************************************
  473. bool
  474. SHAMD5DataWriteNonBlocking(uint32_t ui32Base, uint32_t *pui32Src)
  475. {
  476. uint32_t ui32Counter;
  477. //
  478. // Check the arguments.
  479. //
  480. ASSERT(ui32Base == SHAMD5_BASE);
  481. //
  482. // Check that the SHA/MD5 module is ready for data. If not, return false.
  483. //
  484. if((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_INPUT_READY) == 0)
  485. {
  486. return(false);
  487. }
  488. //
  489. // Write the 16 words of data.
  490. //
  491. for(ui32Counter = 0; ui32Counter < 64; ui32Counter += 4)
  492. {
  493. HWREG(ui32Base + SHAMD5_O_DATA_0_IN + ui32Counter) = *pui32Src++;
  494. }
  495. //
  496. // Return true as a sign of successfully completing the function.
  497. //
  498. return(true);
  499. }
  500. //*****************************************************************************
  501. //
  502. //! Perform a blocking write of 16 words of data to the SHA/MD5 module.
  503. //!
  504. //! \param ui32Base is the base address of the SHA/MD5 module.
  505. //! \param pui32Src is the pointer to the 16-word array of data that will be
  506. //! written.
  507. //!
  508. //! This function does not return until the module is ready to accept data and
  509. //! the data has been written.
  510. //!
  511. //! \return None.
  512. //
  513. //*****************************************************************************
  514. void
  515. SHAMD5DataWrite(uint32_t ui32Base, uint32_t *pui32Src)
  516. {
  517. uint32_t ui32Counter;
  518. //
  519. // Check the arguments.
  520. //
  521. ASSERT(ui32Base == SHAMD5_BASE);
  522. //
  523. // Wait for the module to be ready to accept data.
  524. //
  525. while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_INPUT_READY) == 0)
  526. {
  527. }
  528. //
  529. // Write the 16 words of data.
  530. //
  531. for(ui32Counter = 0; ui32Counter < 64; ui32Counter += 4)
  532. {
  533. HWREG(ui32Base + SHAMD5_O_DATA_0_IN + ui32Counter) = *pui32Src++;
  534. }
  535. }
  536. //*****************************************************************************
  537. //
  538. //! Reads the result of a hashing operation.
  539. //!
  540. //! \param ui32Base is the base address of the SHA/MD5 module.
  541. //! \param pui32Dest is the pointer to the 16-word array of data that will be
  542. //! written.
  543. //!
  544. //! This function does not return until the module is ready to accept data and
  545. //! the data has been written.
  546. //!
  547. //! \return None.
  548. //
  549. //*****************************************************************************
  550. void
  551. SHAMD5ResultRead(uint32_t ui32Base, uint32_t *pui32Dest)
  552. {
  553. uint32_t ui32Idx, ui32Count;
  554. //
  555. // Check the arguments.
  556. //
  557. ASSERT(ui32Base == SHAMD5_BASE);
  558. //
  559. // Determine the number of bytes in the result, based on the hash type.
  560. //
  561. switch(HWREG(ui32Base + SHAMD5_O_MODE) & SHAMD5_MODE_ALGO_M)
  562. {
  563. //
  564. // The MD5 hash is being used.
  565. //
  566. case SHAMD5_MODE_ALGO_MD5:
  567. {
  568. //
  569. // There are 16 bytes in the MD5 hash.
  570. //
  571. ui32Count = 16;
  572. //
  573. // Done.
  574. //
  575. break;
  576. }
  577. //
  578. // The SHA-1 hash is being used.
  579. //
  580. case SHAMD5_MODE_ALGO_SHA1:
  581. {
  582. //
  583. // There are 20 bytes in the SHA-1 hash.
  584. //
  585. ui32Count = 20;
  586. //
  587. // Done.
  588. //
  589. break;
  590. }
  591. //
  592. // The SHA-224 hash is being used.
  593. //
  594. case SHAMD5_MODE_ALGO_SHA224:
  595. {
  596. //
  597. // There are 28 bytes in the SHA-224 hash.
  598. //
  599. ui32Count = 28;
  600. //
  601. // Done.
  602. //
  603. break;
  604. }
  605. //
  606. // The SHA-256 hash is being used.
  607. //
  608. case SHAMD5_MODE_ALGO_SHA256:
  609. {
  610. //
  611. // There are 32 bytes in the SHA-256 hash.
  612. //
  613. ui32Count = 32;
  614. //
  615. // Done.
  616. //
  617. break;
  618. }
  619. //
  620. // The hash type is not recognized.
  621. //
  622. default:
  623. {
  624. //
  625. // Return without reading a result since the hardware appears to be
  626. // misconfigured.
  627. //
  628. return;
  629. }
  630. }
  631. //
  632. // Read the hash result.
  633. //
  634. for(ui32Idx = 0; ui32Idx < ui32Count; ui32Idx += 4)
  635. {
  636. *pui32Dest++ = HWREG(ui32Base + SHAMD5_O_IDIGEST_A + ui32Idx);
  637. }
  638. }
  639. //*****************************************************************************
  640. //
  641. //! Writes multiple words of data into the SHA/MD5 data registers.
  642. //!
  643. //! \param ui32Base is the base address of the SHA/MD5 module.
  644. //! \param pui32DataSrc is a pointer to an array of data to be written.
  645. //! \param ui32DataLength is the length of the data to be written in bytes.
  646. //!
  647. //! This function writes a variable number of words into the SHA/MD5 data
  648. //! registers. The function waits for each block of data to be processed
  649. //! before another is written. The \e ui32DataLength parameter must be a
  650. //! multiple of 4 to fall on a word boundry.
  651. //!
  652. //! \note This function is used by SHAMD5DataProcess() and SHAMD5HMACProcess()
  653. //! to process data.
  654. //!
  655. //! \return None.
  656. //
  657. //*****************************************************************************
  658. static void
  659. _SHAMD5DataWriteMultiple(uint32_t ui32Base, uint32_t *pui32DataSrc,
  660. uint32_t ui32DataLength)
  661. {
  662. uint32_t ui32Idx, ui32Count;
  663. //
  664. // Check the arguments.
  665. //
  666. ASSERT(ui32Base == SHAMD5_BASE);
  667. //
  668. // Calculate the number of blocks of data.
  669. //
  670. ui32Count = ui32DataLength / 64;
  671. //
  672. // Loop through all the blocks and write them into the data registers
  673. // making sure to block additional operations until we can write the
  674. // next 16 words.
  675. //
  676. for(ui32Idx = 0; ui32Idx < ui32Count; ui32Idx++)
  677. {
  678. //
  679. // Write the block of data.
  680. //
  681. SHAMD5DataWrite(ui32Base, pui32DataSrc);
  682. //
  683. // Increment the pointer to next block of data.
  684. //
  685. pui32DataSrc += 16;
  686. }
  687. //
  688. // Calculate the remaining bytes of data that don't make up a full block.
  689. //
  690. ui32Count = ui32DataLength % 64;
  691. //
  692. // If there are bytes that do not make up a whole block, then
  693. // write them separately.
  694. //
  695. if(ui32Count)
  696. {
  697. //
  698. // Wait until the engine has finished processing the previous block.
  699. //
  700. while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) &
  701. SHAMD5_INT_INPUT_READY) == 0)
  702. {
  703. }
  704. //
  705. // Loop through the remaining words.
  706. //
  707. for(ui32Idx = 0; ui32Idx < ui32Count; ui32Idx += 4)
  708. {
  709. //
  710. // Write the word into the data register.
  711. //
  712. HWREG(ui32Base + SHAMD5_O_DATA_0_IN + ui32Idx) = *pui32DataSrc++;
  713. }
  714. }
  715. }
  716. //*****************************************************************************
  717. //
  718. //! Compute a hash using the SHA/MD5 module.
  719. //!
  720. //! \param ui32Base is the base address of the SHA/MD5 module.
  721. //! \param pui32DataSrc is a pointer to an array of data that contains the
  722. //! data that will be hashed.
  723. //! \param ui32DataLength specifies the length of the data to be hashed in
  724. //! bytes.
  725. //! \param pui32HashResult is a pointer to an array that holds the result
  726. //! of the hashing operation.
  727. //!
  728. //! This function computes the hash of an array of data using the SHA/MD5
  729. //! module.
  730. //!
  731. //! The length of the hash result is dependent on the algorithm that is in use.
  732. //! The following table shows the correct array size for each algorithm:
  733. //!
  734. //! -----------------------------------------
  735. //! | Algorithm | Number of Words in Result |
  736. //! -----------------------------------------
  737. //! | MD5 | 4 Words (128 bits) |
  738. //! | SHA-1 | 5 Words (160 bits) |
  739. //! | SHA-224 | 7 Words (224 bits) |
  740. //! | SHA-256 | 8 Words (256 bits) |
  741. //! -----------------------------------------
  742. //!
  743. //! \return None
  744. //
  745. //*****************************************************************************
  746. void
  747. SHAMD5DataProcess(uint32_t ui32Base, uint32_t *pui32DataSrc,
  748. uint32_t ui32DataLength, uint32_t *pui32HashResult)
  749. {
  750. //
  751. // Check the arguments.
  752. //
  753. ASSERT(ui32Base == SHAMD5_BASE);
  754. ASSERT((ui32DataLength % 64) == 0);
  755. //
  756. // Wait for the context to be ready before writing the mode.
  757. //
  758. while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_CONTEXT_READY) ==
  759. 0)
  760. {
  761. }
  762. //
  763. // Write the length.
  764. //
  765. SHAMD5HashLengthSet(ui32Base, ui32DataLength);
  766. //
  767. // Write the data.
  768. //
  769. _SHAMD5DataWriteMultiple(ui32Base, pui32DataSrc, ui32DataLength);
  770. //
  771. // Wait for the output to be ready.
  772. //
  773. while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY) ==
  774. 0)
  775. {
  776. }
  777. //
  778. // Read the result.
  779. //
  780. SHAMD5ResultRead(ui32Base, pui32HashResult);
  781. }
  782. //*****************************************************************************
  783. //
  784. //! Compute a HMAC with key pre-processing using the SHA/MD5 module.
  785. //!
  786. //! \param ui32Base is the base address of the SHA/MD5 module.
  787. //! \param pui32DataSrc is a pointer to an array of data that contains the
  788. //! data that is to be hashed.
  789. //! \param ui32DataLength specifies the length of the data to be hashed in
  790. //! bytes.
  791. //! \param pui32HashResult is a pointer to an array that holds the result
  792. //! of the hashing operation.
  793. //!
  794. //! This function computes a HMAC with the given data using the SHA/MD5
  795. //! module with a preprocessed key.
  796. //!
  797. //! The length of the hash result is dependent on the algorithm that is
  798. //! selected with the \e ui32Algo argument. The following table shows the
  799. //! correct array size for each algorithm:
  800. //!
  801. //! -----------------------------------------
  802. //! | Algorithm | Number of Words in Result |
  803. //! -----------------------------------------
  804. //! | MD5 | 4 Words (128 bits) |
  805. //! | SHA-1 | 5 Words (160 bits) |
  806. //! | SHA-224 | 7 Words (224 bits) |
  807. //! | SHA-256 | 8 Words (256 bits) |
  808. //! -----------------------------------------
  809. //!
  810. //! \return None
  811. //
  812. //*****************************************************************************
  813. void
  814. SHAMD5HMACProcess(uint32_t ui32Base, uint32_t *pui32DataSrc,
  815. uint32_t ui32DataLength, uint32_t *pui32HashResult)
  816. {
  817. //
  818. // Check the arguments.
  819. //
  820. ASSERT(ui32Base == SHAMD5_BASE);
  821. //
  822. // Wait for the context to be ready before writing the mode.
  823. //
  824. while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_CONTEXT_READY) ==
  825. 0)
  826. {
  827. }
  828. //
  829. // Write the length.
  830. //
  831. SHAMD5HashLengthSet(ui32Base, ui32DataLength);
  832. //
  833. // Write the data in the registers.
  834. //
  835. _SHAMD5DataWriteMultiple(ui32Base, pui32DataSrc, ui32DataLength);
  836. //
  837. // Wait for the output to be ready.
  838. //
  839. while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY) ==
  840. 0)
  841. {
  842. }
  843. //
  844. // Read the result.
  845. //
  846. SHAMD5ResultRead(ui32Base, pui32HashResult);
  847. }
  848. //*****************************************************************************
  849. //
  850. //! Process an HMAC key using the SHA/MD5 module.
  851. //!
  852. //! \param ui32Base is the base address of the SHA/MD5 module.
  853. //! \param pui32Key is a pointer to an array that contains the key to be
  854. //! processed.
  855. //! \param pui32PPKey is the pointer to the array that contains the
  856. //! pre-processed key.
  857. //!
  858. //! This function processes an HMAC key using the SHA/MD5. The resultant
  859. //! pre-processed key can then be used with later HMAC operations to speed
  860. //! processing time.
  861. //!
  862. //! The \e pui32Key array must be 16 words (512 bits) long. If the key is less
  863. //! than 512 bits, it must be padded with zeros. The \e pui32PPKey array must
  864. //! each be 16 words (512 bits) long.
  865. //!
  866. //! \return None
  867. //
  868. //*****************************************************************************
  869. void
  870. SHAMD5HMACPPKeyGenerate(uint32_t ui32Base, uint32_t *pui32Key,
  871. uint32_t *pui32PPKey)
  872. {
  873. uint32_t ui32Index;
  874. //
  875. // Check the arguments.
  876. //
  877. ASSERT(ui32Base == SHAMD5_BASE);
  878. //
  879. // Wait for the context to be ready before writing the mode.
  880. //
  881. while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_CONTEXT_READY) ==
  882. 0)
  883. {
  884. }
  885. //
  886. // Write the HMAC key.
  887. //
  888. for(ui32Index = 0; ui32Index < 64; ui32Index += 4)
  889. {
  890. HWREG(ui32Base + SHAMD5_O_ODIGEST_A + ui32Index) = *pui32Key++;
  891. }
  892. //
  893. // Set the flag to cause the HMAC key to be pre-processed.
  894. //
  895. HWREG(ui32Base + SHAMD5_O_MODE) |= SHAMD5_MODE_HMAC_KEY_PROC;
  896. //
  897. // Set the length to zero to start the HMAC key pre-processing.
  898. //
  899. HWREG(ui32Base + SHAMD5_O_LENGTH) = 0;
  900. //
  901. // Wait for key to be processed.
  902. //
  903. while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY) ==
  904. 0)
  905. {
  906. }
  907. //
  908. // Read the pre-processed key from the SHA/MD5 module.
  909. //
  910. for(ui32Index = 0; ui32Index < 64; ui32Index += 4)
  911. {
  912. *pui32PPKey++ = HWREG(ui32Base + SHAMD5_O_ODIGEST_A + ui32Index);
  913. }
  914. }
  915. //*****************************************************************************
  916. //
  917. //! Writes an HMAC key to the digest registers in the SHA/MD5 module.
  918. //!
  919. //! \param ui32Base is the base address of the SHA/MD5 module.
  920. //! \param pui32Src is the pointer to the 16-word array of the HMAC key.
  921. //!
  922. //! This function is used to write HMAC key to the digest registers for
  923. //! key preprocessing. The size of pui32Src must be 512 bytes. If the key is
  924. //! less than 512 bytes, then it must be padded with zeros.
  925. //!
  926. //! \note It is recommended to use the SHAMD5IntStatus() function to check
  927. //! whether the context is ready before writing the key.
  928. //!
  929. //! \return None
  930. //
  931. //*****************************************************************************
  932. void
  933. SHAMD5HMACKeySet(uint32_t ui32Base, uint32_t *pui32Src)
  934. {
  935. uint32_t ui32Idx;
  936. //
  937. // Check the arguments.
  938. //
  939. ASSERT(ui32Base == SHAMD5_BASE);
  940. //
  941. // Write the key to the digest registers.
  942. //
  943. for(ui32Idx = 0; ui32Idx < 64; ui32Idx += 4)
  944. {
  945. HWREG(ui32Base + SHAMD5_O_ODIGEST_A + ui32Idx) = *pui32Src++;
  946. }
  947. //
  948. // Configure the SHA engine for HMAC operation.
  949. //
  950. HWREG(ui32Base + SHAMD5_O_MODE) |= (SHAMD5_MODE_HMAC_OUTER_HASH |
  951. SHAMD5_MODE_HMAC_KEY_PROC |
  952. SHAMD5_MODE_CLOSE_HASH);
  953. }
  954. //*****************************************************************************
  955. //
  956. //! Writes a pre-processed HMAC key to the digest registers in the SHA/MD5
  957. //! module.
  958. //!
  959. //! \param ui32Base is the base address of the SHA/MD5 module.
  960. //! \param pui32Src is the pointer to the 16-word array of the HMAC key.
  961. //!
  962. //! This function is used to write HMAC key to the digest registers for
  963. //! key preprocessing. The size of pui32Src must be 512 bytes. If the key is
  964. //! less than 512 bytes, then it must be padded with zeros.
  965. //!
  966. //! \note It is recommended to use the SHAMD5IntStatus() function to check
  967. //! whether the context is ready before writing the key.
  968. //!
  969. //! \return None
  970. //
  971. //*****************************************************************************
  972. void
  973. SHAMD5HMACPPKeySet(uint32_t ui32Base, uint32_t *pui32Src)
  974. {
  975. uint32_t ui32Idx;
  976. //
  977. // Check the arguments.
  978. //
  979. ASSERT(ui32Base == SHAMD5_BASE);
  980. //
  981. // Write the key to the digest registers.
  982. //
  983. for(ui32Idx = 0; ui32Idx < 64; ui32Idx += 4)
  984. {
  985. HWREG(ui32Base + SHAMD5_O_ODIGEST_A + ui32Idx) = *pui32Src++;
  986. }
  987. //
  988. // Configure the SHA engine to continue the HMAC.
  989. //
  990. HWREG(ui32Base + SHAMD5_O_MODE) |= (SHAMD5_MODE_HMAC_OUTER_HASH |
  991. SHAMD5_MODE_CLOSE_HASH);
  992. //
  993. // Write the digest count to 64 to account for the preprocessed key.
  994. //
  995. HWREG(ui32Base + SHAMD5_O_DIGEST_COUNT) = 64;
  996. }
  997. //*****************************************************************************
  998. //
  999. // Close the Doxygen group.
  1000. //! @}
  1001. //
  1002. //*****************************************************************************