source: rtems/cpukit/httpd/md5c.c @ 0a7278e

4.104.115
Last change on this file since 0a7278e was 0a7278e, checked in by Ralf Corsepius <ralf.corsepius@…>, on 11/29/09 at 13:20:53

Whitespace removal.

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