~drizzle-trunk/drizzle/development

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