stm32f4xx_hash_sha1.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_hash_sha1.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 SHA1 and
  8. * HMAC SHA1 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 SHA1 Digest using HASH_SHA1() function.
  20. (#) Calculate the HMAC SHA1 Digest using HMAC_SHA1() 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 SHA1BUSY_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_Group6 High Level SHA1 functions
  62. * @brief High Level SHA1 Hash and HMAC functions
  63. *
  64. @verbatim
  65. ===============================================================================
  66. ##### High Level SHA1 Hash and HMAC functions #####
  67. ===============================================================================
  68. @endverbatim
  69. * @{
  70. */
  71. /**
  72. * @brief Compute the HASH SHA1 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_SHA1(uint8_t *Input, uint32_t Ilen, uint8_t Output[20])
  81. {
  82. HASH_InitTypeDef SHA1_HASH_InitStructure;
  83. HASH_MsgDigest SHA1_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. SHA1_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_SHA1;
  97. SHA1_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH;
  98. SHA1_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
  99. HASH_Init(&SHA1_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 != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
  116. if (busystatus != RESET)
  117. {
  118. status = ERROR;
  119. }
  120. else
  121. {
  122. /* Read the message digest */
  123. HASH_GetDigest(&SHA1_MessageDigest);
  124. *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[0]);
  125. outputaddr+=4;
  126. *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[1]);
  127. outputaddr+=4;
  128. *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[2]);
  129. outputaddr+=4;
  130. *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[3]);
  131. outputaddr+=4;
  132. *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[4]);
  133. }
  134. return status;
  135. }
  136. /**
  137. * @brief Compute the HMAC SHA1 digest.
  138. * @param Key: pointer to the Key used for HMAC.
  139. * @param Keylen: length of the Key used for HMAC.
  140. * @param Input: pointer to the Input buffer to be treated.
  141. * @param Ilen: length of the Input buffer.
  142. * @param Output: the returned digest
  143. * @retval An ErrorStatus enumeration value:
  144. * - SUCCESS: digest computation done
  145. * - ERROR: digest computation failed
  146. */
  147. ErrorStatus HMAC_SHA1(uint8_t *Key, uint32_t Keylen, uint8_t *Input,
  148. uint32_t Ilen, uint8_t Output[20])
  149. {
  150. HASH_InitTypeDef SHA1_HASH_InitStructure;
  151. HASH_MsgDigest SHA1_MessageDigest;
  152. __IO uint16_t nbvalidbitsdata = 0;
  153. __IO uint16_t nbvalidbitskey = 0;
  154. uint32_t i = 0;
  155. __IO uint32_t counter = 0;
  156. uint32_t busystatus = 0;
  157. ErrorStatus status = SUCCESS;
  158. uint32_t keyaddr = (uint32_t)Key;
  159. uint32_t inputaddr = (uint32_t)Input;
  160. uint32_t outputaddr = (uint32_t)Output;
  161. /* Number of valid bits in last word of the Input data */
  162. nbvalidbitsdata = 8 * (Ilen % 4);
  163. /* Number of valid bits in last word of the Key */
  164. nbvalidbitskey = 8 * (Keylen % 4);
  165. /* HASH peripheral initialization */
  166. HASH_DeInit();
  167. /* HASH Configuration */
  168. SHA1_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_SHA1;
  169. SHA1_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HMAC;
  170. SHA1_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
  171. if(Keylen > 64)
  172. {
  173. /* HMAC long Key */
  174. SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey;
  175. }
  176. else
  177. {
  178. /* HMAC short Key */
  179. SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey;
  180. }
  181. HASH_Init(&SHA1_HASH_InitStructure);
  182. /* Configure the number of valid bits in last word of the Key */
  183. HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
  184. /* Write the Key */
  185. for(i=0; i<Keylen; i+=4)
  186. {
  187. HASH_DataIn(*(uint32_t*)keyaddr);
  188. keyaddr+=4;
  189. }
  190. /* Start the HASH processor */
  191. HASH_StartDigest();
  192. /* wait until the Busy flag is RESET */
  193. do
  194. {
  195. busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
  196. counter++;
  197. }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
  198. if (busystatus != RESET)
  199. {
  200. status = ERROR;
  201. }
  202. else
  203. {
  204. /* Configure the number of valid bits in last word of the Input data */
  205. HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
  206. /* Write the Input block in the IN FIFO */
  207. for(i=0; i<Ilen; i+=4)
  208. {
  209. HASH_DataIn(*(uint32_t*)inputaddr);
  210. inputaddr+=4;
  211. }
  212. /* Start the HASH processor */
  213. HASH_StartDigest();
  214. /* wait until the Busy flag is RESET */
  215. counter =0;
  216. do
  217. {
  218. busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
  219. counter++;
  220. }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
  221. if (busystatus != RESET)
  222. {
  223. status = ERROR;
  224. }
  225. else
  226. {
  227. /* Configure the number of valid bits in last word of the Key */
  228. HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
  229. /* Write the Key */
  230. keyaddr = (uint32_t)Key;
  231. for(i=0; i<Keylen; i+=4)
  232. {
  233. HASH_DataIn(*(uint32_t*)keyaddr);
  234. keyaddr+=4;
  235. }
  236. /* Start the HASH processor */
  237. HASH_StartDigest();
  238. /* wait until the Busy flag is RESET */
  239. counter =0;
  240. do
  241. {
  242. busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
  243. counter++;
  244. }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
  245. if (busystatus != RESET)
  246. {
  247. status = ERROR;
  248. }
  249. else
  250. {
  251. /* Read the message digest */
  252. HASH_GetDigest(&SHA1_MessageDigest);
  253. *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[0]);
  254. outputaddr+=4;
  255. *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[1]);
  256. outputaddr+=4;
  257. *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[2]);
  258. outputaddr+=4;
  259. *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[3]);
  260. outputaddr+=4;
  261. *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[4]);
  262. }
  263. }
  264. }
  265. return status;
  266. }
  267. /**
  268. * @}
  269. */
  270. /**
  271. * @}
  272. */
  273. /**
  274. * @}
  275. */
  276. /**
  277. * @}
  278. */
  279. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/