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