1 /* $NetBSD: md5crypt.c,v 1.12 2012/08/30 12:16:49 drochner Exp $ */
4 * ----------------------------------------------------------------------------
5 * "THE BEER-WARE LICENSE" (Revision 42):
6 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
7 * can do whatever you want with this stuff. If we meet some day, and you think
8 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
9 * ----------------------------------------------------------------------------
11 * from FreeBSD: crypt.c,v 1.5 1996/10/14 08:34:02 phk Exp
12 * via OpenBSD: md5crypt.c,v 1.9 1997/07/23 20:58:27 kstailey Exp
16 #include <sys/cdefs.h>
18 __RCSID("$NetBSD: md5crypt.c,v 1.12 2012/08/30 12:16:49 drochner Exp $");
28 #define MD5_MAGIC "$1$"
29 #define MD5_MAGIC_LEN 3
31 #define INIT(x) MD5Init((x))
32 #define UPDATE(x, b, l) MD5Update((x), (b), (l))
33 #define FINAL(v, x) MD5Final((v), (x))
37 * MD5 password encryption.
40 __md5crypt(const char *pw
, const char *salt
)
42 static char passwd
[120], *p
;
44 unsigned char final
[16];
45 unsigned int i
, sl
, pwl
;
52 /* Refine the salt first */
55 /* If it starts with the magic string, then skip that */
56 if (strncmp(sp
, MD5_MAGIC
, MD5_MAGIC_LEN
) == 0)
59 /* It stops at the first '$', max 8 chars */
60 for (ep
= sp
; *ep
!= '\0' && *ep
!= '$' && ep
< (sp
+ 8); ep
++)
63 /* get the length of the true salt */
68 /* The password first, since that is what is most unknown */
69 UPDATE(&ctx
, (const unsigned char *)pw
, pwl
);
71 /* Then our magic string */
72 UPDATE(&ctx
, (const unsigned char *)MD5_MAGIC
, MD5_MAGIC_LEN
);
74 /* Then the raw salt */
75 UPDATE(&ctx
, (const unsigned char *)sp
, sl
);
77 /* Then just as many characters of the MD5(pw,salt,pw) */
79 UPDATE(&ctx1
, (const unsigned char *)pw
, pwl
);
80 UPDATE(&ctx1
, (const unsigned char *)sp
, sl
);
81 UPDATE(&ctx1
, (const unsigned char *)pw
, pwl
);
84 for (pl
= pwl
; pl
> 0; pl
-= 16)
85 UPDATE(&ctx
, final
, (unsigned int)(pl
> 16 ? 16 : pl
));
87 /* Don't leave anything around in vm they could use. */
88 memset(final
, 0, sizeof(final
));
90 /* Then something really weird... */
91 for (i
= pwl
; i
!= 0; i
>>= 1)
93 UPDATE(&ctx
, final
, 1);
95 UPDATE(&ctx
, (const unsigned char *)pw
, 1);
97 /* Now make the output string */
98 memcpy(passwd
, MD5_MAGIC
, MD5_MAGIC_LEN
);
99 strlcpy(passwd
+ MD5_MAGIC_LEN
, sp
, sl
+ 1);
100 strlcat(passwd
, "$", sizeof(passwd
));
104 /* memset(&ctx, 0, sizeof(ctx)); done by MD5Final() */
107 * And now, just to make sure things don't run too fast. On a 60 MHz
108 * Pentium this takes 34 msec, so you would need 30 seconds to build
109 * a 1000 entry dictionary...
111 for (i
= 0; i
< 1000; i
++) {
115 UPDATE(&ctx1
, (const unsigned char *)pw
, pwl
);
117 UPDATE(&ctx1
, final
, 16);
120 UPDATE(&ctx1
, (const unsigned char *)sp
, sl
);
123 UPDATE(&ctx1
, (const unsigned char *)pw
, pwl
);
126 UPDATE(&ctx1
, final
, 16);
128 UPDATE(&ctx1
, (const unsigned char *)pw
, pwl
);
133 /* memset(&ctx1, 0, sizeof(ctx1)); done by MD5Final() */
135 p
= passwd
+ sl
+ MD5_MAGIC_LEN
+ 1;
137 l
= (final
[ 0]<<16) | (final
[ 6]<<8) | final
[12]; __crypt_to64(p
,l
,4); p
+= 4;
138 l
= (final
[ 1]<<16) | (final
[ 7]<<8) | final
[13]; __crypt_to64(p
,l
,4); p
+= 4;
139 l
= (final
[ 2]<<16) | (final
[ 8]<<8) | final
[14]; __crypt_to64(p
,l
,4); p
+= 4;
140 l
= (final
[ 3]<<16) | (final
[ 9]<<8) | final
[15]; __crypt_to64(p
,l
,4); p
+= 4;
141 l
= (final
[ 4]<<16) | (final
[10]<<8) | final
[ 5]; __crypt_to64(p
,l
,4); p
+= 4;
142 l
= final
[11] ; __crypt_to64(p
,l
,2); p
+= 2;
145 /* Don't leave anything around in vm they could use. */
146 __explicit_bzero(final
, sizeof(final
));