2 * Copyright (c) 2003 Poul-Henning Kamp
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 static char *_crypt_to64(char *s
, uint32_t v
, int n
)
37 static const char itoa64
[64] = "./0123456789"
38 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
41 *s
++ = itoa64
[v
& 0x3f];
47 char *crypt_md5(const char *pw
, const char *salt
)
53 uint8_t final
[MD5_SIZE
];
55 static char passwd
[120]; /* Output buffer */
56 static const char magic
[] = "$1$";
58 const int magic_len
= sizeof magic
- 1;
59 int pwlen
= strlen(pw
);
61 /* Refine the Salt first */
64 /* If it starts with the magic string, then skip that */
65 if (!strncmp(sp
, magic
, magic_len
))
68 /* Compute the salt length:
69 it stops at the first '$', max 8 chars */
70 for (sl
= 0; sl
< 8 && sp
[sl
] && sp
[sl
] != '$'; sl
++) ;
74 /* The password first, since that is what is most unknown */
75 MD5Update(&ctx
, pw
, pwlen
);
77 /* Then our magic string */
78 MD5Update(&ctx
, magic
, magic_len
);
80 /* Then the raw salt */
81 MD5Update(&ctx
, sp
, sl
);
83 /* Then just as many characters of the MD5(pw,salt,pw) */
85 MD5Update(&ctx1
, pw
, pwlen
);
86 MD5Update(&ctx1
, sp
, sl
);
87 MD5Update(&ctx1
, pw
, pwlen
);
88 MD5Final(final
, &ctx1
);
89 for (pl
= pwlen
; pl
> 0; pl
-= MD5_SIZE
)
90 MD5Update(&ctx
, final
, pl
> MD5_SIZE
? MD5_SIZE
: pl
);
92 /* Don't leave anything around in vm they could use. */
93 memset(final
, 0, sizeof final
);
95 /* Then something really weird... */
96 for (i
= pwlen
; i
; i
>>= 1)
98 MD5Update(&ctx
, final
, 1);
100 MD5Update(&ctx
, pw
, 1);
102 /* Now make the output string */
105 memcpy(p
, magic
, magic_len
);
113 MD5Final(final
, &ctx
);
116 * and now, just to make sure things don't run too fast
117 * On a 60 Mhz Pentium this takes 34 msec, so you would
118 * need 30 seconds to build a 1000 entry dictionary...
120 for (i
= 0; i
< 1000; i
++) {
123 MD5Update(&ctx1
, pw
, pwlen
);
125 MD5Update(&ctx1
, final
, MD5_SIZE
);
128 MD5Update(&ctx1
, sp
, sl
);
131 MD5Update(&ctx1
, pw
, pwlen
);
134 MD5Update(&ctx1
, final
, MD5_SIZE
);
136 MD5Update(&ctx1
, pw
, pwlen
);
137 MD5Final(final
, &ctx1
);
140 l
= (final
[0] << 16) | (final
[6] << 8) | final
[12];
141 p
= _crypt_to64(p
, l
, 4);
142 l
= (final
[1] << 16) | (final
[7] << 8) | final
[13];
143 p
= _crypt_to64(p
, l
, 4);
144 l
= (final
[2] << 16) | (final
[8] << 8) | final
[14];
145 p
= _crypt_to64(p
, l
, 4);
146 l
= (final
[3] << 16) | (final
[9] << 8) | final
[15];
147 p
= _crypt_to64(p
, l
, 4);
148 l
= (final
[4] << 16) | (final
[10] << 8) | final
[5];
149 p
= _crypt_to64(p
, l
, 4);
151 p
= _crypt_to64(p
, l
, 2);
154 /* Don't leave anything around in vm they could use. */
155 memset(final
, 0, sizeof final
);
163 int main(int argc
, char *argv
[])
167 for (i
= 2; i
< argc
; i
+= 2) {
168 puts(crypt_md5(argv
[i
], argv
[i
- 1]));