]> jfr.im git - irc/evilnet/x3.git/blame - src/md5.c
Minor typo in previous commit where returning 0 when it should have been 1 from opser...
[irc/evilnet/x3.git] / src / md5.c
CommitLineData
1c0d5243 1/*
2 * RFC 1321 compliant MD5 implementation
3 *
4 * Copyright (C) 2001-2003 Christophe Devine
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
348683aa 8 * the Free Software Foundation; either version 3 of the License, or
1c0d5243 9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <string.h>
22
23#include "common.h"
24#include "md5.h"
25
26#define OLDPASSFUNC
27#ifdef OLDPASSFUNC
28/* ----------------------------------------------------- */
29/* DELETE THIS SOME DAY - OLD STUFF HERE */
30/* ----------------------------------------------------- */
31
d76ed9a9 32/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */
33
34/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
35rights reserved.
36
37License to copy and use this software is granted provided that it
38is identified as the "RSA Data Security, Inc. MD5 Message-Digest
39Algorithm" in all material mentioning or referencing this software
40or this function.
41
42License is also granted to make and use derivative works provided
43that such works are identified as "derived from the RSA Data
44Security, Inc. MD5 Message-Digest Algorithm" in all material
45mentioning or referencing the derived work.
46
47RSA Data Security, Inc. makes no representations concerning either
48the merchantability of this software or the suitability of this
49software for any particular purpose. It is provided "as is"
50without express or implied warranty of any kind.
51
52These notices must be retained in any copies of any part of this
53documentation and/or software.
54 */
55
d76ed9a9 56/* Constants for MD5Transform routine.
57 */
58#define S11 7
59#define S12 12
60#define S13 17
61#define S14 22
62#define S21 5
63#define S22 9
64#define S23 14
65#define S24 20
66#define S31 4
67#define S32 11
68#define S33 16
69#define S34 23
70#define S41 6
71#define S42 10
72#define S43 15
73#define S44 21
74
75static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
76static void Encode PROTO_LIST
77 ((unsigned char *, UINT4 *, unsigned int));
78static void Decode PROTO_LIST
79 ((UINT4 *, unsigned char *, unsigned int));
80
81static unsigned char PADDING[64] = {
82 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
85};
86
87/* F, G, H and I are basic MD5 functions.
88 */
89#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
90#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
91#define H(x, y, z) ((x) ^ (y) ^ (z))
92#define I(x, y, z) ((y) ^ ((x) | (~z)))
93
94/* ROTATE_LEFT rotates x left n bits. */
95#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
96
97/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
98Rotation is separate from addition to prevent recomputation.
99 */
100#define FF(a, b, c, d, x, s, ac) { \
101 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
102 (a) = ROTATE_LEFT ((a), (s)); \
103 (a) += (b); \
104 }
105#define GG(a, b, c, d, x, s, ac) { \
106 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
107 (a) = ROTATE_LEFT ((a), (s)); \
108 (a) += (b); \
109 }
110#define HH(a, b, c, d, x, s, ac) { \
111 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
112 (a) = ROTATE_LEFT ((a), (s)); \
113 (a) += (b); \
114 }
115#define II(a, b, c, d, x, s, ac) { \
116 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
117 (a) = ROTATE_LEFT ((a), (s)); \
118 (a) += (b); \
119 }
120
121/* MD5 initialization. Begins an MD5 operation, writing a new context. */
122void MD5Init (context)
123MD5_CTX *context; /* context */
124{
125 context->count[0] = context->count[1] = 0;
126 /* Load magic initialization constants. */
127 context->state[0] = 0x67452301;
128 context->state[1] = 0xefcdab89;
129 context->state[2] = 0x98badcfe;
130 context->state[3] = 0x10325476;
131}
132
133/* MD5 block update operation. Continues an MD5 message-digest
134 operation, processing another message block, and updating the
135 context.
136 */
137void MD5Update (context, input, inputLen)
138MD5_CTX *context; /* context */
139unsigned char *input; /* input block */
140unsigned int inputLen; /* length of input block */
141{
1136f709 142 unsigned int i, idx, partLen;
d76ed9a9 143
144 /* Compute number of bytes mod 64 */
1136f709 145 idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
d76ed9a9 146
147 /* Update number of bits */
148 if ((context->count[0] += ((UINT4)inputLen << 3))
149 < ((UINT4)inputLen << 3))
150 context->count[1]++;
151 context->count[1] += ((UINT4)inputLen >> 29);
152
1136f709 153 partLen = 64 - idx;
d76ed9a9 154
155 /* Transform as many times as possible. */
156 if (inputLen >= partLen) {
1136f709 157 memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen);
d76ed9a9 158 MD5Transform (context->state, context->buffer);
159
160 for (i = partLen; i + 63 < inputLen; i += 64)
161 MD5Transform (context->state, &input[i]);
162
1136f709 163 idx = 0;
d76ed9a9 164 }
165 else
166 i = 0;
167
168 /* Buffer remaining input */
1136f709 169 memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i],
d76ed9a9 170 inputLen-i);
171}
172
173/* MD5 finalization. Ends an MD5 message-digest operation, writing the
174 the message digest and zeroizing the context.
175 */
176void MD5Final (digest, context)
177unsigned char digest[16]; /* message digest */
178MD5_CTX *context; /* context */
179{
180 unsigned char bits[8];
1136f709 181 unsigned int idx, padLen;
d76ed9a9 182
183 /* Save number of bits */
184 Encode (bits, context->count, 8);
185
186 /* Pad out to 56 mod 64. */
1136f709 187 idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
188 padLen = (idx < 56) ? (56 - idx) : (120 - idx);
d76ed9a9 189 MD5Update (context, PADDING, padLen);
190
191 /* Append length (before padding) */
192 MD5Update (context, bits, 8);
193
194 /* Store state in digest */
195 Encode (digest, context->state, 16);
196
197 /* Zeroize sensitive information. */
198 memset ((POINTER)context, 0, sizeof (*context));
199}
200
201/* MD5 basic transformation. Transforms state based on block. */
202static void MD5Transform (state, block)
203UINT4 state[4];
204unsigned char block[64];
205{
206 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
207
208 Decode (x, block, 64);
209
210 /* Round 1 */
211 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
212 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
213 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
214 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
215 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
216 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
217 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
218 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
219 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
220 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
221 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
222 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
223 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
224 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
225 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
226 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
227
228 /* Round 2 */
229 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
230 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
231 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
232 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
233 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
234 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
235 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
236 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
237 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
238 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
239 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
240 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
241 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
242 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
243 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
244 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
245
246 /* Round 3 */
247 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
248 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
249 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
250 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
251 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
252 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
253 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
254 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
255 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
256 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
257 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
258 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
259 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
260 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
261 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
262 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
263
264 /* Round 4 */
265 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
266 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
267 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
268 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
269 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
270 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
271 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
272 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
273 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
274 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
275 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
276 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
277 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
278 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
279 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
280 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
281
282 state[0] += a;
283 state[1] += b;
284 state[2] += c;
285 state[3] += d;
286
287 /* Zeroize sensitive information. */
288 memset ((POINTER)x, 0, sizeof (x));
289}
290
291/* Encodes input (UINT4) into output (unsigned char). Assumes len is
292 a multiple of 4.
293 */
294static void Encode (output, input, len)
295unsigned char *output;
296UINT4 *input;
297unsigned int len;
298{
299 unsigned int i, j;
300
301 for (i = 0, j = 0; j < len; i++, j += 4) {
302 output[j] = (unsigned char)(input[i] & 0xff);
303 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
304 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
305 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
306 }
307}
308
309/* Decodes input (unsigned char) into output (UINT4). Assumes len is
310 a multiple of 4.
311 */
312static void Decode (output, input, len)
313UINT4 *output;
314unsigned char *input;
315unsigned int len;
316{
317 unsigned int i, j;
318
319 for (i = 0, j = 0; j < len; i++, j += 4)
320 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
321 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
322}
323
324static const char *
325cryptpass_real(const char *pass, char *buffer, int seed)
326{
327 static const char hex_digits[] = "0123456789ABCDEF";
328 MD5_CTX ctx;
329 unsigned int len, i, j;
330 unsigned char temp[64], buff[16];
331
332 /* first: generate seed */
333 if (seed) {
334 for (i=j=0; j<4; j++) {
335 temp[i++] = hex_digits[(seed >> (28 - 8*j)) & 15];
336 temp[i++] = hex_digits[(seed >> (24 - 8*j)) & 15];
337 }
338 /* fill temp buffer with password, 1 and then 0's */
339 j = strlen(pass);
340 if ((sizeof(temp) - i) < j) j = sizeof(temp) - i;
341 memcpy(temp+i, pass, j);
342 i += j;
343 if (i < sizeof(temp)) temp[i++] = '1';
344 while (i < sizeof(temp)) temp[i++] = '0';
345 } else {
346 i = 0;
347 /* next: duplicate password to fill temp buffer */
348 len = strlen(pass);
349 for (j=0; i<sizeof(temp); i++) {
350 temp[i] = pass[j];
351 if (++j == len) j = 0;
352 }
353 }
354 /* next: compute MD5 digest of repeated password */
355 MD5Init(&ctx);
356 MD5Update(&ctx, temp, sizeof(temp));
357 MD5Final(buff, &ctx);
358 /* finally: write digest to output buffer */
359 if (seed) {
360 buffer[0] = '$';
361 for (i=0,j=1; i<4; i++) {
362 buffer[j++] = hex_digits[(seed >> (28 - 8*i)) & 15];
363 buffer[j++] = hex_digits[(seed >> (24 - 8*i)) & 15];
364 }
365 } else {
366 j = 0;
367 }
368 for (i=0; i<sizeof(buff); i++) {
369 buffer[j++] = hex_digits[buff[i] >> 4];
370 buffer[j++] = hex_digits[buff[i] & 15];
371 }
372 buffer[j] = 0;
373 return buffer;
374}
375
1c0d5243 376/* ----------------------------------------------------- */
377/* DELETE ABOVE SOME DAY -- OLD STUFF */
378/* ----------------------------------------------------- */
379
380#endif
381
382#define GET_UINT32(n,b,i) \
383{ \
384 (n) = ( (uint32) (b)[(i) ] ) \
385 | ( (uint32) (b)[(i) + 1] << 8 ) \
386 | ( (uint32) (b)[(i) + 2] << 16 ) \
387 | ( (uint32) (b)[(i) + 3] << 24 ); \
388}
389
390#define PUT_UINT32(n,b,i) \
391{ \
392 (b)[(i) ] = (uint8) ( (n) ); \
393 (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \
394 (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \
395 (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \
396}
397
398void md5_starts( md5_context *ctx )
399{
400 ctx->total[0] = 0;
401 ctx->total[1] = 0;
402
403 ctx->state[0] = 0x67452301;
404 ctx->state[1] = 0xEFCDAB89;
405 ctx->state[2] = 0x98BADCFE;
406 ctx->state[3] = 0x10325476;
407}
408
409void md5_process( md5_context *ctx, uint8 data[64] )
410{
411 uint32 X[16], A, B, C, D;
412
413 GET_UINT32( X[0], data, 0 );
414 GET_UINT32( X[1], data, 4 );
415 GET_UINT32( X[2], data, 8 );
416 GET_UINT32( X[3], data, 12 );
417 GET_UINT32( X[4], data, 16 );
418 GET_UINT32( X[5], data, 20 );
419 GET_UINT32( X[6], data, 24 );
420 GET_UINT32( X[7], data, 28 );
421 GET_UINT32( X[8], data, 32 );
422 GET_UINT32( X[9], data, 36 );
423 GET_UINT32( X[10], data, 40 );
424 GET_UINT32( X[11], data, 44 );
425 GET_UINT32( X[12], data, 48 );
426 GET_UINT32( X[13], data, 52 );
427 GET_UINT32( X[14], data, 56 );
428 GET_UINT32( X[15], data, 60 );
429
430#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
431
432#define P(a,b,c,d,k,s,t) \
433{ \
434 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
435}
436
437 A = ctx->state[0];
438 B = ctx->state[1];
439 C = ctx->state[2];
440 D = ctx->state[3];
441
34938510 442#undef F
1c0d5243 443#define F(x,y,z) (z ^ (x & (y ^ z)))
444
445 P( A, B, C, D, 0, 7, 0xD76AA478 );
446 P( D, A, B, C, 1, 12, 0xE8C7B756 );
447 P( C, D, A, B, 2, 17, 0x242070DB );
448 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
449 P( A, B, C, D, 4, 7, 0xF57C0FAF );
450 P( D, A, B, C, 5, 12, 0x4787C62A );
451 P( C, D, A, B, 6, 17, 0xA8304613 );
452 P( B, C, D, A, 7, 22, 0xFD469501 );
453 P( A, B, C, D, 8, 7, 0x698098D8 );
454 P( D, A, B, C, 9, 12, 0x8B44F7AF );
455 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
456 P( B, C, D, A, 11, 22, 0x895CD7BE );
457 P( A, B, C, D, 12, 7, 0x6B901122 );
458 P( D, A, B, C, 13, 12, 0xFD987193 );
459 P( C, D, A, B, 14, 17, 0xA679438E );
460 P( B, C, D, A, 15, 22, 0x49B40821 );
461
462#undef F
463
464#define F(x,y,z) (y ^ (z & (x ^ y)))
465
466 P( A, B, C, D, 1, 5, 0xF61E2562 );
467 P( D, A, B, C, 6, 9, 0xC040B340 );
468 P( C, D, A, B, 11, 14, 0x265E5A51 );
469 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
470 P( A, B, C, D, 5, 5, 0xD62F105D );
471 P( D, A, B, C, 10, 9, 0x02441453 );
472 P( C, D, A, B, 15, 14, 0xD8A1E681 );
473 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
474 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
475 P( D, A, B, C, 14, 9, 0xC33707D6 );
476 P( C, D, A, B, 3, 14, 0xF4D50D87 );
477 P( B, C, D, A, 8, 20, 0x455A14ED );
478 P( A, B, C, D, 13, 5, 0xA9E3E905 );
479 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
480 P( C, D, A, B, 7, 14, 0x676F02D9 );
481 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
482
483#undef F
484
485#define F(x,y,z) (x ^ y ^ z)
486
487 P( A, B, C, D, 5, 4, 0xFFFA3942 );
488 P( D, A, B, C, 8, 11, 0x8771F681 );
489 P( C, D, A, B, 11, 16, 0x6D9D6122 );
490 P( B, C, D, A, 14, 23, 0xFDE5380C );
491 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
492 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
493 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
494 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
495 P( A, B, C, D, 13, 4, 0x289B7EC6 );
496 P( D, A, B, C, 0, 11, 0xEAA127FA );
497 P( C, D, A, B, 3, 16, 0xD4EF3085 );
498 P( B, C, D, A, 6, 23, 0x04881D05 );
499 P( A, B, C, D, 9, 4, 0xD9D4D039 );
500 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
501 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
502 P( B, C, D, A, 2, 23, 0xC4AC5665 );
503
504#undef F
505
506#define F(x,y,z) (y ^ (x | ~z))
507
508 P( A, B, C, D, 0, 6, 0xF4292244 );
509 P( D, A, B, C, 7, 10, 0x432AFF97 );
510 P( C, D, A, B, 14, 15, 0xAB9423A7 );
511 P( B, C, D, A, 5, 21, 0xFC93A039 );
512 P( A, B, C, D, 12, 6, 0x655B59C3 );
513 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
514 P( C, D, A, B, 10, 15, 0xFFEFF47D );
515 P( B, C, D, A, 1, 21, 0x85845DD1 );
516 P( A, B, C, D, 8, 6, 0x6FA87E4F );
517 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
518 P( C, D, A, B, 6, 15, 0xA3014314 );
519 P( B, C, D, A, 13, 21, 0x4E0811A1 );
520 P( A, B, C, D, 4, 6, 0xF7537E82 );
521 P( D, A, B, C, 11, 10, 0xBD3AF235 );
522 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
523 P( B, C, D, A, 9, 21, 0xEB86D391 );
524
525#undef F
526
527 ctx->state[0] += A;
528 ctx->state[1] += B;
529 ctx->state[2] += C;
530 ctx->state[3] += D;
531}
532
533void md5_update( md5_context *ctx, uint8 *input, uint32 length )
534{
535 uint32 left, fill;
536
537 if( ! length ) return;
538
539 left = ctx->total[0] & 0x3F;
540 fill = 64 - left;
541
542 ctx->total[0] += length;
543 ctx->total[0] &= 0xFFFFFFFF;
544
545 if( ctx->total[0] < length )
546 ctx->total[1]++;
547
548 if( left && length >= fill )
549 {
550 memcpy( (void *) (ctx->buffer + left),
551 (void *) input, fill );
552 md5_process( ctx, ctx->buffer );
553 length -= fill;
554 input += fill;
555 left = 0;
556 }
557
558 while( length >= 64 )
559 {
560 md5_process( ctx, input );
561 length -= 64;
562 input += 64;
563 }
564
565 if( length )
566 {
567 memcpy( (void *) (ctx->buffer + left),
568 (void *) input, length );
569 }
570}
571
572static uint8 md5_padding[64] =
573{
574 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
575 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
576 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
577 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
578};
579
580void md5_finish( md5_context *ctx, uint8 digest[16] )
581{
582 uint32 last, padn;
583 uint32 high, low;
584 uint8 msglen[8];
585
586 high = ( ctx->total[0] >> 29 )
587 | ( ctx->total[1] << 3 );
588 low = ( ctx->total[0] << 3 );
589
590 PUT_UINT32( low, msglen, 0 );
591 PUT_UINT32( high, msglen, 4 );
592
593 last = ctx->total[0] & 0x3F;
594 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
595
596 md5_update( ctx, md5_padding, padn );
597 md5_update( ctx, msglen, 8 );
598
599 PUT_UINT32( ctx->state[0], digest, 0 );
600 PUT_UINT32( ctx->state[1], digest, 4 );
601 PUT_UINT32( ctx->state[2], digest, 8 );
602 PUT_UINT32( ctx->state[3], digest, 12 );
603}
604
605#define TEST
606#ifdef TEST
607
608#include <stdlib.h>
609#include <stdio.h>
610
611/*
612 * those are the standard RFC 1321 test vectors
613 */
614
ceafd592 615char* md5(const char* pass, char* output)
1c0d5243 616{
617 md5_context ctx;
618 int j;
619 unsigned char md5sum[16];
620
621 md5_starts( &ctx );
622 md5_update( &ctx, (uint8 *) pass, strlen(pass));
623 md5_finish( &ctx, md5sum );
624 for(j = 0; j<16; j++)
625 {
626 sprintf(output + j * 2, "%02x", md5sum[j]);
627 }
e166c31b 628 /* printf("The hash of %s is %s\n\n", pass, output); */
ceafd592 629 return 0;
1c0d5243 630}
631
d76ed9a9 632const char *
633cryptpass(const char *pass, char *buffer)
634{
1c0d5243 635 return md5(pass, buffer);
d76ed9a9 636}
637
638int
1136f709 639checkpass(const char *pass, const char *crypted)
d76ed9a9 640{
1136f709 641 char new_crypted[MD5_CRYPT_LENGTH], hseed[9];
d76ed9a9 642 int seed;
643
1136f709 644 if (crypted[0] == '$') {
d76ed9a9 645 /* new-style crypt, use "seed" after '$' */
1136f709 646 strncpy(hseed, crypted+1, 8);
d76ed9a9 647 hseed[8] = 0;
648 seed = strtoul(hseed, NULL, 16);
1136f709 649 cryptpass_real(pass, new_crypted, seed);
d76ed9a9 650 } else {
1c0d5243 651 /* new "old-style" md5 crypt compatable with php, md5sum etc */
1136f709 652 md5(pass, new_crypted);
d76ed9a9 653 }
1136f709 654 return !strcmp(crypted, new_crypted);
d76ed9a9 655}
1c0d5243 656
657
658
659#endif