1 | /*
|
---|
2 | * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
---|
3 | *
|
---|
4 | * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
---|
5 | * rights reserved.
|
---|
6 | *
|
---|
7 | * License to copy and use this software is granted provided that it
|
---|
8 | * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
---|
9 | * Algorithm" in all material mentioning or referencing this software
|
---|
10 | * or this function.
|
---|
11 | *
|
---|
12 | * License is also granted to make and use derivative works provided
|
---|
13 | * that such works are identified as "derived from the RSA Data
|
---|
14 | * Security, Inc. MD5 Message-Digest Algorithm" in all material
|
---|
15 | * mentioning or referencing the derived work.
|
---|
16 | *
|
---|
17 | * RSA Data Security, Inc. makes no representations concerning either
|
---|
18 | * the merchantability of this software or the suitability of this
|
---|
19 | * software for any particular purpose. It is provided "as is"
|
---|
20 | * without express or implied warranty of any kind.
|
---|
21 | *
|
---|
22 | * These notices must be retained in any copies of any part of this
|
---|
23 | * documentation and/or software.
|
---|
24 | *
|
---|
25 | * $FreeBSD: src/lib/libmd/md5c.c,v 1.9.2.1 1999/08/29 14:57:12 peter Exp $
|
---|
26 | *
|
---|
27 | * This code is the same as the code published by RSA Inc. It has been
|
---|
28 | * edited for clarity and style only.
|
---|
29 | *
|
---|
30 | * ----------------------------------------------------------------------------
|
---|
31 | * The md5_crypt() function was taken from freeBSD's libcrypt and contains
|
---|
32 | * this license:
|
---|
33 | * "THE BEER-WARE LICENSE" (Revision 42):
|
---|
34 | * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
|
---|
35 | * can do whatever you want with this stuff. If we meet some day, and you think
|
---|
36 | * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
---|
37 | *
|
---|
38 | * $FreeBSD: src/lib/libcrypt/crypt.c,v 1.7.2.1 1999/08/29 14:56:33 peter Exp $
|
---|
39 | *
|
---|
40 | * ----------------------------------------------------------------------------
|
---|
41 | * On April 19th, 2001 md5_crypt() was modified to make it reentrant
|
---|
42 | * by Erik Andersen <andersen@uclibc.org>
|
---|
43 | *
|
---|
44 | *
|
---|
45 | * June 28, 2001 Manuel Novoa III
|
---|
46 | *
|
---|
47 | * "Un-inlined" code using loops and static const tables in order to
|
---|
48 | * reduce generated code size (on i386 from approx 4k to approx 2.5k).
|
---|
49 | *
|
---|
50 | * June 29, 2001 Manuel Novoa III
|
---|
51 | *
|
---|
52 | * Completely removed static PADDING array.
|
---|
53 | *
|
---|
54 | * Reintroduced the loop unrolling in MD5_Transform and added the
|
---|
55 | * MD5_SIZE_OVER_SPEED option for configurability. Define below as:
|
---|
56 | * 0 fully unrolled loops
|
---|
57 | * 1 partially unrolled (4 ops per loop)
|
---|
58 | * 2 no unrolling -- introduces the need to swap 4 variables (slow)
|
---|
59 | * 3 no unrolling and all 4 loops merged into one with switch
|
---|
60 | * in each loop (glacial)
|
---|
61 | * On i386, sizes are roughly (-Os -fno-builtin):
|
---|
62 | * 0: 3k 1: 2.5k 2: 2.2k 3: 2k
|
---|
63 | *
|
---|
64 | * Since SuSv3 does not require crypt_r, modified again August 7, 2002
|
---|
65 | * by Erik Andersen to remove reentrance stuff...
|
---|
66 | */
|
---|
67 |
|
---|
68 | /*
|
---|
69 | * UNIX password
|
---|
70 | *
|
---|
71 | * Use MD5 for what it is best at...
|
---|
72 | */
|
---|
73 | #define MD5_OUT_BUFSIZE 36
|
---|
74 | static char *
|
---|
75 | NOINLINE
|
---|
76 | md5_crypt(char result[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned char *salt)
|
---|
77 | {
|
---|
78 | char *p;
|
---|
79 | unsigned char final[17]; /* final[16] exists only to aid in looping */
|
---|
80 | int sl, pl, i, pw_len;
|
---|
81 | md5_ctx_t ctx, ctx1;
|
---|
82 |
|
---|
83 | /* NB: in busybox, "$1$" in salt is always present */
|
---|
84 |
|
---|
85 | /* Refine the Salt first */
|
---|
86 |
|
---|
87 | /* Get the length of the salt including "$1$" */
|
---|
88 | sl = 3;
|
---|
89 | while (salt[sl] && salt[sl] != '$' && sl < (3 + 8))
|
---|
90 | sl++;
|
---|
91 |
|
---|
92 | /* Hash. the password first, since that is what is most unknown */
|
---|
93 | md5_begin(&ctx);
|
---|
94 | pw_len = strlen((char*)pw);
|
---|
95 | md5_hash(&ctx, pw, pw_len);
|
---|
96 |
|
---|
97 | /* Then the salt including "$1$" */
|
---|
98 | md5_hash(&ctx, salt, sl);
|
---|
99 |
|
---|
100 | /* Copy salt to result; skip "$1$" */
|
---|
101 | memcpy(result, salt, sl);
|
---|
102 | result[sl] = '$';
|
---|
103 | salt += 3;
|
---|
104 | sl -= 3;
|
---|
105 |
|
---|
106 | /* Then just as many characters of the MD5(pw, salt, pw) */
|
---|
107 | md5_begin(&ctx1);
|
---|
108 | md5_hash(&ctx1, pw, pw_len);
|
---|
109 | md5_hash(&ctx1, salt, sl);
|
---|
110 | md5_hash(&ctx1, pw, pw_len);
|
---|
111 | md5_end(&ctx1, final);
|
---|
112 | for (pl = pw_len; pl > 0; pl -= 16)
|
---|
113 | md5_hash(&ctx, final, pl > 16 ? 16 : pl);
|
---|
114 |
|
---|
115 | /* Then something really weird... */
|
---|
116 | memset(final, 0, sizeof(final));
|
---|
117 | for (i = pw_len; i; i >>= 1) {
|
---|
118 | md5_hash(&ctx, ((i & 1) ? final : (const unsigned char *) pw), 1);
|
---|
119 | }
|
---|
120 | md5_end(&ctx, final);
|
---|
121 |
|
---|
122 | /* And now, just to make sure things don't run too fast.
|
---|
123 | * On a 60 Mhz Pentium this takes 34 msec, so you would
|
---|
124 | * need 30 seconds to build a 1000 entry dictionary...
|
---|
125 | */
|
---|
126 | for (i = 0; i < 1000; i++) {
|
---|
127 | md5_begin(&ctx1);
|
---|
128 | if (i & 1)
|
---|
129 | md5_hash(&ctx1, pw, pw_len);
|
---|
130 | else
|
---|
131 | md5_hash(&ctx1, final, 16);
|
---|
132 |
|
---|
133 | if (i % 3)
|
---|
134 | md5_hash(&ctx1, salt, sl);
|
---|
135 |
|
---|
136 | if (i % 7)
|
---|
137 | md5_hash(&ctx1, pw, pw_len);
|
---|
138 |
|
---|
139 | if (i & 1)
|
---|
140 | md5_hash(&ctx1, final, 16);
|
---|
141 | else
|
---|
142 | md5_hash(&ctx1, pw, pw_len);
|
---|
143 | md5_end(&ctx1, final);
|
---|
144 | }
|
---|
145 |
|
---|
146 | p = result + sl + 4; /* 12 bytes max (sl is up to 8 bytes) */
|
---|
147 |
|
---|
148 | /* Add 5*4+2 = 22 bytes of hash, + NUL byte. */
|
---|
149 | final[16] = final[5];
|
---|
150 | for (i = 0; i < 5; i++) {
|
---|
151 | unsigned l = (final[i] << 16) | (final[i+6] << 8) | final[i+12];
|
---|
152 | p = to64(p, l, 4);
|
---|
153 | }
|
---|
154 | p = to64(p, final[11], 2);
|
---|
155 | *p = '\0';
|
---|
156 |
|
---|
157 | /* Don't leave anything around in vm they could use. */
|
---|
158 | memset(final, 0, sizeof(final));
|
---|
159 |
|
---|
160 | return result;
|
---|
161 | }
|
---|