Create release.yml
[betaflight.git] / lib / main / STM32F4 / Drivers / STM32F4xx_StdPeriph_Driver / src / stm32f4xx_hash_sha1.c
blob8a7b39f17b5e1ceb594f4520059bf8878ac185bc
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hash_sha1.c
4 * @author MCD Application Team
5 * @version V1.7.1
6 * @date 20-May-2016
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.
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.
20 (#) Calculate the HASH SHA1 Digest using HASH_SHA1() function.
22 (#) Calculate the HMAC SHA1 Digest using HMAC_SHA1() function.
24 @endverbatim
26 ******************************************************************************
27 * @attention
29 * <h2><center>&copy; 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
50 * @{
53 /** @defgroup HASH
54 * @brief HASH driver modules
55 * @{
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
68 * @{
69 */
71 /** @defgroup HASH_Group6 High Level SHA1 functions
72 * @brief High Level SHA1 Hash and HMAC functions
74 @verbatim
75 ===============================================================================
76 ##### High Level SHA1 Hash and HMAC functions #####
77 ===============================================================================
80 @endverbatim
81 * @{
84 /**
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;
98 uint32_t i = 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 */
109 HASH_DeInit();
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);
124 inputaddr+=4;
127 /* Start the HASH processor */
128 HASH_StartDigest();
130 /* wait until the Busy flag is RESET */
133 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
134 counter++;
135 }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
137 if (busystatus != RESET)
139 status = ERROR;
141 else
143 /* Read the message digest */
144 HASH_GetDigest(&SHA1_MessageDigest);
145 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[0]);
146 outputaddr+=4;
147 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[1]);
148 outputaddr+=4;
149 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[2]);
150 outputaddr+=4;
151 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[3]);
152 outputaddr+=4;
153 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[4]);
155 return status;
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;
176 uint32_t i = 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 */
191 HASH_DeInit();
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;
197 if(Keylen > 64)
199 /* HMAC long Key */
200 SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey;
202 else
204 /* HMAC short Key */
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);
212 /* Write the Key */
213 for(i=0; i<Keylen; i+=4)
215 HASH_DataIn(*(uint32_t*)keyaddr);
216 keyaddr+=4;
219 /* Start the HASH processor */
220 HASH_StartDigest();
222 /* wait until the Busy flag is RESET */
225 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
226 counter++;
227 }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
229 if (busystatus != RESET)
231 status = ERROR;
233 else
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);
242 inputaddr+=4;
245 /* Start the HASH processor */
246 HASH_StartDigest();
249 /* wait until the Busy flag is RESET */
250 counter =0;
253 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
254 counter++;
255 }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
257 if (busystatus != RESET)
259 status = ERROR;
261 else
263 /* Configure the number of valid bits in last word of the Key */
264 HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
266 /* Write the Key */
267 keyaddr = (uint32_t)Key;
268 for(i=0; i<Keylen; i+=4)
270 HASH_DataIn(*(uint32_t*)keyaddr);
271 keyaddr+=4;
274 /* Start the HASH processor */
275 HASH_StartDigest();
277 /* wait until the Busy flag is RESET */
278 counter =0;
281 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
282 counter++;
283 }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));
285 if (busystatus != RESET)
287 status = ERROR;
289 else
291 /* Read the message digest */
292 HASH_GetDigest(&SHA1_MessageDigest);
293 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[0]);
294 outputaddr+=4;
295 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[1]);
296 outputaddr+=4;
297 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[2]);
298 outputaddr+=4;
299 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[3]);
300 outputaddr+=4;
301 *(uint32_t*)(outputaddr) = __REV(SHA1_MessageDigest.Data[4]);
305 return status;
308 * @}
312 * @}
316 * @}
320 * @}
323 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/