2 ******************************************************************************
3 * @file stm32f4xx_hash_md5.c
4 * @author MCD Application Team
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
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 MD5 Digest using HASH_MD5() function.
22 (#) Calculate the HMAC MD5 Digest using HMAC_MD5() 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 MD5BUSY_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_Group7 High Level MD5 functions
72 * @brief High Level MD5 Hash and HMAC functions
75 ===============================================================================
76 ##### High Level MD5 Hash and HMAC functions #####
77 ===============================================================================
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;
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 */
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
);
128 /* Start the HASH processor */
131 /* wait until the Busy flag is RESET */
134 busystatus
= HASH_GetFlagStatus(HASH_FLAG_BUSY
);
136 }while ((counter
!= MD5BUSY_TIMEOUT
) && (busystatus
!= RESET
));
138 if (busystatus
!= RESET
)
144 /* Read the message digest */
145 HASH_GetDigest(&MD5_MessageDigest
);
146 *(uint32_t*)(outputaddr
) = __REV(MD5_MessageDigest
.Data
[0]);
148 *(uint32_t*)(outputaddr
) = __REV(MD5_MessageDigest
.Data
[1]);
150 *(uint32_t*)(outputaddr
) = __REV(MD5_MessageDigest
.Data
[2]);
152 *(uint32_t*)(outputaddr
) = __REV(MD5_MessageDigest
.Data
[3]);
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;
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 */
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
;
199 MD5_HASH_InitStructure
.HASH_HMACKeyType
= HASH_HMACKeyType_LongKey
;
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
);
212 for(i
=0; i
<Keylen
; i
+=4)
214 HASH_DataIn(*(uint32_t*)keyaddr
);
218 /* Start the HASH processor */
221 /* wait until the Busy flag is RESET */
224 busystatus
= HASH_GetFlagStatus(HASH_FLAG_BUSY
);
226 }while ((counter
!= MD5BUSY_TIMEOUT
) && (busystatus
!= RESET
));
228 if (busystatus
!= RESET
)
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
);
244 /* Start the HASH processor */
247 /* wait until the Busy flag is RESET */
251 busystatus
= HASH_GetFlagStatus(HASH_FLAG_BUSY
);
253 }while ((counter
!= MD5BUSY_TIMEOUT
) && (busystatus
!= RESET
));
255 if (busystatus
!= RESET
)
261 /* Configure the number of valid bits in last word of the Key */
262 HASH_SetLastWordValidBitsNbr(nbvalidbitskey
);
265 keyaddr
= (uint32_t)Key
;
266 for(i
=0; i
<Keylen
; i
+=4)
268 HASH_DataIn(*(uint32_t*)keyaddr
);
272 /* Start the HASH processor */
275 /* wait until the Busy flag is RESET */
279 busystatus
= HASH_GetFlagStatus(HASH_FLAG_BUSY
);
281 }while ((counter
!= MD5BUSY_TIMEOUT
) && (busystatus
!= RESET
));
283 if (busystatus
!= RESET
)
289 /* Read the message digest */
290 HASH_GetDigest(&MD5_MessageDigest
);
291 *(uint32_t*)(outputaddr
) = __REV(MD5_MessageDigest
.Data
[0]);
293 *(uint32_t*)(outputaddr
) = __REV(MD5_MessageDigest
.Data
[1]);
295 *(uint32_t*)(outputaddr
) = __REV(MD5_MessageDigest
.Data
[2]);
297 *(uint32_t*)(outputaddr
) = __REV(MD5_MessageDigest
.Data
[3]);
319 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/