Create release.yml
[betaflight.git] / lib / main / STM32F4 / Drivers / STM32F4xx_StdPeriph_Driver / src / stm32f4xx_hash_md5.c
blobef2aa4c708d18c2caa1eba705db64743601babc3
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hash_md5.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 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.
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 MD5 Digest using HASH_MD5() function.
22 (#) Calculate the HMAC MD5 Digest using HMAC_MD5() 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 MD5BUSY_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_Group7 High Level MD5 functions
72 * @brief High Level MD5 Hash and HMAC functions
74 @verbatim
75 ===============================================================================
76 ##### High Level MD5 Hash and HMAC functions #####
77 ===============================================================================
80 @endverbatim
81 * @{
84 /**
85 * @brief Compute the HASH MD5 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_MD5(uint8_t *Input, uint32_t Ilen, uint8_t Output[16])
95 HASH_InitTypeDef MD5_HASH_InitStructure;
96 HASH_MsgDigest MD5_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;
106 /* Number of valid bits in last word of the Input data */
107 nbvalidbitsdata = 8 * (Ilen % 4);
109 /* HASH peripheral initialization */
110 HASH_DeInit();
112 /* HASH Configuration */
113 MD5_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_MD5;
114 MD5_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH;
115 MD5_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
116 HASH_Init(&MD5_HASH_InitStructure);
118 /* Configure the number of valid bits in last word of the data */
119 HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
121 /* Write the Input block in the IN FIFO */
122 for(i=0; i<Ilen; i+=4)
124 HASH_DataIn(*(uint32_t*)inputaddr);
125 inputaddr+=4;
128 /* Start the HASH processor */
129 HASH_StartDigest();
131 /* wait until the Busy flag is RESET */
134 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
135 counter++;
136 }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
138 if (busystatus != RESET)
140 status = ERROR;
142 else
144 /* Read the message digest */
145 HASH_GetDigest(&MD5_MessageDigest);
146 *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[0]);
147 outputaddr+=4;
148 *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[1]);
149 outputaddr+=4;
150 *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[2]);
151 outputaddr+=4;
152 *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[3]);
154 return status;
158 * @brief Compute the HMAC MD5 digest.
159 * @param Key: pointer to the Key used for HMAC.
160 * @param Keylen: length of the Key used for HMAC.
161 * @param Input: pointer to the Input buffer to be treated.
162 * @param Ilen: length of the Input buffer.
163 * @param Output: the returned digest
164 * @retval An ErrorStatus enumeration value:
165 * - SUCCESS: digest computation done
166 * - ERROR: digest computation failed
168 ErrorStatus HMAC_MD5(uint8_t *Key, uint32_t Keylen, uint8_t *Input,
169 uint32_t Ilen, uint8_t Output[16])
171 HASH_InitTypeDef MD5_HASH_InitStructure;
172 HASH_MsgDigest MD5_MessageDigest;
173 __IO uint16_t nbvalidbitsdata = 0;
174 __IO uint16_t nbvalidbitskey = 0;
175 uint32_t i = 0;
176 __IO uint32_t counter = 0;
177 uint32_t busystatus = 0;
178 ErrorStatus status = SUCCESS;
179 uint32_t keyaddr = (uint32_t)Key;
180 uint32_t inputaddr = (uint32_t)Input;
181 uint32_t outputaddr = (uint32_t)Output;
183 /* Number of valid bits in last word of the Input data */
184 nbvalidbitsdata = 8 * (Ilen % 4);
186 /* Number of valid bits in last word of the Key */
187 nbvalidbitskey = 8 * (Keylen % 4);
189 /* HASH peripheral initialization */
190 HASH_DeInit();
192 /* HASH Configuration */
193 MD5_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_MD5;
194 MD5_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HMAC;
195 MD5_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
196 if(Keylen > 64)
198 /* HMAC long Key */
199 MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey;
201 else
203 /* HMAC short Key */
204 MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey;
206 HASH_Init(&MD5_HASH_InitStructure);
208 /* Configure the number of valid bits in last word of the Key */
209 HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
211 /* Write the Key */
212 for(i=0; i<Keylen; i+=4)
214 HASH_DataIn(*(uint32_t*)keyaddr);
215 keyaddr+=4;
218 /* Start the HASH processor */
219 HASH_StartDigest();
221 /* wait until the Busy flag is RESET */
224 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
225 counter++;
226 }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
228 if (busystatus != RESET)
230 status = ERROR;
232 else
234 /* Configure the number of valid bits in last word of the Input data */
235 HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
237 /* Write the Input block in the IN FIFO */
238 for(i=0; i<Ilen; i+=4)
240 HASH_DataIn(*(uint32_t*)inputaddr);
241 inputaddr+=4;
244 /* Start the HASH processor */
245 HASH_StartDigest();
247 /* wait until the Busy flag is RESET */
248 counter =0;
251 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
252 counter++;
253 }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
255 if (busystatus != RESET)
257 status = ERROR;
259 else
261 /* Configure the number of valid bits in last word of the Key */
262 HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
264 /* Write the Key */
265 keyaddr = (uint32_t)Key;
266 for(i=0; i<Keylen; i+=4)
268 HASH_DataIn(*(uint32_t*)keyaddr);
269 keyaddr+=4;
272 /* Start the HASH processor */
273 HASH_StartDigest();
275 /* wait until the Busy flag is RESET */
276 counter =0;
279 busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
280 counter++;
281 }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
283 if (busystatus != RESET)
285 status = ERROR;
287 else
289 /* Read the message digest */
290 HASH_GetDigest(&MD5_MessageDigest);
291 *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[0]);
292 outputaddr+=4;
293 *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[1]);
294 outputaddr+=4;
295 *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[2]);
296 outputaddr+=4;
297 *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[3]);
301 return status;
304 * @}
308 * @}
312 * @}
316 * @}
319 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/