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