1
+ /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
2
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
3
+ * All rights reserved.
4
+ *
5
+ * License to copy and use this software is granted provided that it
6
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
7
+ * Algorithm" in all material mentioning or referencing this software
8
+ * or this function.
9
+ *
10
+ * License is also granted to make and use derivative works provided
11
+ * that such works are identified as "derived from the RSA Data
12
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
13
+ * mentioning or referencing the derived work.
14
+ *
15
+ * RSA Data Security, Inc. makes no representations concerning either
16
+ * the merchantability of this software or the suitability of this
17
+ * software for any particular purpose. It is provided "as is"
18
+ * without express or implied warranty of any kind.
19
+ *
20
+ * These notices must be retained in any copies of any part of this
21
+ * documentation and/or software.
22
+ */
23
+
24
+ #include "global.h"
25
+ #include "MD5.h"
26
+
27
+ /* Constants for MD5Transform routine. */
28
+
29
+ #define S11 7
30
+ #define S12 12
31
+ #define S13 17
32
+ #define S14 22
33
+ #define S21 5
34
+ #define S22 9
35
+ #define S23 14
36
+ #define S24 20
37
+ #define S31 4
38
+ #define S32 11
39
+ #define S33 16
40
+ #define S34 23
41
+ #define S41 6
42
+ #define S42 10
43
+ #define S43 15
44
+ #define S44 21
45
+
46
+ static void MD5Transform (UINT4 [4 ], unsigned char [64 ]);
47
+ static void Encode (unsigned char * , UINT4 * , unsigned int );
48
+ static void Decode (UINT4 * , unsigned char * , unsigned int );
49
+ static void MD5_memcpy (POINTER , POINTER , unsigned int );
50
+ static void MD5_memset (POINTER , int , unsigned int );
51
+
52
+ static unsigned char PADDING [64 ] = {
53
+ 0x80 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
54
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
55
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
56
+ };
57
+
58
+ static unsigned char MD5Digest [16 ];
59
+
60
+ /* F, G, H and I are basic MD5 functions. */
61
+ #define F (x , y , z ) (((x) & (y)) | ((~x) & (z)))
62
+ #define G (x , y , z ) (((x) & (z)) | ((y) & (~z)))
63
+ #define H (x , y , z ) ((x) ^ (y) ^ (z))
64
+ #define I (x , y , z ) ((y) ^ ((x) | (~z)))
65
+
66
+ /* ROTATE_LEFT rotates x left n bits. */
67
+ #define ROTATE_LEFT (x , n ) (((x) << (n)) | ((x) >> (32-(n))))
68
+
69
+ /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
70
+ * Rotation is separate from addition to prevent recomputation.
71
+ */
72
+ #define FF (a , b , c , d , x , s , ac ) { \
73
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
74
+ (a) = ROTATE_LEFT ((a), (s)); \
75
+ (a) += (b); \
76
+ }
77
+ #define GG (a , b , c , d , x , s , ac ) { \
78
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
79
+ (a) = ROTATE_LEFT ((a), (s)); \
80
+ (a) += (b); \
81
+ }
82
+ #define HH (a , b , c , d , x , s , ac ) { \
83
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
84
+ (a) = ROTATE_LEFT ((a), (s)); \
85
+ (a) += (b); \
86
+ }
87
+ #define II (a , b , c , d , x , s , ac ) { \
88
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
89
+ (a) = ROTATE_LEFT ((a), (s)); \
90
+ (a) += (b); \
91
+ }
92
+
93
+ /* MD5 initialization. Begins an MD5 operation, writing a new context. */
94
+ void MD5Init (MD5_CTX * context ) /* context */
95
+ {
96
+ context -> count [0 ] = context -> count [1 ] = 0 ;
97
+ /* Load magic initialization constants. */
98
+ context -> state [0 ] = 0x67452301 ;
99
+ context -> state [1 ] = 0xefcdab89 ;
100
+ context -> state [2 ] = 0x98badcfe ;
101
+ context -> state [3 ] = 0x10325476 ;
102
+ }
103
+
104
+ /* MD5 block update operation. Continues an MD5 message-digest
105
+ * operation, processing another message block, and updating the
106
+ * context.
107
+ */
108
+ void MD5Update (MD5_CTX * context , unsigned char * input ,unsigned int inputLen ) /* length of input block */
109
+ {
110
+ unsigned int i , index , partLen ;
111
+
112
+ /* Compute number of bytes mod 64 */
113
+ index = (unsigned int )((context -> count [0 ] >> 3 ) & 0x3F );
114
+
115
+ /* Update number of bits */
116
+ if ((context -> count [0 ] += ((UINT4 )inputLen << 3 ))
117
+ < ((UINT4 )inputLen << 3 ))
118
+ context -> count [1 ]++ ;
119
+ context -> count [1 ] += ((UINT4 )inputLen >> 29 );
120
+ partLen = 64 - index ;
121
+
122
+ /* Transform as many times as possible. */
123
+ if (inputLen >= partLen ) {
124
+ MD5_memcpy ((POINTER )& context -> buffer [index ], (POINTER )input , partLen );
125
+ MD5Transform (context -> state , context -> buffer );
126
+ for (i = partLen ; i + 63 < inputLen ; i += 64 )
127
+ MD5Transform (context -> state , & input [i ]);
128
+ index = 0 ;
129
+ }
130
+ else
131
+ i = 0 ;
132
+
133
+ /* Buffer remaining input */
134
+ MD5_memcpy ((POINTER )& context -> buffer [index ], (POINTER )& input [i ],
135
+ inputLen - i );
136
+ }
137
+
138
+ /* MD5 finalization. Ends an MD5 message-digest operation, writing the
139
+ * the message digest and zeroizing the context.
140
+ */
141
+ void MD5Final (unsigned char digest [16 ], MD5_CTX * context )
142
+ {
143
+ unsigned char bits [8 ];
144
+ unsigned int index , padLen ;
145
+
146
+ /* Save number of bits */
147
+ Encode (bits , context -> count , 8 );
148
+
149
+ /* Pad out to 56 mod 64. */
150
+ index = (unsigned int )((context -> count [0 ] >> 3 ) & 0x3f );
151
+ padLen = (index < 56 ) ? (56 - index ) : (120 - index );
152
+ MD5Update (context , PADDING , padLen );
153
+
154
+ /* Append length (before padding) */
155
+ MD5Update (context , bits , 8 );
156
+
157
+ /* Store state in digest */
158
+ Encode (digest , context -> state , 16 );
159
+
160
+ /* Zeroize sensitive information. */
161
+ MD5_memset ((POINTER )context , 0 , sizeof (* context ));
162
+ }
163
+
164
+ /* MD5 basic transformation. Transforms state based on block. */
165
+ static void MD5Transform (UINT4 state [4 ], unsigned char block [64 ])
166
+ {
167
+ UINT4 a = state [0 ], b = state [1 ], c = state [2 ], d = state [3 ], x [16 ];
168
+
169
+ Decode (x , block , 64 );
170
+
171
+ /* Round 1 */
172
+ FF (a , b , c , d , x [ 0 ], S11 , 0xd76aa478 ); /* 1 */
173
+ FF (d , a , b , c , x [ 1 ], S12 , 0xe8c7b756 ); /* 2 */
174
+ FF (c , d , a , b , x [ 2 ], S13 , 0x242070db ); /* 3 */
175
+ FF (b , c , d , a , x [ 3 ], S14 , 0xc1bdceee ); /* 4 */
176
+ FF (a , b , c , d , x [ 4 ], S11 , 0xf57c0faf ); /* 5 */
177
+ FF (d , a , b , c , x [ 5 ], S12 , 0x4787c62a ); /* 6 */
178
+ FF (c , d , a , b , x [ 6 ], S13 , 0xa8304613 ); /* 7 */
179
+ FF (b , c , d , a , x [ 7 ], S14 , 0xfd469501 ); /* 8 */
180
+ FF (a , b , c , d , x [ 8 ], S11 , 0x698098d8 ); /* 9 */
181
+ FF (d , a , b , c , x [ 9 ], S12 , 0x8b44f7af ); /* 10 */
182
+ FF (c , d , a , b , x [10 ], S13 , 0xffff5bb1 ); /* 11 */
183
+ FF (b , c , d , a , x [11 ], S14 , 0x895cd7be ); /* 12 */
184
+ FF (a , b , c , d , x [12 ], S11 , 0x6b901122 ); /* 13 */
185
+ FF (d , a , b , c , x [13 ], S12 , 0xfd987193 ); /* 14 */
186
+ FF (c , d , a , b , x [14 ], S13 , 0xa679438e ); /* 15 */
187
+ FF (b , c , d , a , x [15 ], S14 , 0x49b40821 ); /* 16 */
188
+
189
+ /* Round 2 */
190
+ GG (a , b , c , d , x [ 1 ], S21 , 0xf61e2562 ); /* 17 */
191
+ GG (d , a , b , c , x [ 6 ], S22 , 0xc040b340 ); /* 18 */
192
+ GG (c , d , a , b , x [11 ], S23 , 0x265e5a51 ); /* 19 */
193
+ GG (b , c , d , a , x [ 0 ], S24 , 0xe9b6c7aa ); /* 20 */
194
+ GG (a , b , c , d , x [ 5 ], S21 , 0xd62f105d ); /* 21 */
195
+ GG (d , a , b , c , x [10 ], S22 , 0x2441453 ); /* 22 */
196
+ GG (c , d , a , b , x [15 ], S23 , 0xd8a1e681 ); /* 23 */
197
+ GG (b , c , d , a , x [ 4 ], S24 , 0xe7d3fbc8 ); /* 24 */
198
+ GG (a , b , c , d , x [ 9 ], S21 , 0x21e1cde6 ); /* 25 */
199
+ GG (d , a , b , c , x [14 ], S22 , 0xc33707d6 ); /* 26 */
200
+ GG (c , d , a , b , x [ 3 ], S23 , 0xf4d50d87 ); /* 27 */
201
+ GG (b , c , d , a , x [ 8 ], S24 , 0x455a14ed ); /* 28 */
202
+ GG (a , b , c , d , x [13 ], S21 , 0xa9e3e905 ); /* 29 */
203
+ GG (d , a , b , c , x [ 2 ], S22 , 0xfcefa3f8 ); /* 30 */
204
+ GG (c , d , a , b , x [ 7 ], S23 , 0x676f02d9 ); /* 31 */
205
+ GG (b , c , d , a , x [12 ], S24 , 0x8d2a4c8a ); /* 32 */
206
+
207
+ /* Round 3 */
208
+ HH (a , b , c , d , x [ 5 ], S31 , 0xfffa3942 ); /* 33 */
209
+ HH (d , a , b , c , x [ 8 ], S32 , 0x8771f681 ); /* 34 */
210
+ HH (c , d , a , b , x [11 ], S33 , 0x6d9d6122 ); /* 35 */
211
+ HH (b , c , d , a , x [14 ], S34 , 0xfde5380c ); /* 36 */
212
+ HH (a , b , c , d , x [ 1 ], S31 , 0xa4beea44 ); /* 37 */
213
+ HH (d , a , b , c , x [ 4 ], S32 , 0x4bdecfa9 ); /* 38 */
214
+ HH (c , d , a , b , x [ 7 ], S33 , 0xf6bb4b60 ); /* 39 */
215
+ HH (b , c , d , a , x [10 ], S34 , 0xbebfbc70 ); /* 40 */
216
+ HH (a , b , c , d , x [13 ], S31 , 0x289b7ec6 ); /* 41 */
217
+ HH (d , a , b , c , x [ 0 ], S32 , 0xeaa127fa ); /* 42 */
218
+ HH (c , d , a , b , x [ 3 ], S33 , 0xd4ef3085 ); /* 43 */
219
+ HH (b , c , d , a , x [ 6 ], S34 , 0x4881d05 ); /* 44 */
220
+ HH (a , b , c , d , x [ 9 ], S31 , 0xd9d4d039 ); /* 45 */
221
+ HH (d , a , b , c , x [12 ], S32 , 0xe6db99e5 ); /* 46 */
222
+ HH (c , d , a , b , x [15 ], S33 , 0x1fa27cf8 ); /* 47 */
223
+ HH (b , c , d , a , x [ 2 ], S34 , 0xc4ac5665 ); /* 48 */
224
+
225
+ /* Round 4 */
226
+ II (a , b , c , d , x [ 0 ], S41 , 0xf4292244 ); /* 49 */
227
+ II (d , a , b , c , x [ 7 ], S42 , 0x432aff97 ); /* 50 */
228
+ II (c , d , a , b , x [14 ], S43 , 0xab9423a7 ); /* 51 */
229
+ II (b , c , d , a , x [ 5 ], S44 , 0xfc93a039 ); /* 52 */
230
+ II (a , b , c , d , x [12 ], S41 , 0x655b59c3 ); /* 53 */
231
+ II (d , a , b , c , x [ 3 ], S42 , 0x8f0ccc92 ); /* 54 */
232
+ II (c , d , a , b , x [10 ], S43 , 0xffeff47d ); /* 55 */
233
+ II (b , c , d , a , x [ 1 ], S44 , 0x85845dd1 ); /* 56 */
234
+ II (a , b , c , d , x [ 8 ], S41 , 0x6fa87e4f ); /* 57 */
235
+ II (d , a , b , c , x [15 ], S42 , 0xfe2ce6e0 ); /* 58 */
236
+ II (c , d , a , b , x [ 6 ], S43 , 0xa3014314 ); /* 59 */
237
+ II (b , c , d , a , x [13 ], S44 , 0x4e0811a1 ); /* 60 */
238
+ II (a , b , c , d , x [ 4 ], S41 , 0xf7537e82 ); /* 61 */
239
+ II (d , a , b , c , x [11 ], S42 , 0xbd3af235 ); /* 62 */
240
+ II (c , d , a , b , x [ 2 ], S43 , 0x2ad7d2bb ); /* 63 */
241
+ II (b , c , d , a , x [ 9 ], S44 , 0xeb86d391 ); /* 64 */
242
+
243
+ state [0 ] += a ;
244
+ state [1 ] += b ;
245
+ state [2 ] += c ;
246
+ state [3 ] += d ;
247
+
248
+ /* Zeroize sensitive information. */
249
+ MD5_memset ((POINTER )x , 0 , sizeof (x ));
250
+ }
251
+
252
+ /* Encodes input (UINT4) into output (unsigned char). Assumes len is
253
+ * a multiple of 4.
254
+ */
255
+ static void Encode (unsigned char * output , UINT4 * input , unsigned int len )
256
+ {
257
+ unsigned int i , j ;
258
+
259
+ for (i = 0 , j = 0 ; j < len ; i ++ , j += 4 ) {
260
+ output [j ] = (unsigned char )(input [i ] & 0xff );
261
+ output [j + 1 ] = (unsigned char )((input [i ] >> 8 ) & 0xff );
262
+ output [j + 2 ] = (unsigned char )((input [i ] >> 16 ) & 0xff );
263
+ output [j + 3 ] = (unsigned char )((input [i ] >> 24 ) & 0xff );
264
+ }
265
+ }
266
+
267
+ /* Decodes input (unsigned char) into output (UINT4). Assumes len is
268
+ * a multiple of 4.
269
+ */
270
+ static void Decode (UINT4 * output , unsigned char * input , unsigned int len )
271
+ {
272
+ unsigned int i , j ;
273
+
274
+ for (i = 0 , j = 0 ; j < len ; i ++ , j += 4 )
275
+ output [i ] = ((UINT4 )input [j ]) | (((UINT4 )input [j + 1 ]) << 8 ) |
276
+ (((UINT4 )input [j + 2 ]) << 16 ) | (((UINT4 )input [j + 3 ]) << 24 );
277
+ }
278
+
279
+ /* Note: Replace "for loop" with standard memcpy if possible. */
280
+
281
+ static void MD5_memcpy (POINTER output , POINTER input , unsigned int len )
282
+ {
283
+ unsigned int i ;
284
+
285
+ for (i = 0 ; i < len ; i ++ )
286
+ output [i ] = input [i ];
287
+ }
288
+
289
+ /* Note: Replace "for loop" with standard memset if possible. */
290
+ static void MD5_memset (POINTER output , int value , unsigned int len )
291
+ {
292
+ unsigned int i ;
293
+
294
+ for (i = 0 ; i < len ; i ++ )
295
+ ((char * )output )[i ] = (char )value ;
296
+ }
297
+
298
+ /* Modified by MMoore http://mikestechspot.blogspot.com
299
+ Called from Arduino it takes the char array and the length of the
300
+ char array (without the '\0' NULL at the end) and stores the result
301
+ inside the static variable MD5Digest[16], an unsigned char[] declared
302
+ at the top of this file. */
303
+ void MD5 (unsigned char strInputString [], unsigned int len ){
304
+
305
+ MD5_CTX ctx ;
306
+ MD5Init (& ctx );
307
+
308
+ MD5Update (& ctx , strInputString , len );
309
+ MD5Final (MD5Digest , & ctx );
310
+
311
+
312
+ }
0 commit comments