]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libcrypt/crypt-md5.c
The new crypt code breaks "make world". Back it out.
[FreeBSD/FreeBSD.git] / lib / libcrypt / crypt-md5.c
1 /*
2  * ----------------------------------------------------------------------------
3  * "THE BEER-WARE LICENSE" (Revision 42):
4  * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
5  * can do whatever you want with this stuff. If we meet some day, and you think
6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7  * ----------------------------------------------------------------------------
8  *
9  * $FreeBSD$
10  *
11  */
12
13 /*
14 // Modularized by Brandon Gillespie
15 */
16
17 #if defined(LIBC_SCCS) && !defined(lint)
18 static char rcsid[] = "$Header: /home/ncvs/src/lib/libcrypt/crypt.c,v 1.4 1996/07/12 18:56:01 jkh Exp $";
19 #endif /* LIBC_SCCS and not lint */
20
21 #include <unistd.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include "crypt.h"
27
28 char *
29 crypt_md5(pw, pl, sp, sl, passwd, token)
30         register const unsigned char *pw;
31         const unsigned int pl;
32         register const unsigned char *sp;
33         const unsigned int sl;
34         char * passwd;
35         char * token;
36 {
37         char *p;
38         unsigned char final[_MD5_SIZE];
39         int i,j;
40         MD5_CTX ctx,ctx1;
41         unsigned long l;
42
43         MD5Init(&ctx);
44
45         /* The password first, since that is what is most unknown */
46         MD5Update(&ctx,pw,pl);
47
48         /* Then our magic string */
49         MD5Update(&ctx,(unsigned char *)token,strlen(token));
50
51         /* Then the raw salt */
52         MD5Update(&ctx,sp,sl);
53
54         /* Then just as many characters of the MD5(pw,salt,pw) */
55         MD5Init(&ctx1);
56         MD5Update(&ctx1,pw,pl);
57         MD5Update(&ctx1,sp,sl);
58         MD5Update(&ctx1,pw,pl);
59         MD5Final(final,&ctx1);
60         for(i = pl; i > 0; i -= 16)
61                 MD5Update(&ctx,final,i>16 ? 16 : i);
62
63         /* Don't leave anything around in vm they could use. */
64         memset(final,0,sizeof final);
65
66         /* Then something really weird... */
67         for (j=0,i = pl; i ; i >>= 1)
68                 if(i&1)
69                     MD5Update(&ctx, final+j, 1);
70                 else
71                     MD5Update(&ctx, pw+j, 1);
72
73         /* Now make the output string */
74         strcpy(passwd, token);
75         strncat(passwd, (char *)sp, (int)sl);
76         strcat(passwd, "$");
77
78         MD5Final(final,&ctx);
79
80         /*
81          * and now, just to make sure things don't run too fast
82          * On a 60 Mhz Pentium this takes 34 msec, so you would
83          * need 30 seconds to build a 1000 entry dictionary...
84          */
85         for(i=0;i<1000;i++) {
86                 MD5Init(&ctx1);
87                 if(i & 1)
88                         MD5Update(&ctx1,pw,pl);
89                 else
90                         MD5Update(&ctx1,final,_MD5_SIZE);
91
92                 if(i % 3)
93                         MD5Update(&ctx1,sp,sl);
94
95                 if(i % 7)
96                         MD5Update(&ctx1,pw,pl);
97
98                 if(i & 1)
99                         MD5Update(&ctx1,final,_MD5_SIZE);
100                 else
101                         MD5Update(&ctx1,pw,pl);
102                 MD5Final(final,&ctx1);
103         }
104
105         p = passwd + strlen(passwd);
106
107         l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
108         l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
109         l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
110         l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
111         l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
112         l =                    final[11]                ; to64(p,l,2); p += 2;
113         *p = '\0';
114
115         /* Don't leave anything around in vm they could use. */
116         memset(final,0,sizeof final);
117
118         return passwd;
119 }
120