ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/src/crypt.c
Revision: 34
Committed: Sun Oct 2 21:05:51 2005 UTC (18 years, 5 months ago) by lusky
Content type: text/x-csrc
File size: 14184 byte(s)
Log Message:
create 7.2 branch, we can move/rename it as needed.


File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * crypt.c: Provides MD5 password crypt() functions.
4 *
5 * ----------------------------------------------------------------------------
6 * "THE BEER-WARE LICENSE" (Revision 42):
7 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
8 * can do whatever you want with this stuff. If we meet some day, and you think
9 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
10 * ----------------------------------------------------------------------------
11 *
12 * $Id$
13 */
14
15 #include "stdinc.h"
16
17 #define MD5_SIZE 16
18
19 /* MD5 context. */
20 typedef struct MD5Context {
21 u_int32_t state[4]; /* state (ABCD) */
22 u_int32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
23 unsigned char buffer[64]; /* input buffer */
24 } MD5_CTX;
25
26 void MD5Init (MD5_CTX *);
27 void MD5Update (MD5_CTX *, const unsigned char *, unsigned int);
28 void MD5Pad (MD5_CTX *);
29 void MD5Final (unsigned char [16], MD5_CTX *);
30 char * MD5End(MD5_CTX *, char *);
31 char * MD5File(const char *, char *);
32 char * MD5Data(const unsigned char *, unsigned int, char *);
33
34 static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
35 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
36
37 void
38 _crypt_to64(s, v, n)
39 char *s;
40 unsigned long v;
41 int n;
42 {
43 while (--n >= 0) {
44 *s++ = itoa64[v&0x3f];
45 v >>= 6;
46 }
47 }
48
49 /*
50 * UNIX password
51 */
52
53 char *
54 crypt(const char *pw, const char *salt)
55 {
56 static char *magic = "$1$"; /*
57 * This string is magic for
58 * this algorithm. Having
59 * it this way, we can get
60 * better later on
61 */
62 static char passwd[120], *p;
63 static const char *sp,*ep;
64 unsigned char final[MD5_SIZE];
65 int sl,pl,i;
66 MD5_CTX ctx,ctx1;
67 unsigned long l;
68
69 /* Refine the Salt first */
70 sp = salt;
71
72 /* If it starts with the magic string, then skip that */
73 if(!strncmp(sp,magic,strlen(magic)))
74 sp += strlen(magic);
75
76 /* It stops at the first '$', max 8 chars */
77 for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
78 continue;
79
80 /* get the length of the true salt */
81 sl = ep - sp;
82
83 MD5Init(&ctx);
84
85 /* The password first, since that is what is most unknown */
86 MD5Update(&ctx,(const unsigned char *)pw,strlen(pw));
87
88 /* Then our magic string */
89 MD5Update(&ctx,(const unsigned char *)magic,strlen(magic));
90
91 /* Then the raw salt */
92 MD5Update(&ctx,(const unsigned char *)sp,sl);
93
94 /* Then just as many characters of the MD5(pw,salt,pw) */
95 MD5Init(&ctx1);
96 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
97 MD5Update(&ctx1,(const unsigned char *)sp,sl);
98 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
99 MD5Final(final,&ctx1);
100 for(pl = strlen(pw); pl > 0; pl -= MD5_SIZE)
101 MD5Update(&ctx,final,pl>MD5_SIZE ? MD5_SIZE : pl);
102
103 /* Don't leave anything around in vm they could use. */
104 memset(final,0,sizeof final);
105
106 /* Then something really weird... */
107 for (i = strlen(pw); i ; i >>= 1)
108 if(i&1)
109 MD5Update(&ctx, final, 1);
110 else
111 MD5Update(&ctx, (const unsigned char *)pw, 1);
112
113 /* Now make the output string */
114 strcpy(passwd,magic);
115 strncat(passwd,sp,sl);
116 strcat(passwd,"$");
117
118 MD5Final(final,&ctx);
119
120 /*
121 * and now, just to make sure things don't run too fast
122 * On a 60 Mhz Pentium this takes 34 msec, so you would
123 * need 30 seconds to build a 1000 entry dictionary...
124 */
125 for(i=0;i<1000;i++) {
126 MD5Init(&ctx1);
127 if(i & 1)
128 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
129 else
130 MD5Update(&ctx1,final,MD5_SIZE);
131
132 if(i % 3)
133 MD5Update(&ctx1,(const unsigned char *)sp,sl);
134
135 if(i % 7)
136 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
137
138 if(i & 1)
139 MD5Update(&ctx1,final,MD5_SIZE);
140 else
141 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
142 MD5Final(final,&ctx1);
143 }
144
145 p = passwd + strlen(passwd);
146
147 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
148 _crypt_to64(p,l,4); p += 4;
149 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
150 _crypt_to64(p,l,4); p += 4;
151 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
152 _crypt_to64(p,l,4); p += 4;
153 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
154 _crypt_to64(p,l,4); p += 4;
155 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
156 _crypt_to64(p,l,4); p += 4;
157 l = final[11] ;
158 _crypt_to64(p,l,2); p += 2;
159 *p = '\0';
160
161 /* Don't leave anything around in vm they could use. */
162 memset(final,0,sizeof final);
163
164 return passwd;
165 }
166
167 /*
168 * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
169 *
170 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
171 * rights reserved.
172 *
173 * License to copy and use this software is granted provided that it
174 * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
175 * Algorithm" in all material mentioning or referencing this software
176 * or this function.
177 *
178 * License is also granted to make and use derivative works provided
179 * that such works are identified as "derived from the RSA Data
180 * Security, Inc. MD5 Message-Digest Algorithm" in all material
181 * mentioning or referencing the derived work.
182 *
183 * RSA Data Security, Inc. makes no representations concerning either
184 * the merchantability of this software or the suitability of this
185 * software for any particular purpose. It is provided "as is"
186 * without express or implied warranty of any kind.
187 *
188 * These notices must be retained in any copies of any part of this
189 * documentation and/or software.
190 *
191 * $FreeBSD: src/lib/libmd/md5c.c,v 1.11 1999/12/29 05:04:20 peter Exp $
192 *
193 * This code is the same as the code published by RSA Inc. It has been
194 * edited for clarity and style only.
195 */
196
197 static void MD5Transform (u_int32_t [4], const unsigned char [64]);
198
199 /*
200 * Encodes input (u_int32_t) into output (unsigned char). Assumes len is
201 * a multiple of 4.
202 */
203
204 static void
205 Encode (output, input, len)
206 unsigned char *output;
207 u_int32_t *input;
208 unsigned int len;
209 {
210 unsigned int i, j;
211
212 for (i = 0, j = 0; j < len; i++, j += 4) {
213 output[j] = (unsigned char)(input[i] & 0xff);
214 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
215 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
216 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
217 }
218 }
219
220 /*
221 * Decodes input (unsigned char) into output (u_int32_t). Assumes len is
222 * a multiple of 4.
223 */
224
225 static void
226 Decode (output, input, len)
227 u_int32_t *output;
228 const unsigned char *input;
229 unsigned int len;
230 {
231 unsigned int i, j;
232
233 for (i = 0, j = 0; j < len; i++, j += 4)
234 output[i] = ((u_int32_t)input[j]) | (((u_int32_t)input[j+1]) << 8) |
235 (((u_int32_t)input[j+2]) << 16) | (((u_int32_t)input[j+3]) << 24);
236 }
237
238 static unsigned char PADDING[64] = {
239 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
240 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
242 };
243
244 /* F, G, H and I are basic MD5 functions. */
245 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
246 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
247 #define H(x, y, z) ((x) ^ (y) ^ (z))
248 #define I(x, y, z) ((y) ^ ((x) | (~z)))
249
250 /* ROTATE_LEFT rotates x left n bits. */
251 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
252
253 /*
254 * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
255 * Rotation is separate from addition to prevent recomputation.
256 */
257 #define FF(a, b, c, d, x, s, ac) { \
258 (a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
259 (a) = ROTATE_LEFT ((a), (s)); \
260 (a) += (b); \
261 }
262 #define GG(a, b, c, d, x, s, ac) { \
263 (a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
264 (a) = ROTATE_LEFT ((a), (s)); \
265 (a) += (b); \
266 }
267 #define HH(a, b, c, d, x, s, ac) { \
268 (a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
269 (a) = ROTATE_LEFT ((a), (s)); \
270 (a) += (b); \
271 }
272 #define II(a, b, c, d, x, s, ac) { \
273 (a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
274 (a) = ROTATE_LEFT ((a), (s)); \
275 (a) += (b); \
276 }
277
278 /* MD5 initialization. Begins an MD5 operation, writing a new context. */
279
280 void
281 MD5Init (context)
282 MD5_CTX *context;
283 {
284
285 context->count[0] = context->count[1] = 0;
286
287 /* Load magic initialization constants. */
288 context->state[0] = 0x67452301;
289 context->state[1] = 0xefcdab89;
290 context->state[2] = 0x98badcfe;
291 context->state[3] = 0x10325476;
292 }
293
294 /*
295 * MD5 block update operation. Continues an MD5 message-digest
296 * operation, processing another message block, and updating the
297 * context.
298 */
299
300 void
301 MD5Update (context, input, inputLen)
302 MD5_CTX *context;
303 const unsigned char *input;
304 unsigned int inputLen;
305 {
306 unsigned int i, index, partLen;
307
308 /* Compute number of bytes mod 64 */
309 index = (unsigned int)((context->count[0] >> 3) & 0x3F);
310
311 /* Update number of bits */
312 if ((context->count[0] += ((u_int32_t)inputLen << 3))
313 < ((u_int32_t)inputLen << 3))
314 context->count[1]++;
315 context->count[1] += ((u_int32_t)inputLen >> 29);
316
317 partLen = 64 - index;
318
319 /* Transform as many times as possible. */
320 if (inputLen >= partLen) {
321 memcpy((void *)&context->buffer[index], (const void *)input,
322 partLen);
323 MD5Transform (context->state, context->buffer);
324
325 for (i = partLen; i + 63 < inputLen; i += 64)
326 MD5Transform (context->state, &input[i]);
327
328 index = 0;
329 }
330 else
331 i = 0;
332
333 /* Buffer remaining input */
334 memcpy ((void *)&context->buffer[index], (const void *)&input[i],
335 inputLen-i);
336 }
337
338 /*
339 * MD5 padding. Adds padding followed by original length.
340 */
341
342 void
343 MD5Pad (context)
344 MD5_CTX *context;
345 {
346 unsigned char bits[8];
347 unsigned int index, padLen;
348
349 /* Save number of bits */
350 Encode (bits, context->count, 8);
351
352 /* Pad out to 56 mod 64. */
353 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
354 padLen = (index < 56) ? (56 - index) : (120 - index);
355 MD5Update (context, PADDING, padLen);
356
357 /* Append length (before padding) */
358 MD5Update (context, bits, 8);
359 }
360
361 /*
362 * MD5 finalization. Ends an MD5 message-digest operation, writing the
363 * the message digest and zeroizing the context.
364 */
365
366 void
367 MD5Final (digest, context)
368 unsigned char digest[16];
369 MD5_CTX *context;
370 {
371 /* Do padding. */
372 MD5Pad (context);
373
374 /* Store state in digest */
375 Encode (digest, context->state, 16);
376
377 /* Zeroize sensitive information. */
378 memset ((void *)context, 0, sizeof (*context));
379 }
380
381 /* MD5 basic transformation. Transforms state based on block. */
382
383 static void
384 MD5Transform (state, block)
385 u_int32_t state[4];
386 const unsigned char block[64];
387 {
388 u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
389
390 Decode (x, block, 64);
391
392 /* Round 1 */
393 #define S11 7
394 #define S12 12
395 #define S13 17
396 #define S14 22
397 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
398 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
399 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
400 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
401 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
402 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
403 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
404 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
405 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
406 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
407 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
408 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
409 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
410 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
411 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
412 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
413
414 /* Round 2 */
415 #define S21 5
416 #define S22 9
417 #define S23 14
418 #define S24 20
419 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
420 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
421 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
422 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
423 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
424 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
425 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
426 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
427 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
428 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
429 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
430 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
431 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
432 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
433 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
434 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
435
436 /* Round 3 */
437 #define S31 4
438 #define S32 11
439 #define S33 16
440 #define S34 23
441 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
442 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
443 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
444 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
445 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
446 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
447 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
448 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
449 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
450 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
451 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
452 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
453 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
454 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
455 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
456 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
457
458 /* Round 4 */
459 #define S41 6
460 #define S42 10
461 #define S43 15
462 #define S44 21
463 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
464 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
465 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
466 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
467 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
468 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
469 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
470 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
471 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
472 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
473 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
474 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
475 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
476 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
477 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
478 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
479
480 state[0] += a;
481 state[1] += b;
482 state[2] += c;
483 state[3] += d;
484
485 /* Zeroize sensitive information. */
486 memset ((void *)x, 0, sizeof (x));
487 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision