Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Demo / ARMCM4_STM32F405_Power_Management_GCC / Boot / lib / stdperiphlib / STM32F4xx_StdPeriph_Driver / src / stm32f4xx_hash_md5.c @ 69661903

History | View | Annotate | Download (9.37 KB)

1 69661903 Thomas Schöpping
/**
2
  ******************************************************************************
3
  * @file    stm32f4xx_hash_md5.c
4
  * @author  MCD Application Team
5
  * @version V1.1.0
6
  * @date    11-January-2013
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.
11
  *
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.
19
  
20
   (#) Calculate the HASH MD5 Digest using HASH_MD5() function.
21
  
22
   (#) Calculate the HMAC MD5 Digest using HMAC_MD5() function.
23
  
24
@endverbatim
25
  *
26
  ******************************************************************************
27
  * @attention
28
  *
29
  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
30
  *
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:
34
  *
35
  *        http://www.st.com/software_license_agreement_liberty_v2
36
  *
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.
42
  *
43
  ******************************************************************************
44
  */
45
46
/* Includes ------------------------------------------------------------------*/
47
#include "stm32f4xx_hash.h"
48
49
/** @addtogroup STM32F4xx_StdPeriph_Driver
50
  * @{
51
  */
52
53
/** @defgroup HASH 
54
  * @brief HASH driver modules
55
  * @{
56
  */
57
58
/* Private typedef -----------------------------------------------------------*/
59
/* Private define ------------------------------------------------------------*/
60
#define MD5BUSY_TIMEOUT    ((uint32_t) 0x00010000)
61
62
/* Private macro -------------------------------------------------------------*/
63
/* Private variables ---------------------------------------------------------*/
64
/* Private function prototypes -----------------------------------------------*/
65
/* Private functions ---------------------------------------------------------*/
66
67
/** @defgroup HASH_Private_Functions
68
  * @{
69
  */ 
70
71
/** @defgroup HASH_Group7 High Level MD5 functions
72
 *  @brief   High Level MD5 Hash and HMAC functions 
73
 *
74
@verbatim   
75
 ===============================================================================
76
              ##### High Level MD5 Hash and HMAC functions #####
77
 ===============================================================================
78

79

80
@endverbatim
81
  * @{
82
  */
83
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
92
  */
93
ErrorStatus HASH_MD5(uint8_t *Input, uint32_t Ilen, uint8_t Output[16])
94
{
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;
104
105
106
  /* Number of valid bits in last word of the Input data */
107
  nbvalidbitsdata = 8 * (Ilen % 4);
108
109
  /* HASH peripheral initialization */
110
  HASH_DeInit();
111
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);
117
118
  /* Configure the number of valid bits in last word of the data */
119
  HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
120
121
  /* Write the Input block in the IN FIFO */
122
  for(i=0; i<Ilen; i+=4)
123
  {
124
    HASH_DataIn(*(uint32_t*)inputaddr);
125
    inputaddr+=4;
126
  }
127
128
  /* Start the HASH processor */
129
  HASH_StartDigest();
130
131
  /* wait until the Busy flag is RESET */
132
  do
133
  {
134
    busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
135
    counter++;
136
  }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
137
138
  if (busystatus != RESET)
139
  {
140
     status = ERROR;
141
  }
142
  else
143
  {
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]);
153
  }
154
  return status; 
155
}
156
157
/**
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
167
  */
168
ErrorStatus HMAC_MD5(uint8_t *Key, uint32_t Keylen, uint8_t *Input, 
169
                     uint32_t Ilen, uint8_t Output[16])
170
{
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;
182
183
  /* Number of valid bits in last word of the Input data */
184
  nbvalidbitsdata = 8 * (Ilen % 4);
185
186
  /* Number of valid bits in last word of the Key */
187
  nbvalidbitskey = 8 * (Keylen % 4);
188
   
189
  /* HASH peripheral initialization */
190
  HASH_DeInit();
191
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)
197
  {
198
    /* HMAC long Key */
199
    MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey;
200
  }
201
  else
202
  {
203
    /* HMAC short Key */
204
    MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey;
205
  }
206
  HASH_Init(&MD5_HASH_InitStructure);
207
208
  /* Configure the number of valid bits in last word of the Key */
209
  HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
210
211
  /* Write the Key */
212
  for(i=0; i<Keylen; i+=4)
213
  {
214
    HASH_DataIn(*(uint32_t*)keyaddr);
215
    keyaddr+=4;
216
  }
217
  
218
  /* Start the HASH processor */
219
  HASH_StartDigest();
220
221
  /* wait until the Busy flag is RESET */
222
  do
223
  {
224
    busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
225
    counter++;
226
  }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
227
228
  if (busystatus != RESET)
229
  {
230
     status = ERROR;
231
  }
232
  else
233
  {
234
    /* Configure the number of valid bits in last word of the Input data */
235
    HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
236
237
    /* Write the Input block in the IN FIFO */
238
    for(i=0; i<Ilen; i+=4)
239
    {
240
      HASH_DataIn(*(uint32_t*)inputaddr);
241
      inputaddr+=4;
242
    }
243
244
    /* Start the HASH processor */
245
    HASH_StartDigest();
246
247
    /* wait until the Busy flag is RESET */
248
    counter =0;
249
    do
250
    {
251
       busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
252
       counter++;
253
    }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
254
255
    if (busystatus != RESET)
256
    {
257
      status = ERROR;
258
    }
259
    else
260
    {  
261
      /* Configure the number of valid bits in last word of the Key */
262
      HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
263
264
      /* Write the Key */
265
      keyaddr = (uint32_t)Key;
266
      for(i=0; i<Keylen; i+=4)
267
      {
268
        HASH_DataIn(*(uint32_t*)keyaddr);
269
        keyaddr+=4;
270
      }
271
  
272
       /* Start the HASH processor */
273
       HASH_StartDigest();
274
275
       /* wait until the Busy flag is RESET */
276
       counter =0;
277
       do
278
       {
279
          busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);
280
          counter++;
281
      }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET));
282
283
      if (busystatus != RESET)
284
      {
285
         status = ERROR;
286
      }
287
      else
288
      {
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]);
298
      }
299
    }
300
  }
301
  return status;  
302
}
303
/**
304
  * @}
305
  */ 
306
307
/**
308
  * @}
309
  */ 
310
311
/**
312
  * @}
313
  */ 
314
315
/**
316
  * @}
317
  */ 
318
319
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
320