1
/* Copyright (C) 2000 MySQL AB
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.
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.
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 */
16
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
19
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
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
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.
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.
37
These notices must be retained in any copies of any part of this
38
documentation and/or software.
43
Replace of MD5_memset and MD5_memcpy with memset & memcpy
46
#include <my_global.h>
50
/* Constants for MD5Transform routine. */
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));
76
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
77
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
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))
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
89
/* F, G, H and I are basic MD5 functions.
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)))
96
/* ROTATE_LEFT rotates x left n bits.
98
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
100
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
101
Rotation is separate from addition to prevent recomputation.
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)); \
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)); \
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)); \
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)); \
124
/* MD5 initialization. Begins an MD5 operation, writing a new context.
126
void my_MD5Init (my_MD5_CTX *context) /* context */
128
context->count[0] = context->count[1] = 0;
129
/* Load magic initialization constants.
131
context->state[0] = 0x67452301;
132
context->state[1] = 0xefcdab89;
133
context->state[2] = 0x98badcfe;
134
context->state[3] = 0x10325476;
137
/* MD5 block update operation. Continues an MD5 message-digest
138
operation, processing another message block, and updating the
143
my_MD5_CTX *context, /* context */
144
unsigned char *input, /* input block */
145
unsigned int inputLen) /* length of input block */
147
unsigned int i, idx, partLen;
149
/* Compute number of bytes mod 64 */
150
idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
153
/* Update number of bits */
154
if ((context->count[0] += ((UINT4)inputLen << 3))
155
< ((UINT4)inputLen << 3))
157
context->count[1] += ((UINT4)inputLen >> 29);
161
/* Transform as many times as possible.
163
if (inputLen >= partLen) {
164
MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen);
165
MD5Transform(context->state, context->buffer);
167
for (i = partLen; i + 63 < inputLen; i += 64)
168
MD5Transform (context->state, &input[i]);
175
/* Buffer remaining input */
176
MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i],
180
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
181
the message digest and zeroizing the context.
185
unsigned char digest[16], /* message digest */
186
my_MD5_CTX *context) /* context */
188
unsigned char bits[8];
189
unsigned int idx, padLen;
191
/* Save number of bits */
192
Encode (bits, context->count, 8);
194
/* Pad out to 56 mod 64.
196
idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
197
padLen = (idx < 56) ? (56 - idx) : (120 - idx);
198
my_MD5Update (context, PADDING, padLen);
200
/* Append length (before padding) */
201
my_MD5Update (context, bits, 8);
203
/* Store state in digest */
204
Encode (digest, context->state, 16);
206
/* Zeroize sensitive information.
208
MD5_memset ((POINTER)context, 0, sizeof (*context));
211
/* MD5 basic transformation. Transforms state based on block.
213
static void MD5Transform (
215
unsigned char block[64])
217
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
219
Decode (x, block, 64);
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 */
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 */
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 */
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 */
299
/* Zeroize sensitive information.
301
MD5_memset ((POINTER)x, 0, sizeof (x));
304
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
308
unsigned char *output,
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);
323
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
328
unsigned char *input,
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);
338
/* Note: Replace "for loop" with standard memcpy if possible.
342
static void MD5_memcpy (output, input, len)
349
for (i = 0; i < len; i++)
350
output[i] = input[i];
354
/* Note: Replace "for loop" with standard memset if possible.
358
static void MD5_memset (output, value, len)
365
for (i = 0; i < len; i++)
366
((char *)output)[i] = (char)value;