stm32f4xx_hash_md5.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_hash_md5.c
  4. * @author MCD Application Team
  5. * @version V1.5.0
  6. * @date 06-March-2015
  7. * @brief This file provides high level functions to compute the HASH MD5 and
  8. * HMAC MD5 Digest of an input message.
  9. * It uses the stm32f4xx_hash.c/.h drivers to access the STM32F4xx HASH
  10. * peripheral.
  11. *
  12. @verbatim
  13. ===================================================================
  14. ##### How to use this driver #####
  15. ===================================================================
  16. [..]
  17. (#) Enable The HASH controller clock using
  18. RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE); function.
  19. (#) Calculate the HASH MD5 Digest using HASH_MD5() function.
  20. (#) Calculate the HMAC MD5 Digest using HMAC_MD5() function.
  21. @endverbatim
  22. *
  23. ******************************************************************************
  24. * @attention
  25. *
  26. * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
  27. *
  28. * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  29. * You may not use this file except in compliance with the License.
  30. * You may obtain a copy of the License at:
  31. *
  32. * http://www.st.com/software_license_agreement_liberty_v2
  33. *
  34. * Unless required by applicable law or agreed to in writing, software
  35. * distributed under the License is distributed on an "AS IS" BASIS,
  36. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  37. * See the License for the specific language governing permissions and
  38. * limitations under the License.
  39. *
  40. ******************************************************************************
  41. */
  42. /* Includes ------------------------------------------------------------------*/
  43. #include "stm32f4xx_hash.h"
  44. /** @addtogroup STM32F4xx_StdPeriph_Driver
  45. * @{
  46. */
  47. /** @defgroup HASH
  48. * @brief HASH driver modules
  49. * @{
  50. */
  51. /* Private typedef -----------------------------------------------------------*/
  52. /* Private define ------------------------------------------------------------*/
  53. #define MD5BUSY_TIMEOUT ((uint32_t) 0x00010000)
  54. /* Private macro -------------------------------------------------------------*/
  55. /* Private variables ---------------------------------------------------------*/
  56. /* Private function prototypes -----------------------------------------------*/
  57. /* Private functions ---------------------------------------------------------*/
  58. /** @defgroup HASH_Private_Functions
  59. * @{
  60. */
  61. /** @defgroup HASH_Group7 High Level MD5 functions
  62. * @brief High Level MD5 Hash and HMAC functions
  63. *
  64. @verbatim
  65. ===============================================================================
  66. ##### High Level MD5 Hash and HMAC functions #####
  67. ===============================================================================
  68. @endverbatim
  69. * @{
  70. */
  71. /**
  72. * @brief Compute the HASH MD5 digest.
  73. * @param Input: pointer to the Input buffer to be treated.
  74. * @param Ilen: length of the Input buffer.
  75. * @param Output: the returned digest
  76. * @retval An ErrorStatus enumeration value:
  77. * - SUCCESS: digest computation done
  78. * - ERROR: digest computation failed
  79. */
  80. ErrorStatus HASH_MD5(uint8_t *Input, uint32_t Ilen, uint8_t Output[16])
  81. {
  82. HASH_InitTypeDef MD5_HASH_InitStructure;
  83. HASH_MsgDigest MD5_MessageDigest;
  84. __IO uint16_t nbvalidbitsdata = 0;
  85. uint32_t i = 0;
  86. __IO uint32_t counter = 0;
  87. uint32_t busystatus = 0;
  88. ErrorStatus status = SUCCESS;
  89. uint32_t inputaddr = (uint32_t)Input;
  90. uint32_t outputaddr = (uint32_t)Output;
  91. /* Number of valid bits in last word of the Input data */
  92. nbvalidbitsdata = 8 * (Ilen % 4);
  93. /* HASH peripheral initialization */
  94. HASH_DeInit();
  95. /* HASH Configuration */
  96. MD5_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_MD5;
  97. MD5_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH;
  98. MD5_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
  99. HASH_Init(&MD5_HASH_InitStructure);
  100. /* Configure the number of valid bits in last word of the data */
  101. HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
  102. /* Write the Input block in the IN FIFO */
  103. for(i=0; i<Ilen; i+=4)
  104. {
  105. HASH_DataIn(*(uint32_t*)inputaddr);
  106. inputaddr+=4;
  107. }
  108. /* Start the HASH processor */
  109. HASH_StartDigest();
  110. /* wait until the Busy flag is RESET */
  111. do
  112. {
  113. busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
  114. counter++;
  115. }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
  116. if (busystatus != RESET)
  117. {
  118. status = ERROR;
  119. }
  120. else
  121. {
  122. /* Read the message digest */
  123. HASH_GetDigest(&MD5_MessageDigest);
  124. *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[0]);
  125. outputaddr+=4;
  126. *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[1]);
  127. outputaddr+=4;
  128. *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[2]);
  129. outputaddr+=4;
  130. *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[3]);
  131. }
  132. return status;
  133. }
  134. /**
  135. * @brief Compute the HMAC MD5 digest.
  136. * @param Key: pointer to the Key used for HMAC.
  137. * @param Keylen: length of the Key used for HMAC.
  138. * @param Input: pointer to the Input buffer to be treated.
  139. * @param Ilen: length of the Input buffer.
  140. * @param Output: the returned digest
  141. * @retval An ErrorStatus enumeration value:
  142. * - SUCCESS: digest computation done
  143. * - ERROR: digest computation failed
  144. */
  145. ErrorStatus HMAC_MD5(uint8_t *Key, uint32_t Keylen, uint8_t *Input,
  146. uint32_t Ilen, uint8_t Output[16])
  147. {
  148. HASH_InitTypeDef MD5_HASH_InitStructure;
  149. HASH_MsgDigest MD5_MessageDigest;
  150. __IO uint16_t nbvalidbitsdata = 0;
  151. __IO uint16_t nbvalidbitskey = 0;
  152. uint32_t i = 0;
  153. __IO uint32_t counter = 0;
  154. uint32_t busystatus = 0;
  155. ErrorStatus status = SUCCESS;
  156. uint32_t keyaddr = (uint32_t)Key;
  157. uint32_t inputaddr = (uint32_t)Input;
  158. uint32_t outputaddr = (uint32_t)Output;
  159. /* Number of valid bits in last word of the Input data */
  160. nbvalidbitsdata = 8 * (Ilen % 4);
  161. /* Number of valid bits in last word of the Key */
  162. nbvalidbitskey = 8 * (Keylen % 4);
  163. /* HASH peripheral initialization */
  164. HASH_DeInit();
  165. /* HASH Configuration */
  166. MD5_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_MD5;
  167. MD5_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HMAC;
  168. MD5_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
  169. if(Keylen > 64)
  170. {
  171. /* HMAC long Key */
  172. MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey;
  173. }
  174. else
  175. {
  176. /* HMAC short Key */
  177. MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey;
  178. }
  179. HASH_Init(&MD5_HASH_InitStructure);
  180. /* Configure the number of valid bits in last word of the Key */
  181. HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
  182. /* Write the Key */
  183. for(i=0; i<Keylen; i+=4)
  184. {
  185. HASH_DataIn(*(uint32_t*)keyaddr);
  186. keyaddr+=4;
  187. }
  188. /* Start the HASH processor */
  189. HASH_StartDigest();
  190. /* wait until the Busy flag is RESET */
  191. do
  192. {
  193. busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
  194. counter++;
  195. }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
  196. if (busystatus != RESET)
  197. {
  198. status = ERROR;
  199. }
  200. else
  201. {
  202. /* Configure the number of valid bits in last word of the Input data */
  203. HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
  204. /* Write the Input block in the IN FIFO */
  205. for(i=0; i<Ilen; i+=4)
  206. {
  207. HASH_DataIn(*(uint32_t*)inputaddr);
  208. inputaddr+=4;
  209. }
  210. /* Start the HASH processor */
  211. HASH_StartDigest();
  212. /* wait until the Busy flag is RESET */
  213. counter =0;
  214. do
  215. {
  216. busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
  217. counter++;
  218. }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
  219. if (busystatus != RESET)
  220. {
  221. status = ERROR;
  222. }
  223. else
  224. {
  225. /* Configure the number of valid bits in last word of the Key */
  226. HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
  227. /* Write the Key */
  228. keyaddr = (uint32_t)Key;
  229. for(i=0; i<Keylen; i+=4)
  230. {
  231. HASH_DataIn(*(uint32_t*)keyaddr);
  232. keyaddr+=4;
  233. }
  234. /* Start the HASH processor */
  235. HASH_StartDigest();
  236. /* wait until the Busy flag is RESET */
  237. counter =0;
  238. do
  239. {
  240. busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
  241. counter++;
  242. }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
  243. if (busystatus != RESET)
  244. {
  245. status = ERROR;
  246. }
  247. else
  248. {
  249. /* Read the message digest */
  250. HASH_GetDigest(&MD5_MessageDigest);
  251. *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[0]);
  252. outputaddr+=4;
  253. *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[1]);
  254. outputaddr+=4;
  255. *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[2]);
  256. outputaddr+=4;
  257. *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[3]);
  258. }
  259. }
  260. }
  261. return status;
  262. }
  263. /**
  264. * @}
  265. */
  266. /**
  267. * @}
  268. */
  269. /**
  270. * @}
  271. */
  272. /**
  273. * @}
  274. */
  275. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/