2 ******************************************************************************
3 * @file stm32f4xx_hash_sha1.c
4 * @author MCD Application Team
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
14 * ===================================================================
15 * How to use this driver
16 * ===================================================================
17 * 1. Enable The HASH controller clock using
18 * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE); function.
20 * 2. Calculate the HASH SHA1 Digest using HASH_SHA1() function.
22 * 3. Calculate the HMAC SHA1 Digest using HMAC_SHA1() function.
26 ******************************************************************************
29 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
30 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
31 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
32 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
33 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
34 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
36 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
37 ******************************************************************************
40 /* Includes ------------------------------------------------------------------*/
41 #include "stm32f4xx_hash.h"
43 /** @addtogroup STM32F4xx_StdPeriph_Driver
48 * @brief HASH driver modules
52 /* Private typedef -----------------------------------------------------------*/
53 /* Private define ------------------------------------------------------------*/
54 #define SHA1BUSY_TIMEOUT ((uint32_t) 0x00010000)
56 /* Private macro -------------------------------------------------------------*/
57 /* Private variables ---------------------------------------------------------*/
58 /* Private function prototypes -----------------------------------------------*/
59 /* Private functions ---------------------------------------------------------*/
61 /** @defgroup HASH_Private_Functions
65 /** @defgroup HASH_Group6 High Level SHA1 functions
66 * @brief High Level SHA1 Hash and HMAC functions
69 ===============================================================================
70 High Level SHA1 Hash and HMAC functions
71 ===============================================================================
79 * @brief Compute the HASH SHA1 digest.
80 * @param Input: pointer to the Input buffer to be treated.
81 * @param Ilen: length of the Input buffer.
82 * @param Output: the returned digest
83 * @retval An ErrorStatus enumeration value:
84 * - SUCCESS: digest computation done
85 * - ERROR: digest computation failed
87 ErrorStatus HASH_SHA1(uint8_t *Input, uint32_t Ilen, uint8_t Output[20])
89 HASH_InitTypeDef SHA1_HASH_InitStructure;
90 HASH_MsgDigest SHA1_MessageDigest;
91 __IO uint16_t nbvalidbitsdata = 0;
93 __IO uint32_t counter = 0;
94 uint32_t busystatus = 0;
95 ErrorStatus status = SUCCESS;
96 uint32_t inputaddr = (uint32_t)Input;
97 uint32_t outputaddr = (uint32_t)Output;
99 /* Number of valid bits in last word of the Input data */
100 nbvalidbitsdata = 8 * (Ilen % 4);
102 /* HASH peripheral initialization */
105 /* HASH Configuration */
106 SHA1_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_SHA1;
107 SHA1_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH;
108 SHA1_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
109 HASH_Init(&SHA1_HASH_InitStructure);
111 /* Configure the number of valid bits in last word of the data */
112 HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
114 /* Write the Input block in the IN FIFO */
115 for(i=0; i<Ilen; i+=4)
117 HASH_DataIn(*(uint32_t*)inputaddr);
121 /* Start the HASH processor */
124 /* wait until the Busy flag is RESET */
127 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
129 }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
131 if (busystatus != RESET)
137 /* Read the message digest */
138 HASH_GetDigest(&SHA1_MessageDigest);
139 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[0]);
141 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[1]);
143 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[2]);
145 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[3]);
147 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[4]);
153 * @brief Compute the HMAC SHA1 digest.
154 * @param Key: pointer to the Key used for HMAC.
155 * @param Keylen: length of the Key used for HMAC.
156 * @param Input: pointer to the Input buffer to be treated.
157 * @param Ilen: length of the Input buffer.
158 * @param Output: the returned digest
159 * @retval An ErrorStatus enumeration value:
160 * - SUCCESS: digest computation done
161 * - ERROR: digest computation failed
163 ErrorStatus HMAC_SHA1(uint8_t *Key, uint32_t Keylen, uint8_t *Input,
164 uint32_t Ilen, uint8_t Output[20])
166 HASH_InitTypeDef SHA1_HASH_InitStructure;
167 HASH_MsgDigest SHA1_MessageDigest;
168 __IO uint16_t nbvalidbitsdata = 0;
169 __IO uint16_t nbvalidbitskey = 0;
171 __IO uint32_t counter = 0;
172 uint32_t busystatus = 0;
173 ErrorStatus status = SUCCESS;
174 uint32_t keyaddr = (uint32_t)Key;
175 uint32_t inputaddr = (uint32_t)Input;
176 uint32_t outputaddr = (uint32_t)Output;
178 /* Number of valid bits in last word of the Input data */
179 nbvalidbitsdata = 8 * (Ilen % 4);
181 /* Number of valid bits in last word of the Key */
182 nbvalidbitskey = 8 * (Keylen % 4);
184 /* HASH peripheral initialization */
187 /* HASH Configuration */
188 SHA1_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_SHA1;
189 SHA1_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HMAC;
190 SHA1_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
194 SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey;
199 SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey;
201 HASH_Init(&SHA1_HASH_InitStructure);
203 /* Configure the number of valid bits in last word of the Key */
204 HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
207 for(i=0; i<Keylen; i+=4)
209 HASH_DataIn(*(uint32_t*)keyaddr);
213 /* Start the HASH processor */
216 /* wait until the Busy flag is RESET */
219 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
221 }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
223 if (busystatus != RESET)
229 /* Configure the number of valid bits in last word of the Input data */
230 HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
232 /* Write the Input block in the IN FIFO */
233 for(i=0; i<Ilen; i+=4)
235 HASH_DataIn(*(uint32_t*)inputaddr);
239 /* Start the HASH processor */
243 /* wait until the Busy flag is RESET */
247 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
249 }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
251 if (busystatus != RESET)
257 /* Configure the number of valid bits in last word of the Key */
258 HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
261 keyaddr = (uint32_t)Key;
262 for(i=0; i<Keylen; i+=4)
264 HASH_DataIn(*(uint32_t*)keyaddr);
268 /* Start the HASH processor */
271 /* wait until the Busy flag is RESET */
275 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
277 }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
279 if (busystatus != RESET)
285 /* Read the message digest */
286 HASH_GetDigest(&SHA1_MessageDigest);
287 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[0]);
289 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[1]);
291 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[2]);
293 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[3]);
295 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[4]);
317 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/