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 */
17
* This code implements the MD5 message-digest algorithm.
18
* The algorithm is due to Ron Rivest. This code was
19
* written by Colin Plumb in 1993, no copyright is claimed.
20
* This code is in the public domain; do with it what you wish.
22
* Equivalent code is available from RSA Data Security, Inc.
23
* This code has been tested against that, and is equivalent,
24
* except that you don't need to include two pages of legalese
27
* To compute the message digest of a chunk of bytes, declare an
28
* MD5Context structure, pass it to MD5Init, call MD5Update as
29
* needed on buffers full of bytes, and then call MD5Final, which
30
* will fill a supplied 16-byte array with the digest.
33
/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
34
not require an integer type which is exactly 32 bits. This work
35
draws on the changes for the same purpose by Tatu Ylonen
36
<ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
37
that code, there is no copyright issue. I hereby disclaim
38
copyright in any changes I have made; this code remains in the
41
#include <my_global.h>
45
#include <string.h> /* for memcpy() and memset() */
49
my_MD5Transform (cvs_uint32 buf[4], const unsigned char in[64]);
51
/* Little-endian byte-swapping routines. Note that these do not
52
depend on the size of datatypes such as uint32, nor do they require
53
us to detect the endianness of the machine we are running on. It
54
is possible they should be macros for speed, but I would be
55
surprised if they were a performance bottleneck for MD5. */
57
static uint32 getu32 (const unsigned char *addr)
59
return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
60
| addr[1]) << 8 | addr[0];
64
putu32 (uint32 data, unsigned char *addr)
66
addr[0] = (unsigned char)data;
67
addr[1] = (unsigned char)(data >> 8);
68
addr[2] = (unsigned char)(data >> 16);
69
addr[3] = (unsigned char)(data >> 24);
73
Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
74
initialization constants.
77
my_MD5Init (my_MD5Context *ctx)
79
ctx->buf[0] = 0x67452301;
80
ctx->buf[1] = 0xefcdab89;
81
ctx->buf[2] = 0x98badcfe;
82
ctx->buf[3] = 0x10325476;
89
Update context to reflect the concatenation of another buffer full
93
my_MD5Update (my_MD5Context *ctx, unsigned char const *buf, unsigned len)
100
if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t)
101
ctx->bits[1]++; /* Carry from low to high */
102
ctx->bits[1] += len >> 29;
104
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
106
/* Handle any leading odd-sized chunks */
109
unsigned char *p = ctx->in + t;
117
my_MD5Transform (ctx->buf, ctx->in);
122
/* Process data in 64-byte chunks */
125
memcpy(ctx->in, buf, 64);
126
my_MD5Transform (ctx->buf, ctx->in);
131
/* Handle any remaining bytes of data. */
133
memcpy(ctx->in, buf, len);
137
Final wrapup - pad to 64-byte boundary with the bit pattern
138
1 0* (64-bit count of bits processed, MSB-first)
141
my_MD5Final (unsigned char digest[16], my_MD5Context *ctx)
146
/* Compute number of bytes mod 64 */
147
count = (ctx->bits[0] >> 3) & 0x3F;
149
/* Set the first char of padding to 0x80. This is safe since there is
150
always at least one byte free */
154
/* Bytes of padding needed to make 64 bytes */
155
count = 64 - 1 - count;
157
/* Pad out to 56 mod 64 */
159
/* Two lots of padding: Pad the first block to 64 bytes */
161
my_MD5Transform (ctx->buf, ctx->in);
163
/* Now fill the next block with 56 bytes */
164
memset(ctx->in, 0, 56);
166
/* Pad block to 56 bytes */
167
memset(p, 0, count-8);
170
/* Append length in bits and transform */
171
putu32(ctx->bits[0], ctx->in + 56);
172
putu32(ctx->bits[1], ctx->in + 60);
174
my_MD5Transform (ctx->buf, ctx->in);
175
putu32(ctx->buf[0], digest);
176
putu32(ctx->buf[1], digest + 4);
177
putu32(ctx->buf[2], digest + 8);
178
putu32(ctx->buf[3], digest + 12);
179
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
184
/* The four core functions - F1 is optimized somewhat */
186
/* #define F1(x, y, z) (x & y | ~x & z) */
187
#define F1(x, y, z) (z ^ (x & (y ^ z)))
188
#define F2(x, y, z) F1(z, x, y)
189
#define F3(x, y, z) (x ^ y ^ z)
190
#define F4(x, y, z) (y ^ (x | ~z))
192
/* This is the central step in the MD5 algorithm. */
193
#define MD5STEP(f, w, x, y, z, data, s) \
194
( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
197
* The core of the MD5 algorithm, this alters an existing MD5 hash to
198
* reflect the addition of 16 longwords of new data. MD5Update blocks
199
* the data and converts bytes into longwords for this routine.
202
my_MD5Transform (uint32 buf[4], const unsigned char inraw[64])
204
register uint32 a, b, c, d;
208
for (i = 0; i < 16; ++i)
209
in[i] = getu32 (inraw + 4 * i);
216
MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
217
MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
218
MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
219
MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
220
MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
221
MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
222
MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
223
MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
224
MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
225
MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
226
MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
227
MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
228
MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
229
MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
230
MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
231
MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
233
MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
234
MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
235
MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
236
MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
237
MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
238
MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
239
MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
240
MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
241
MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
242
MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
243
MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
244
MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
245
MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
246
MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
247
MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
248
MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
250
MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
251
MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
252
MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
253
MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
254
MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
255
MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
256
MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
257
MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
258
MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
259
MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
260
MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
261
MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
262
MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
263
MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
264
MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
265
MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
267
MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
268
MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
269
MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
270
MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
271
MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
272
MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
273
MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
274
MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
275
MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
276
MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
277
MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
278
MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
279
MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
280
MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
281
MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
282
MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
293
Simple test program. Can use it to manually run the tests from
299
main (int argc, char **argv)
301
my_MD5Context context;
302
unsigned char checksum[16];
308
fprintf (stderr, "usage: %s string-to-hash\n", argv[0]);
311
for (j = 1; j < argc; ++j)
313
printf ("MD5 (\"%s\") = ", argv[j]);
314
my_MD5Init (&context);
315
my_MD5Update (&context, argv[j], strlen (argv[j]));
316
my_MD5Final (checksum, &context);
317
for (i = 0; i < 16; i++)
319
printf ("%02x", (unsigned int) checksum[i]);