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