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
13 ===================================================================
14 ##### How to use this driver #####
15 ===================================================================
17 (#) Enable The HASH controller clock using
18 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE); function.
20 (#) Calculate the HASH SHA1 Digest using HASH_SHA1() function.
22 (#) Calculate the HMAC SHA1 Digest using HMAC_SHA1() function.
26 ******************************************************************************
29 * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
31 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
32 * You may not use this file except in compliance with the License.
33 * You may obtain a copy of the License at:
35 * http://www.st.com/software_license_agreement_liberty_v2
37 * Unless required by applicable law or agreed to in writing, software
38 * distributed under the License is distributed on an "AS IS" BASIS,
39 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40 * See the License for the specific language governing permissions and
41 * limitations under the License.
43 ******************************************************************************
46 /* Includes ------------------------------------------------------------------*/
47 #include "stm32f4xx_hash.h"
49 /** @addtogroup STM32F4xx_StdPeriph_Driver
54 * @brief HASH driver modules
58 /* Private typedef -----------------------------------------------------------*/
59 /* Private define ------------------------------------------------------------*/
60 #define SHA1BUSY_TIMEOUT ((uint32_t) 0x00010000)
62 /* Private macro -------------------------------------------------------------*/
63 /* Private variables ---------------------------------------------------------*/
64 /* Private function prototypes -----------------------------------------------*/
65 /* Private functions ---------------------------------------------------------*/
67 /** @defgroup HASH_Private_Functions
71 /** @defgroup HASH_Group6 High Level SHA1 functions
72 * @brief High Level SHA1 Hash and HMAC functions
75 ===============================================================================
76 ##### High Level SHA1 Hash and HMAC functions #####
77 ===============================================================================
85 * @brief Compute the HASH SHA1 digest.
86 * @param Input: pointer to the Input buffer to be treated.
87 * @param Ilen: length of the Input buffer.
88 * @param Output: the returned digest
89 * @retval An ErrorStatus enumeration value:
90 * - SUCCESS: digest computation done
91 * - ERROR: digest computation failed
93 ErrorStatus
HASH_SHA1(uint8_t *Input
, uint32_t Ilen
, uint8_t Output
[20])
95 HASH_InitTypeDef SHA1_HASH_InitStructure
;
96 HASH_MsgDigest SHA1_MessageDigest
;
97 __IO
uint16_t nbvalidbitsdata
= 0;
99 __IO
uint32_t counter
= 0;
100 uint32_t busystatus
= 0;
101 ErrorStatus status
= SUCCESS
;
102 uint32_t inputaddr
= (uint32_t)Input
;
103 uint32_t outputaddr
= (uint32_t)Output
;
105 /* Number of valid bits in last word of the Input data */
106 nbvalidbitsdata
= 8 * (Ilen
% 4);
108 /* HASH peripheral initialization */
111 /* HASH Configuration */
112 SHA1_HASH_InitStructure
.HASH_AlgoSelection
= HASH_AlgoSelection_SHA1
;
113 SHA1_HASH_InitStructure
.HASH_AlgoMode
= HASH_AlgoMode_HASH
;
114 SHA1_HASH_InitStructure
.HASH_DataType
= HASH_DataType_8b
;
115 HASH_Init(&SHA1_HASH_InitStructure
);
117 /* Configure the number of valid bits in last word of the data */
118 HASH_SetLastWordValidBitsNbr(nbvalidbitsdata
);
120 /* Write the Input block in the IN FIFO */
121 for(i
=0; i
<Ilen
; i
+=4)
123 HASH_DataIn(*(uint32_t*)inputaddr
);
127 /* Start the HASH processor */
130 /* wait until the Busy flag is RESET */
133 busystatus
= HASH_GetFlagStatus(HASH_FLAG_BUSY
);
135 }while ((counter
!= SHA1BUSY_TIMEOUT
) && (busystatus
!= RESET
));
137 if (busystatus
!= RESET
)
143 /* Read the message digest */
144 HASH_GetDigest(&SHA1_MessageDigest
);
145 *(uint32_t*)(outputaddr
) = __REV(SHA1_MessageDigest
.Data
[0]);
147 *(uint32_t*)(outputaddr
) = __REV(SHA1_MessageDigest
.Data
[1]);
149 *(uint32_t*)(outputaddr
) = __REV(SHA1_MessageDigest
.Data
[2]);
151 *(uint32_t*)(outputaddr
) = __REV(SHA1_MessageDigest
.Data
[3]);
153 *(uint32_t*)(outputaddr
) = __REV(SHA1_MessageDigest
.Data
[4]);
159 * @brief Compute the HMAC SHA1 digest.
160 * @param Key: pointer to the Key used for HMAC.
161 * @param Keylen: length of the Key used for HMAC.
162 * @param Input: pointer to the Input buffer to be treated.
163 * @param Ilen: length of the Input buffer.
164 * @param Output: the returned digest
165 * @retval An ErrorStatus enumeration value:
166 * - SUCCESS: digest computation done
167 * - ERROR: digest computation failed
169 ErrorStatus
HMAC_SHA1(uint8_t *Key
, uint32_t Keylen
, uint8_t *Input
,
170 uint32_t Ilen
, uint8_t Output
[20])
172 HASH_InitTypeDef SHA1_HASH_InitStructure
;
173 HASH_MsgDigest SHA1_MessageDigest
;
174 __IO
uint16_t nbvalidbitsdata
= 0;
175 __IO
uint16_t nbvalidbitskey
= 0;
177 __IO
uint32_t counter
= 0;
178 uint32_t busystatus
= 0;
179 ErrorStatus status
= SUCCESS
;
180 uint32_t keyaddr
= (uint32_t)Key
;
181 uint32_t inputaddr
= (uint32_t)Input
;
182 uint32_t outputaddr
= (uint32_t)Output
;
184 /* Number of valid bits in last word of the Input data */
185 nbvalidbitsdata
= 8 * (Ilen
% 4);
187 /* Number of valid bits in last word of the Key */
188 nbvalidbitskey
= 8 * (Keylen
% 4);
190 /* HASH peripheral initialization */
193 /* HASH Configuration */
194 SHA1_HASH_InitStructure
.HASH_AlgoSelection
= HASH_AlgoSelection_SHA1
;
195 SHA1_HASH_InitStructure
.HASH_AlgoMode
= HASH_AlgoMode_HMAC
;
196 SHA1_HASH_InitStructure
.HASH_DataType
= HASH_DataType_8b
;
200 SHA1_HASH_InitStructure
.HASH_HMACKeyType
= HASH_HMACKeyType_LongKey
;
205 SHA1_HASH_InitStructure
.HASH_HMACKeyType
= HASH_HMACKeyType_ShortKey
;
207 HASH_Init(&SHA1_HASH_InitStructure
);
209 /* Configure the number of valid bits in last word of the Key */
210 HASH_SetLastWordValidBitsNbr(nbvalidbitskey
);
213 for(i
=0; i
<Keylen
; i
+=4)
215 HASH_DataIn(*(uint32_t*)keyaddr
);
219 /* Start the HASH processor */
222 /* wait until the Busy flag is RESET */
225 busystatus
= HASH_GetFlagStatus(HASH_FLAG_BUSY
);
227 }while ((counter
!= SHA1BUSY_TIMEOUT
) && (busystatus
!= RESET
));
229 if (busystatus
!= RESET
)
235 /* Configure the number of valid bits in last word of the Input data */
236 HASH_SetLastWordValidBitsNbr(nbvalidbitsdata
);
238 /* Write the Input block in the IN FIFO */
239 for(i
=0; i
<Ilen
; i
+=4)
241 HASH_DataIn(*(uint32_t*)inputaddr
);
245 /* Start the HASH processor */
249 /* wait until the Busy flag is RESET */
253 busystatus
= HASH_GetFlagStatus(HASH_FLAG_BUSY
);
255 }while ((counter
!= SHA1BUSY_TIMEOUT
) && (busystatus
!= RESET
));
257 if (busystatus
!= RESET
)
263 /* Configure the number of valid bits in last word of the Key */
264 HASH_SetLastWordValidBitsNbr(nbvalidbitskey
);
267 keyaddr
= (uint32_t)Key
;
268 for(i
=0; i
<Keylen
; i
+=4)
270 HASH_DataIn(*(uint32_t*)keyaddr
);
274 /* Start the HASH processor */
277 /* wait until the Busy flag is RESET */
281 busystatus
= HASH_GetFlagStatus(HASH_FLAG_BUSY
);
283 }while ((counter
!= SHA1BUSY_TIMEOUT
) && (busystatus
!= RESET
));
285 if (busystatus
!= RESET
)
291 /* Read the message digest */
292 HASH_GetDigest(&SHA1_MessageDigest
);
293 *(uint32_t*)(outputaddr
) = __REV(SHA1_MessageDigest
.Data
[0]);
295 *(uint32_t*)(outputaddr
) = __REV(SHA1_MessageDigest
.Data
[1]);
297 *(uint32_t*)(outputaddr
) = __REV(SHA1_MessageDigest
.Data
[2]);
299 *(uint32_t*)(outputaddr
) = __REV(SHA1_MessageDigest
.Data
[3]);
301 *(uint32_t*)(outputaddr
) = __REV(SHA1_MessageDigest
.Data
[4]);
323 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/