ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/src/crypt.c
Revision: 33
Committed: Sun Oct 2 20:50:00 2005 UTC (19 years, 10 months ago) by knight
Content type: text/x-csrc
Original Path: ircd-hybrid/src/crypt.c
File size: 14184 byte(s)
Log Message:
- svn:keywords

File Contents

# User Rev Content
1 adx 30 /*
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 knight 31 * $Id$
13 adx 30 */
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