source: trunk/third/moira/util/rsaref/md5c.c @ 23095

Revision 23095, 10.5 KB checked in by ghudson, 16 years ago (diff)
Import the moira package from SIPB Debathena.
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
5   rights reserved.
6
7   License to copy and use this software is granted provided that it
8   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
9   Algorithm" in all material mentioning or referencing this software
10   or this function.
11
12   License is also granted to make and use derivative works provided
13   that such works are identified as "derived from the RSA Data
14   Security, Inc. MD5 Message-Digest Algorithm" in all material
15   mentioning or referencing the derived work. 
16                                                                   
17   RSA Data Security, Inc. makes no representations concerning either
18   the merchantability of this software or the suitability of this
19   software for any particular purpose. It is provided "as is"
20   without express or implied warranty of any kind. 
21                                                                   
22   These notices must be retained in any copies of any part of this
23   documentation and/or software. 
24 */
25
26#include "global.h"
27#include "md5.h"
28
29/* Constants for MD5Transform routine.
30 */
31#define S11 7
32#define S12 12
33#define S13 17
34#define S14 22
35#define S21 5
36#define S22 9
37#define S23 14
38#define S24 20
39#define S31 4
40#define S32 11
41#define S33 16
42#define S34 23
43#define S41 6
44#define S42 10
45#define S43 15
46#define S44 21
47
48static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
49static void Encode PROTO_LIST
50  ((unsigned char *, UINT4 *, unsigned int));
51static void Decode PROTO_LIST
52  ((UINT4 *, unsigned char *, unsigned int));
53static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
54static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
55
56static unsigned char PADDING[64] = {
57  0x80, 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, 0, 0, 0, 0,
59  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
60};
61
62/* F, G, H and I are basic MD5 functions.
63 */
64#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
65#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
66#define H(x, y, z) ((x) ^ (y) ^ (z))
67#define I(x, y, z) ((y) ^ ((x) | (~z)))
68
69/* ROTATE_LEFT rotates x left n bits.
70 */
71#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
72
73/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
74   Rotation is separate from addition to prevent recomputation.
75 */
76#define FF(a, b, c, d, x, s, ac) { \
77    (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
78    (a) = ROTATE_LEFT ((a), (s)); \
79    (a) += (b); \
80  }
81#define GG(a, b, c, d, x, s, ac) { \
82    (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
83    (a) = ROTATE_LEFT ((a), (s)); \
84    (a) += (b); \
85  }
86#define HH(a, b, c, d, x, s, ac) { \
87    (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
88    (a) = ROTATE_LEFT ((a), (s)); \
89    (a) += (b); \
90  }
91#define II(a, b, c, d, x, s, ac) { \
92    (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
93    (a) = ROTATE_LEFT ((a), (s)); \
94    (a) += (b); \
95  }
96
97/* MD5 initialization. Begins an MD5 operation, writing a new context.
98 */
99void MD5Init (context)
100MD5_CTX *context;                                        /* context */
101{
102  context->count[0] = context->count[1] = 0;
103
104  /* Load magic initialization constants.
105   */
106  context->state[0] = 0x67452301;
107  context->state[1] = 0xefcdab89;
108  context->state[2] = 0x98badcfe;
109  context->state[3] = 0x10325476;
110}
111
112/* MD5 block update operation. Continues an MD5 message-digest
113     operation, processing another message block, and updating the
114     context.
115 */
116void MD5Update (context, input, inputLen)
117MD5_CTX *context;                                        /* context */
118unsigned char *input;                                /* input block */
119unsigned int inputLen;                     /* length of input block */
120{
121  unsigned int i, index, partLen;
122
123  /* Compute number of bytes mod 64 */
124  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
125
126  /* Update number of bits */
127  if ((context->count[0] += ((UINT4)inputLen << 3))
128      < ((UINT4)inputLen << 3))
129    context->count[1]++;
130  context->count[1] += ((UINT4)inputLen >> 29);
131 
132  partLen = 64 - index;
133 
134  /* Transform as many times as possible.
135   */
136  if (inputLen >= partLen) {
137    MD5_memcpy
138      ((POINTER)&context->buffer[index], (POINTER)input, partLen);
139    MD5Transform (context->state, context->buffer);
140 
141    for (i = partLen; i + 63 < inputLen; i += 64)
142      MD5Transform (context->state, &input[i]);
143   
144    index = 0;
145  }
146  else
147    i = 0;
148 
149  /* Buffer remaining input */
150  MD5_memcpy
151    ((POINTER)&context->buffer[index], (POINTER)&input[i],
152     inputLen-i);
153}
154
155/* MD5 finalization. Ends an MD5 message-digest operation, writing the
156     the message digest and zeroizing the context.
157 */
158void MD5Final (digest, context)
159unsigned char digest[16];                         /* message digest */
160MD5_CTX *context;                                       /* context */
161{
162  unsigned char bits[8];
163  unsigned int index, padLen;
164
165  /* Save number of bits */
166  Encode (bits, context->count, 8);
167
168  /* Pad out to 56 mod 64.
169   */
170  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
171  padLen = (index < 56) ? (56 - index) : (120 - index);
172  MD5Update (context, PADDING, padLen);
173 
174  /* Append length (before padding) */
175  MD5Update (context, bits, 8);
176
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 */
312static void MD5_memcpy (output, input, len)
313POINTER output;
314POINTER input;
315unsigned int len;
316{
317  unsigned int i;
318 
319  for (i = 0; i < len; i++)
320    output[i] = input[i];
321}
322
323/* Note: Replace "for loop" with standard memset if possible.
324 */
325static void MD5_memset (output, value, len)
326POINTER output;
327int value;
328unsigned int len;
329{
330  unsigned int i;
331 
332  for (i = 0; i < len; i++)
333    ((char *)output)[i] = (char)value;
334}
Note: See TracBrowser for help on using the repository browser.