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