source: rtems/cpukit/httpd/md5c.c @ dc7fb59b

4.104.114.84.95
Last change on this file since dc7fb59b was a6b4c0df, checked in by Joel Sherrill <joel.sherrill@…>, on 09/01/00 at 10:57:21

2000-08-30 Joel Sherrill <joel@…>

  • Merged version 2.1 of GoAhead? webserver. This update was submitted by Antti P Miettinen <antti.p.miettinen@…>.
  • NOTES, base64.c, ejIntrn.h, emfdb.c, emfdb.h, md5.h, md5c.c, um.c, um.h: New files.
  • wbase64.c: Removed.
  • Makefile.am, asp.c, balloc.c, default.c, ej.h, ejlex.c, ejparse.c, form.c, h.c, handler.c, mime.c, misc.c, ringq.c, rom.c, security.c, socket.c, sym.c, uemf.c, uemf.h, url.c, value.c, webcomp.c, webmain.c, webpage.c, webrom.c, webs.c, webs.h, websuemf.c, wsIntrn.h: Modified.
  • Property mode set to 100644
File size: 10.2 KB
Line 
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#include "md5.h"
27
28/* Constants for MD5Transform routine.
29 */
30#define S11 7
31#define S12 12
32#define S13 17
33#define S14 22
34#define S21 5
35#define S22 9
36#define S23 14
37#define S24 20
38#define S31 4
39#define S32 11
40#define S33 16
41#define S34 23
42#define S41 6
43#define S42 10
44#define S43 15
45#define S44 21
46
47static void MD5Transform (UINT4 [4], unsigned char [64]);
48static void Encode (unsigned char *, UINT4 *, unsigned int);
49static void Decode (UINT4 *, unsigned char *, unsigned int);
50static void MD5_memcpy (POINTER, POINTER, unsigned int);
51static void MD5_memset (POINTER, int, unsigned int);
52
53static unsigned char PADDING[64] = {
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/*
60 *      Note:   The following MD5 macros can be implemented as functions
61 *                      for code compactness, (at the expense of execution speed).
62 */
63
64/* F, G, H and I are basic MD5 functions.
65 */
66#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
67#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
68#define H(x, y, z) ((x) ^ (y) ^ (z))
69#define I(x, y, z) ((y) ^ ((x) | (~z)))
70
71/* ROTATE_LEFT rotates x left n bits.
72 */
73#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
74
75/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
76Rotation is separate from addition to prevent recomputation.
77 */
78#define FF(a, b, c, d, x, s, ac) { \
79 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
80 (a) = ROTATE_LEFT ((a), (s)); \
81 (a) += (b); \
82  }
83#define GG(a, b, c, d, x, s, ac) { \
84 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
85 (a) = ROTATE_LEFT ((a), (s)); \
86 (a) += (b); \
87  }
88#define HH(a, b, c, d, x, s, ac) { \
89 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
90 (a) = ROTATE_LEFT ((a), (s)); \
91 (a) += (b); \
92  }
93#define II(a, b, c, d, x, s, ac) { \
94 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
95 (a) = ROTATE_LEFT ((a), (s)); \
96 (a) += (b); \
97  }
98
99/* MD5 initialization. Begins an MD5 operation, writing a new context.
100 */
101void MD5Init (context)
102MD5_CONTEXT *context;                                        /* context */
103{
104  context->count[0] = context->count[1] = 0;
105  /* Load magic initialization constants.
106*/
107  context->state[0] = 0x67452301;
108  context->state[1] = 0xefcdab89;
109  context->state[2] = 0x98badcfe;
110  context->state[3] = 0x10325476;
111}
112
113/* MD5 block update operation. Continues an MD5 message-digest
114  operation, processing another message block, and updating the
115  context.
116 */
117void MD5Update (context, input, inputLen)
118MD5_CONTEXT *context;                                        /* context */
119unsigned char *input;                                /* input block */
120unsigned int inputLen;                     /* length of input block */
121{
122  unsigned int i, index, partLen;
123
124  /* Compute number of bytes mod 64 */
125  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
126
127  /* Update number of bits */
128  if ((context->count[0] += ((UINT4)inputLen << 3))
129   < ((UINT4)inputLen << 3))
130 context->count[1]++;
131  context->count[1] += ((UINT4)inputLen >> 29);
132
133  partLen = 64 - index;
134
135  /* Transform as many times as possible.
136*/
137  if (inputLen >= partLen) {
138 MD5_memcpy
139   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
140 MD5Transform (context->state, context->buffer);
141
142 for (i = partLen; i + 63 < inputLen; i += 64)
143   MD5Transform (context->state, &input[i]);
144
145 index = 0;
146  }
147  else
148 i = 0;
149
150  /* Buffer remaining input */
151  MD5_memcpy
152 ((POINTER)&context->buffer[index], (POINTER)&input[i],
153  inputLen-i);
154}
155
156/* MD5 finalization. Ends an MD5 message-digest operation, writing the
157  the message digest and zeroizing the context.
158 */
159void MD5Final (digest, context)
160unsigned char digest[16];                         /* message digest */
161MD5_CONTEXT *context;                                       /* context */
162{
163  unsigned char bits[8];
164  unsigned int index, padLen;
165
166  /* Save number of bits */
167  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  MD5Update (context, PADDING, padLen);
174
175  /* Append length (before padding) */
176  MD5Update (context, bits, 8);
177  /* Store state in digest */
178  Encode (digest, context->state, 16);
179
180  /* Zeroize sensitive information.
181*/
182  MD5_memset ((POINTER)context, 0, sizeof (*context));
183}
184
185/* MD5 basic transformation. Transforms state based on block.
186 */
187static void MD5Transform (state, block)
188UINT4 state[4];
189unsigned char block[64];
190{
191  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
192
193  Decode (x, block, 64);
194
195  /* Round 1 */
196  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
197  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
198  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
199  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
200  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
201  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
202  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
203  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
204  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
205  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
206  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
207  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
208  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
209  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
210  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
211  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
212
213 /* Round 2 */
214  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
215  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
216  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
217  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
218  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
219  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
220  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
221  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
222  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
223  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
224  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
225  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
226  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
227  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
228  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
229  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
230
231  /* Round 3 */
232  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
233  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
234  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
235  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
236  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
237  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
238  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
239  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
240  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
241  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
242  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
243  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
244  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
245  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
246  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
247  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
248
249  /* Round 4 */
250  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
251  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
252  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
253  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
254  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
255  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
256  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
257  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
258  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
259  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
260  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
261  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
262  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
263  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
264  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
265  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
266
267  state[0] += a;
268  state[1] += b;
269  state[2] += c;
270  state[3] += d;
271
272  /* Zeroize sensitive information.
273*/
274  MD5_memset ((POINTER)x, 0, sizeof (x));
275}
276
277/* Encodes input (UINT4) into output (unsigned char). Assumes len is
278  a multiple of 4.
279 */
280static void Encode (output, input, len)
281unsigned char *output;
282UINT4 *input;
283unsigned int len;
284{
285  unsigned int i, j;
286
287  for (i = 0, j = 0; j < len; i++, j += 4) {
288 output[j] = (unsigned char)(input[i] & 0xff);
289 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
290 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
291 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
292  }
293}
294
295/* Decodes input (unsigned char) into output (UINT4). Assumes len is
296  a multiple of 4.
297 */
298static void Decode (output, input, len)
299UINT4 *output;
300unsigned char *input;
301unsigned int len;
302{
303  unsigned int i, j;
304
305  for (i = 0, j = 0; j < len; i++, j += 4)
306 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
307   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
308}
309
310/* Note: Replace "for loop" with standard memcpy if possible.
311 */
312
313static void MD5_memcpy (output, input, len)
314POINTER output;
315POINTER input;
316unsigned int len;
317{
318        unsigned int i;
319
320        for (i = 0; i < len; i++)
321                output[i] = input[i];
322}
323
324/* Note: Replace "for loop" with standard memset if possible.
325 */
326static void MD5_memset (output, value, len)
327POINTER output;
328int value;
329unsigned int len;
330{
331  unsigned int i;
332
333  for (i = 0; i < len; i++)
334 ((char *)output)[i] = (char)value;
335}
Note: See TracBrowser for help on using the repository browser.