~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/md5.c

  • Committer: Stewart Smith
  • Date: 2008-07-13 06:56:15 UTC
  • mto: (210.1.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 211.
  • Revision ID: stewart@flamingspork.com-20080713065615-vzok75kgnnviokl9
Move MD5() into a UDF

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