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