]> jfr.im git - irc/evilnet/x3.git/blob - src/md5.c
Couple of srvx updates.
[irc/evilnet/x3.git] / src / md5.c
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
8 * the Free Software Foundation; either version 3 of the License, or
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
32 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */
33
34 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
35 rights reserved.
36
37 License to copy and use this software is granted provided that it
38 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
39 Algorithm" in all material mentioning or referencing this software
40 or this function.
41
42 License is also granted to make and use derivative works provided
43 that such works are identified as "derived from the RSA Data
44 Security, Inc. MD5 Message-Digest Algorithm" in all material
45 mentioning or referencing the derived work.
46
47 RSA Data Security, Inc. makes no representations concerning either
48 the merchantability of this software or the suitability of this
49 software for any particular purpose. It is provided "as is"
50 without express or implied warranty of any kind.
51
52 These notices must be retained in any copies of any part of this
53 documentation and/or software.
54 */
55
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
75 static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
76 static void Encode PROTO_LIST
77 ((unsigned char *, UINT4 *, unsigned int));
78 static void Decode PROTO_LIST
79 ((UINT4 *, unsigned char *, unsigned int));
80
81 static 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.
98 Rotation 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. */
122 void MD5Init (context)
123 MD5_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 */
137 void MD5Update (context, input, inputLen)
138 MD5_CTX *context; /* context */
139 unsigned char *input; /* input block */
140 unsigned int inputLen; /* length of input block */
141 {
142 unsigned int i, idx, partLen;
143
144 /* Compute number of bytes mod 64 */
145 idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
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
153 partLen = 64 - idx;
154
155 /* Transform as many times as possible. */
156 if (inputLen >= partLen) {
157 memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen);
158 MD5Transform (context->state, context->buffer);
159
160 for (i = partLen; i + 63 < inputLen; i += 64)
161 MD5Transform (context->state, &input[i]);
162
163 idx = 0;
164 }
165 else
166 i = 0;
167
168 /* Buffer remaining input */
169 memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i],
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 */
176 void MD5Final (digest, context)
177 unsigned char digest[16]; /* message digest */
178 MD5_CTX *context; /* context */
179 {
180 unsigned char bits[8];
181 unsigned int idx, padLen;
182
183 /* Save number of bits */
184 Encode (bits, context->count, 8);
185
186 /* Pad out to 56 mod 64. */
187 idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
188 padLen = (idx < 56) ? (56 - idx) : (120 - idx);
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. */
202 static void MD5Transform (state, block)
203 UINT4 state[4];
204 unsigned 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 */
294 static void Encode (output, input, len)
295 unsigned char *output;
296 UINT4 *input;
297 unsigned 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 */
312 static void Decode (output, input, len)
313 UINT4 *output;
314 unsigned char *input;
315 unsigned 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
324 static const char *
325 cryptpass_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
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
398 void 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
409 void 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
442 #undef F
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
533 void 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
572 static 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
580 void 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
615 char* md5(const char* pass, char* output)
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 }
628 /* printf("The hash of %s is %s\n\n", pass, output); */
629 return 0;
630 }
631
632 const char *
633 cryptpass(const char *pass, char *buffer)
634 {
635 return md5(pass, buffer);
636 }
637
638 int
639 checkpass(const char *pass, const char *crypted)
640 {
641 char new_crypted[MD5_CRYPT_LENGTH], hseed[9];
642 int seed;
643
644 if (crypted[0] == '$') {
645 /* new-style crypt, use "seed" after '$' */
646 strncpy(hseed, crypted+1, 8);
647 hseed[8] = 0;
648 seed = strtoul(hseed, NULL, 16);
649 cryptpass_real(pass, new_crypted, seed);
650 } else {
651 /* new "old-style" md5 crypt compatable with php, md5sum etc */
652 md5(pass, new_crypted);
653 }
654 return !strcmp(crypted, new_crypted);
655 }
656
657
658
659 #endif