/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- crypt_md5
1 /*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.org> 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
10 /* #include <sys/cdefs.h>
11 __FBSDID("$FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.12 2002/03/25 15:55:36 phk Exp $");
12 */
13 #include <config.h>
14 #include <unistd.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <md5.h>
18 /* #include <err.h> */
19 #include "crypt.h"
20
21 /*
22 * UNIX password
23 */
24
25 char *
26 crypt_md5(const char *pw, const char *salt)
/* [<][>][^][v][top][bottom][index][help] */
27 {
28 MD5_CTX ctx,ctx1;
29 unsigned long l;
30 int sl, pl;
31 u_int i;
32 u_char final[MD5_SIZE];
33 static const char *sp, *ep;
34 static char passwd[120], *p;
35 static const char *magic = "$1$"; /*
36 * This string is magic for
37 * this algorithm. Having
38 * it this way, we can get
39 * better later on.
40 */
41
42 /* Refine the Salt first */
43 sp = salt;
44
45 /* If it starts with the magic string, then skip that */
46 if(!strncmp(sp, magic, strlen(magic)))
47 sp += strlen(magic);
48
49 /* It stops at the first '$', max 8 chars */
50 for(ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
51 continue;
52
53 /* get the length of the true salt */
54 sl = ep - sp;
55
56 MD5Init(&ctx);
57
58 /* The password first, since that is what is most unknown */
59 MD5Update(&ctx, (u_char *)pw, strlen(pw));
60
61 /* Then our magic string */
62 MD5Update(&ctx, (u_char *)magic, strlen(magic));
63
64 /* Then the raw salt */
65 MD5Update(&ctx, (u_char *)sp, (u_int)sl);
66
67 /* Then just as many characters of the MD5(pw,salt,pw) */
68 MD5Init(&ctx1);
69 MD5Update(&ctx1, (u_char *)pw, strlen(pw));
70 MD5Update(&ctx1, (u_char *)sp, (u_int)sl);
71 MD5Update(&ctx1, (u_char *)pw, strlen(pw));
72 MD5Final(final, &ctx1);
73 for(pl = (int)strlen(pw); pl > 0; pl -= MD5_SIZE)
74 MD5Update(&ctx, (u_char *)final,
75 (u_int)(pl > MD5_SIZE ? MD5_SIZE : pl));
76
77 /* Don't leave anything around in vm they could use. */
78 memset(final, 0, sizeof(final));
79
80 /* Then something really weird... */
81 for (i = strlen(pw); i; i >>= 1)
82 if(i & 1)
83 MD5Update(&ctx, (u_char *)final, 1);
84 else
85 MD5Update(&ctx, (u_char *)pw, 1);
86
87 /* Now make the output string */
88 strcpy(passwd, magic);
89 strncat(passwd, sp, (u_int)sl);
90 strcat(passwd, "$");
91
92 MD5Final(final, &ctx);
93
94 /*
95 * and now, just to make sure things don't run too fast
96 * On a 60 Mhz Pentium this takes 34 msec, so you would
97 * need 30 seconds to build a 1000 entry dictionary...
98 */
99 for(i = 0; i < 1000; i++) {
100 MD5Init(&ctx1);
101 if(i & 1)
102 MD5Update(&ctx1, (u_char *)pw, strlen(pw));
103 else
104 MD5Update(&ctx1, (u_char *)final, MD5_SIZE);
105
106 if(i % 3)
107 MD5Update(&ctx1, (u_char *)sp, (u_int)sl);
108
109 if(i % 7)
110 MD5Update(&ctx1, (u_char *)pw, strlen(pw));
111
112 if(i & 1)
113 MD5Update(&ctx1, (u_char *)final, MD5_SIZE);
114 else
115 MD5Update(&ctx1, (u_char *)pw, strlen(pw));
116 MD5Final(final, &ctx1);
117 }
118
119 p = passwd + strlen(passwd);
120
121 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
122 _crypt_to64(p, l, 4); p += 4;
123 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
124 _crypt_to64(p, l, 4); p += 4;
125 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
126 _crypt_to64(p, l, 4); p += 4;
127 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
128 _crypt_to64(p, l, 4); p += 4;
129 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
130 _crypt_to64(p, l, 4); p += 4;
131 l = final[11] ;
132 _crypt_to64(p, l, 2); p += 2;
133 *p = '\0';
134
135 /* Don't leave anything around in vm they could use. */
136 memset(final, 0, sizeof(final));
137
138 return passwd;
139 }
140
141