~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/md5.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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