aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-12 16:55:59 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-12 16:55:59 +0000
commit4ea83bf562c44a6792e7c77e7d87cba91f86f763 (patch)
tree64dba9163b29724e282c1e94027001a11978e74b
parent9de462205542547694299e9fe2bc321088ab79aa (diff)
downloadbusybox-w32-4ea83bf562c44a6792e7c77e7d87cba91f86f763.tar.gz
busybox-w32-4ea83bf562c44a6792e7c77e7d87cba91f86f763.tar.bz2
busybox-w32-4ea83bf562c44a6792e7c77e7d87cba91f86f763.zip
uclibc insists on having 70k static buffer for crypt.
For bbox it's not acceptable. Roll our own des and md5 crypt implementation. Against older uclibc: text data bss dec hex filename 759945 604 6684 767233 bb501 busybox_old 759766 604 6684 767054 bb44e busybox_unstripped so, we still save on code size.
-rw-r--r--include/libbb.h22
-rw-r--r--libbb/correct_password.c2
-rw-r--r--libbb/pw_encrypt.c53
-rw-r--r--libbb/pw_encrypt_des.c703
-rw-r--r--libbb/pw_encrypt_md5.c656
-rw-r--r--loginutils/chpasswd.c2
-rw-r--r--loginutils/cryptpw.c32
-rw-r--r--loginutils/passwd.c4
-rw-r--r--loginutils/sulogin.c2
-rw-r--r--networking/httpd.c4
10 files changed, 1456 insertions, 24 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 97aae0bb4..bd2dbe573 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1032,18 +1032,8 @@ extern int restricted_shell(const char *shell);
1032extern void setup_environment(const char *shell, int clear_env, int change_env, const struct passwd *pw); 1032extern void setup_environment(const char *shell, int clear_env, int change_env, const struct passwd *pw);
1033extern int correct_password(const struct passwd *pw); 1033extern int correct_password(const struct passwd *pw);
1034/* Returns a ptr to static storage */ 1034/* Returns a ptr to static storage */
1035extern char *pw_encrypt(const char *clear, const char *salt); 1035extern char *pw_encrypt(const char *clear, const char *salt, int cleanup);
1036extern int obscure(const char *old, const char *newval, const struct passwd *pwdp); 1036extern int obscure(const char *old, const char *newval, const struct passwd *pwdp);
1037
1038int index_in_str_array(const char *const string_array[], const char *key);
1039int index_in_strings(const char *strings, const char *key);
1040int index_in_substr_array(const char *const string_array[], const char *key);
1041int index_in_substrings(const char *strings, const char *key);
1042const char *nth_string(const char *strings, int n);
1043
1044extern void print_login_issue(const char *issue_file, const char *tty);
1045extern void print_login_prompt(void);
1046
1047/* rnd is additional random input. New one is returned. 1037/* rnd is additional random input. New one is returned.
1048 * Useful if you call crypt_make_salt many times in a row: 1038 * Useful if you call crypt_make_salt many times in a row:
1049 * rnd = crypt_make_salt(buf1, 4, 0); 1039 * rnd = crypt_make_salt(buf1, 4, 0);
@@ -1052,11 +1042,19 @@ extern void print_login_prompt(void);
1052 * (otherwise we risk having same salt generated) 1042 * (otherwise we risk having same salt generated)
1053 */ 1043 */
1054extern int crypt_make_salt(char *p, int cnt, int rnd); 1044extern int crypt_make_salt(char *p, int cnt, int rnd);
1055
1056/* Returns number of lines changed, or -1 on error */ 1045/* Returns number of lines changed, or -1 on error */
1057extern int update_passwd(const char *filename, const char *username, 1046extern int update_passwd(const char *filename, const char *username,
1058 const char *new_pw); 1047 const char *new_pw);
1059 1048
1049int index_in_str_array(const char *const string_array[], const char *key);
1050int index_in_strings(const char *strings, const char *key);
1051int index_in_substr_array(const char *const string_array[], const char *key);
1052int index_in_substrings(const char *strings, const char *key);
1053const char *nth_string(const char *strings, int n);
1054
1055extern void print_login_issue(const char *issue_file, const char *tty);
1056extern void print_login_prompt(void);
1057
1060/* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */ 1058/* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */
1061int get_terminal_width_height(int fd, unsigned *width, unsigned *height); 1059int get_terminal_width_height(int fd, unsigned *width, unsigned *height);
1062 1060
diff --git a/libbb/correct_password.c b/libbb/correct_password.c
index 96bb10e0b..a4ded8b5f 100644
--- a/libbb/correct_password.c
+++ b/libbb/correct_password.c
@@ -71,7 +71,7 @@ int correct_password(const struct passwd *pw)
71 if (!unencrypted) { 71 if (!unencrypted) {
72 return 0; 72 return 0;
73 } 73 }
74 encrypted = crypt(unencrypted, correct); 74 encrypted = pw_encrypt(unencrypted, correct, 1);
75 memset(unencrypted, 0, strlen(unencrypted)); 75 memset(unencrypted, 0, strlen(unencrypted));
76 return strcmp(encrypted, correct) == 0; 76 return strcmp(encrypted, correct) == 0;
77} 77}
diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c
index e9cf4e3b8..d439fc3b4 100644
--- a/libbb/pw_encrypt.c
+++ b/libbb/pw_encrypt.c
@@ -8,11 +8,52 @@
8 */ 8 */
9 9
10#include "libbb.h" 10#include "libbb.h"
11#include <crypt.h>
12 11
13char *pw_encrypt(const char *clear, const char *salt) 12/*
13 * DES and MD5 crypt implementations are taken from uclibc.
14 * They were modified to not use static buffers.
15 * Comparison with uclibc (before uclibc had 70k staic buffers reinstated):
16 * text data bss dec hex filename
17 * 759909 604 6684 767197 bb4dd busybox_old
18 * 759579 604 6684 766867 bb393 busybox_unstripped
19 */
20/* Common for them */
21static const uint8_t ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
22#include "pw_encrypt_des.c"
23#include "pw_encrypt_md5.c"
24
25
26static struct const_des_ctx *des_cctx;
27static struct des_ctx *des_ctx;
28
29/* my_crypt returns malloc'ed data */
30static char *my_crypt(const char *key, const char *salt)
31{
32 /* First, check if we are supposed to be using the MD5 replacement
33 * instead of DES... */
34 if (salt[0] == '$' && salt[1] == '1' && salt[2] == '$') {
35 return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt);
36 }
37
38 {
39 if (!des_cctx)
40 des_cctx = const_des_init();
41 des_ctx = des_init(des_ctx, des_cctx);
42 return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt);
43 }
44}
45
46/* So far nobody wants to have it public */
47static void my_crypt_cleanup(void)
48{
49 free(des_cctx);
50 free(des_ctx);
51 des_cctx = NULL;
52 des_ctx = NULL;
53}
54
55char *pw_encrypt(const char *clear, const char *salt, int cleanup)
14{ 56{
15 /* Was static char[BIGNUM]. Malloced thing works as well */
16 static char *cipher; 57 static char *cipher;
17 58
18#if 0 /* was CONFIG_FEATURE_SHA1_PASSWORDS, but there is no such thing??? */ 59#if 0 /* was CONFIG_FEATURE_SHA1_PASSWORDS, but there is no such thing??? */
@@ -22,6 +63,10 @@ char *pw_encrypt(const char *clear, const char *salt)
22#endif 63#endif
23 64
24 free(cipher); 65 free(cipher);
25 cipher = xstrdup(crypt(clear, salt)); 66 cipher = my_crypt(clear, salt);
67
68 if (cleanup)
69 my_crypt_cleanup();
70
26 return cipher; 71 return cipher;
27} 72}
diff --git a/libbb/pw_encrypt_des.c b/libbb/pw_encrypt_des.c
new file mode 100644
index 000000000..637765ead
--- /dev/null
+++ b/libbb/pw_encrypt_des.c
@@ -0,0 +1,703 @@
1/*
2 * FreeSec: libcrypt for NetBSD
3 *
4 * Copyright (c) 1994 David Burren
5 * All rights reserved.
6 *
7 * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
8 * this file should now *only* export crypt(), in order to make
9 * binaries of libcrypt exportable from the USA
10 *
11 * Adapted for FreeBSD-4.0 by Mark R V Murray
12 * this file should now *only* export crypt_des(), in order to make
13 * a module that can be optionally included in libcrypt.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of the author nor the names of other contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * This is an original implementation of the DES and the crypt(3) interfaces
40 * by David Burren <davidb@werj.com.au>.
41 *
42 * An excellent reference on the underlying algorithm (and related
43 * algorithms) is:
44 *
45 * B. Schneier, Applied Cryptography: protocols, algorithms,
46 * and source code in C, John Wiley & Sons, 1994.
47 *
48 * Note that in that book's description of DES the lookups for the initial,
49 * pbox, and final permutations are inverted (this has been brought to the
50 * attention of the author). A list of errata for this book has been
51 * posted to the sci.crypt newsgroup by the author and is available for FTP.
52 *
53 * ARCHITECTURE ASSUMPTIONS:
54 * It is assumed that the 8-byte arrays passed by reference can be
55 * addressed as arrays of uint32_t's (ie. the CPU is not picky about
56 * alignment).
57 */
58
59/* A pile of data */
60static const uint8_t IP[64] = {
61 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
63 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
64 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
65};
66
67static const uint8_t key_perm[56] = {
68 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
69 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
70 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
71 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
72};
73
74static const uint8_t key_shifts[16] = {
75 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
76};
77
78static const uint8_t comp_perm[48] = {
79 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
80 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
81 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
82 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
83};
84
85/*
86 * No E box is used, as it's replaced by some ANDs, shifts, and ORs.
87 */
88
89static const uint8_t sbox[8][64] = {
90 {
91 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
92 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
93 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
94 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
95 },
96 {
97 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
98 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
99 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
100 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
101 },
102 {
103 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
104 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
105 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
106 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
107 },
108 {
109 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
110 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
111 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
112 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
113 },
114 {
115 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
116 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
117 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
118 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
119 },
120 {
121 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
122 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
123 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
124 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
125 },
126 {
127 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
128 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
129 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
130 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
131 },
132 {
133 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
134 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
135 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
136 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
137 }
138};
139
140static const uint8_t pbox[32] = {
141 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
142 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
143};
144
145static const uint32_t bits32[32] =
146{
147 0x80000000, 0x40000000, 0x20000000, 0x10000000,
148 0x08000000, 0x04000000, 0x02000000, 0x01000000,
149 0x00800000, 0x00400000, 0x00200000, 0x00100000,
150 0x00080000, 0x00040000, 0x00020000, 0x00010000,
151 0x00008000, 0x00004000, 0x00002000, 0x00001000,
152 0x00000800, 0x00000400, 0x00000200, 0x00000100,
153 0x00000080, 0x00000040, 0x00000020, 0x00000010,
154 0x00000008, 0x00000004, 0x00000002, 0x00000001
155};
156
157static const uint8_t bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
158
159
160static int
161ascii_to_bin(char ch)
162{
163 if (ch > 'z')
164 return 0;
165 if (ch >= 'a')
166 return (ch - 'a' + 38);
167 if (ch > 'Z')
168 return 0;
169 if (ch >= 'A')
170 return (ch - 'A' + 12);
171 if (ch > '9')
172 return 0;
173 if (ch >= '.')
174 return (ch - '.');
175 return 0;
176}
177
178
179/* Static stuff that stays resident and doesn't change after
180 * being initialized, and therefore doesn't need to be made
181 * reentrant. */
182struct const_des_ctx {
183 uint8_t init_perm[64], final_perm[64]; /* referenced 2 times each */
184 uint8_t m_sbox[4][4096]; /* 5 times */
185};
186#define C (*cctx)
187#define init_perm (C.init_perm )
188#define final_perm (C.final_perm)
189#define m_sbox (C.m_sbox )
190
191static struct const_des_ctx*
192const_des_init(void)
193{
194 int i, j, b;
195 uint8_t u_sbox[8][64];
196 struct const_des_ctx *cctx;
197
198 cctx = xmalloc(sizeof(*cctx));
199
200 /*
201 * Invert the S-boxes, reordering the input bits.
202 */
203 for (i = 0; i < 8; i++) {
204 for (j = 0; j < 64; j++) {
205 b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
206 u_sbox[i][j] = sbox[i][b];
207 }
208 }
209
210 /*
211 * Convert the inverted S-boxes into 4 arrays of 8 bits.
212 * Each will handle 12 bits of the S-box input.
213 */
214 for (b = 0; b < 4; b++)
215 for (i = 0; i < 64; i++)
216 for (j = 0; j < 64; j++)
217 m_sbox[b][(i << 6) | j] =
218 (uint8_t)((u_sbox[(b << 1)][i] << 4) |
219 u_sbox[(b << 1) + 1][j]);
220
221 /*
222 * Set up the initial & final permutations into a useful form.
223 */
224 for (i = 0; i < 64; i++) {
225 final_perm[i] = IP[i] - 1;
226 init_perm[final_perm[i]] = (uint8_t)i;
227 }
228
229 return cctx;
230}
231
232
233struct des_ctx {
234 const struct const_des_ctx *const_ctx;
235 uint32_t saltbits; /* referenced 5 times */
236 uint32_t old_salt; /* 3 times */
237 uint32_t old_rawkey0, old_rawkey1; /* 3 times each */
238 uint8_t un_pbox[32]; /* 2 times */
239 uint8_t inv_comp_perm[56]; /* 3 times */
240 uint8_t inv_key_perm[64]; /* 3 times */
241 uint32_t en_keysl[16], en_keysr[16]; /* 2 times each */
242 uint32_t de_keysl[16], de_keysr[16]; /* 2 times each */
243 uint32_t ip_maskl[8][256], ip_maskr[8][256]; /* 9 times each */
244 uint32_t fp_maskl[8][256], fp_maskr[8][256]; /* 9 times each */
245 uint32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; /* 9 times */
246 uint32_t comp_maskl[8][128], comp_maskr[8][128]; /* 9 times each */
247 uint32_t psbox[4][256]; /* 5 times */
248};
249#define D (*ctx)
250#define const_ctx (D.const_ctx )
251#define saltbits (D.saltbits )
252#define old_salt (D.old_salt )
253#define old_rawkey0 (D.old_rawkey0 )
254#define old_rawkey1 (D.old_rawkey1 )
255#define un_pbox (D.un_pbox )
256#define inv_comp_perm (D.inv_comp_perm )
257#define inv_key_perm (D.inv_key_perm )
258#define en_keysl (D.en_keysl )
259#define en_keysr (D.en_keysr )
260#define de_keysl (D.de_keysl )
261#define de_keysr (D.de_keysr )
262#define ip_maskl (D.ip_maskl )
263#define ip_maskr (D.ip_maskr )
264#define fp_maskl (D.fp_maskl )
265#define fp_maskr (D.fp_maskr )
266#define key_perm_maskl (D.key_perm_maskl )
267#define key_perm_maskr (D.key_perm_maskr )
268#define comp_maskl (D.comp_maskl )
269#define comp_maskr (D.comp_maskr )
270#define psbox (D.psbox )
271
272static struct des_ctx*
273des_init(struct des_ctx *ctx, const struct const_des_ctx *cctx)
274{
275 int i, j, b, k, inbit, obit;
276 uint32_t *p, *il, *ir, *fl, *fr;
277 const uint32_t *bits28, *bits24;
278
279 if (!ctx)
280 ctx = xmalloc(sizeof(*ctx));
281 const_ctx = cctx;
282
283 old_rawkey0 = old_rawkey1 = 0L;
284 saltbits = 0L;
285 old_salt = 0L;
286 bits28 = bits32 + 4;
287 bits24 = bits28 + 4;
288
289 /*
290 * Initialise the inverted key permutation.
291 */
292 for (i = 0; i < 64; i++) {
293 inv_key_perm[i] = 255;
294 }
295
296 /*
297 * Invert the key permutation and initialise the inverted key
298 * compression permutation.
299 */
300 for (i = 0; i < 56; i++) {
301 inv_key_perm[key_perm[i] - 1] = (uint8_t)i;
302 inv_comp_perm[i] = 255;
303 }
304
305 /*
306 * Invert the key compression permutation.
307 */
308 for (i = 0; i < 48; i++) {
309 inv_comp_perm[comp_perm[i] - 1] = (uint8_t)i;
310 }
311
312 /*
313 * Set up the OR-mask arrays for the initial and final permutations,
314 * and for the key initial and compression permutations.
315 */
316 for (k = 0; k < 8; k++) {
317 for (i = 0; i < 256; i++) {
318 il = &ip_maskl[k][i];
319 ir = &ip_maskr[k][i];
320 fl = &fp_maskl[k][i];
321 fr = &fp_maskr[k][i];
322 *il = 0;
323 *ir = 0;
324 *fl = 0;
325 *fr = 0;
326 for (j = 0; j < 8; j++) {
327 inbit = 8 * k + j;
328 if (i & bits8[j]) {
329 obit = init_perm[inbit];
330 if (obit < 32)
331 *il |= bits32[obit];
332 else
333 *ir |= bits32[obit - 32];
334 obit = final_perm[inbit];
335 if (obit < 32)
336 *fl |= bits32[obit];
337 else
338 *fr |= bits32[obit - 32];
339 }
340 }
341 }
342 for (i = 0; i < 128; i++) {
343 il = &key_perm_maskl[k][i];
344 ir = &key_perm_maskr[k][i];
345 *il = 0;
346 *ir = 0;
347 for (j = 0; j < 7; j++) {
348 inbit = 8 * k + j;
349 if (i & bits8[j + 1]) {
350 obit = inv_key_perm[inbit];
351 if (obit == 255)
352 continue;
353 if (obit < 28)
354 *il |= bits28[obit];
355 else
356 *ir |= bits28[obit - 28];
357 }
358 }
359 il = &comp_maskl[k][i];
360 ir = &comp_maskr[k][i];
361 *il = 0;
362 *ir = 0;
363 for (j = 0; j < 7; j++) {
364 inbit = 7 * k + j;
365 if (i & bits8[j + 1]) {
366 obit = inv_comp_perm[inbit];
367 if (obit == 255)
368 continue;
369 if (obit < 24)
370 *il |= bits24[obit];
371 else
372 *ir |= bits24[obit - 24];
373 }
374 }
375 }
376 }
377
378 /*
379 * Invert the P-box permutation, and convert into OR-masks for
380 * handling the output of the S-box arrays setup above.
381 */
382 for (i = 0; i < 32; i++)
383 un_pbox[pbox[i] - 1] = (uint8_t)i;
384
385 for (b = 0; b < 4; b++) {
386 for (i = 0; i < 256; i++) {
387 p = &psbox[b][i];
388 *p = 0;
389 for (j = 0; j < 8; j++) {
390 if (i & bits8[j])
391 *p |= bits32[un_pbox[8 * b + j]];
392 }
393 }
394 }
395
396 return ctx;
397}
398
399
400static void
401setup_salt(struct des_ctx *ctx, uint32_t salt)
402{
403// const struct const_des_ctx *cctx = const_ctx;
404 uint32_t obit, saltbit;
405 int i;
406
407 if (salt == old_salt)
408 return;
409 old_salt = salt;
410
411 saltbits = 0L;
412 saltbit = 1;
413 obit = 0x800000;
414 for (i = 0; i < 24; i++) {
415 if (salt & saltbit)
416 saltbits |= obit;
417 saltbit <<= 1;
418 obit >>= 1;
419 }
420}
421
422static void
423des_setkey(struct des_ctx *ctx, const char *key)
424{
425// const struct const_des_ctx *cctx = const_ctx;
426 uint32_t k0, k1, rawkey0, rawkey1;
427 int shifts, round;
428
429 rawkey0 = ntohl(*(const uint32_t *) key);
430 rawkey1 = ntohl(*(const uint32_t *) (key + 4));
431
432 if ((rawkey0 | rawkey1)
433 && rawkey0 == old_rawkey0
434 && rawkey1 == old_rawkey1
435 ) {
436 /*
437 * Already setup for this key.
438 * This optimisation fails on a zero key (which is weak and
439 * has bad parity anyway) in order to simplify the starting
440 * conditions.
441 */
442 return;
443 }
444 old_rawkey0 = rawkey0;
445 old_rawkey1 = rawkey1;
446
447 /*
448 * Do key permutation and split into two 28-bit subkeys.
449 */
450 k0 = key_perm_maskl[0][rawkey0 >> 25]
451 | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
452 | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
453 | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
454 | key_perm_maskl[4][rawkey1 >> 25]
455 | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
456 | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
457 | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
458 k1 = key_perm_maskr[0][rawkey0 >> 25]
459 | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
460 | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
461 | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
462 | key_perm_maskr[4][rawkey1 >> 25]
463 | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
464 | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
465 | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
466 /*
467 * Rotate subkeys and do compression permutation.
468 */
469 shifts = 0;
470 for (round = 0; round < 16; round++) {
471 uint32_t t0, t1;
472
473 shifts += key_shifts[round];
474
475 t0 = (k0 << shifts) | (k0 >> (28 - shifts));
476 t1 = (k1 << shifts) | (k1 >> (28 - shifts));
477
478 de_keysl[15 - round] =
479 en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
480 | comp_maskl[1][(t0 >> 14) & 0x7f]
481 | comp_maskl[2][(t0 >> 7) & 0x7f]
482 | comp_maskl[3][t0 & 0x7f]
483 | comp_maskl[4][(t1 >> 21) & 0x7f]
484 | comp_maskl[5][(t1 >> 14) & 0x7f]
485 | comp_maskl[6][(t1 >> 7) & 0x7f]
486 | comp_maskl[7][t1 & 0x7f];
487
488 de_keysr[15 - round] =
489 en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
490 | comp_maskr[1][(t0 >> 14) & 0x7f]
491 | comp_maskr[2][(t0 >> 7) & 0x7f]
492 | comp_maskr[3][t0 & 0x7f]
493 | comp_maskr[4][(t1 >> 21) & 0x7f]
494 | comp_maskr[5][(t1 >> 14) & 0x7f]
495 | comp_maskr[6][(t1 >> 7) & 0x7f]
496 | comp_maskr[7][t1 & 0x7f];
497 }
498}
499
500
501static int
502do_des(struct des_ctx *ctx, uint32_t l_in, uint32_t r_in, uint32_t *l_out, uint32_t *r_out, int count)
503{
504 const struct const_des_ctx *cctx = const_ctx;
505 /*
506 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
507 */
508 uint32_t l, r, *kl, *kr, *kl1, *kr1;
509 uint32_t f = f; /* silence gcc */
510 uint32_t r48l, r48r;
511 int round;
512
513 /*
514 * Encrypting
515 */
516 kl1 = en_keysl;
517 kr1 = en_keysr;
518
519 /*
520 * Do initial permutation (IP).
521 */
522 l = ip_maskl[0][l_in >> 24]
523 | ip_maskl[1][(l_in >> 16) & 0xff]
524 | ip_maskl[2][(l_in >> 8) & 0xff]
525 | ip_maskl[3][l_in & 0xff]
526 | ip_maskl[4][r_in >> 24]
527 | ip_maskl[5][(r_in >> 16) & 0xff]
528 | ip_maskl[6][(r_in >> 8) & 0xff]
529 | ip_maskl[7][r_in & 0xff];
530 r = ip_maskr[0][l_in >> 24]
531 | ip_maskr[1][(l_in >> 16) & 0xff]
532 | ip_maskr[2][(l_in >> 8) & 0xff]
533 | ip_maskr[3][l_in & 0xff]
534 | ip_maskr[4][r_in >> 24]
535 | ip_maskr[5][(r_in >> 16) & 0xff]
536 | ip_maskr[6][(r_in >> 8) & 0xff]
537 | ip_maskr[7][r_in & 0xff];
538
539 while (count--) {
540 /*
541 * Do each round.
542 */
543 kl = kl1;
544 kr = kr1;
545 round = 16;
546 while (round--) {
547 /*
548 * Expand R to 48 bits (simulate the E-box).
549 */
550 r48l = ((r & 0x00000001) << 23)
551 | ((r & 0xf8000000) >> 9)
552 | ((r & 0x1f800000) >> 11)
553 | ((r & 0x01f80000) >> 13)
554 | ((r & 0x001f8000) >> 15);
555
556 r48r = ((r & 0x0001f800) << 7)
557 | ((r & 0x00001f80) << 5)
558 | ((r & 0x000001f8) << 3)
559 | ((r & 0x0000001f) << 1)
560 | ((r & 0x80000000) >> 31);
561 /*
562 * Do salting for crypt() and friends, and
563 * XOR with the permuted key.
564 */
565 f = (r48l ^ r48r) & saltbits;
566 r48l ^= f ^ *kl++;
567 r48r ^= f ^ *kr++;
568 /*
569 * Do sbox lookups (which shrink it back to 32 bits)
570 * and do the pbox permutation at the same time.
571 */
572 f = psbox[0][m_sbox[0][r48l >> 12]]
573 | psbox[1][m_sbox[1][r48l & 0xfff]]
574 | psbox[2][m_sbox[2][r48r >> 12]]
575 | psbox[3][m_sbox[3][r48r & 0xfff]];
576 /*
577 * Now that we've permuted things, complete f().
578 */
579 f ^= l;
580 l = r;
581 r = f;
582 }
583 r = l;
584 l = f;
585 }
586 /*
587 * Do final permutation (inverse of IP).
588 */
589 *l_out = fp_maskl[0][l >> 24]
590 | fp_maskl[1][(l >> 16) & 0xff]
591 | fp_maskl[2][(l >> 8) & 0xff]
592 | fp_maskl[3][l & 0xff]
593 | fp_maskl[4][r >> 24]
594 | fp_maskl[5][(r >> 16) & 0xff]
595 | fp_maskl[6][(r >> 8) & 0xff]
596 | fp_maskl[7][r & 0xff];
597 *r_out = fp_maskr[0][l >> 24]
598 | fp_maskr[1][(l >> 16) & 0xff]
599 | fp_maskr[2][(l >> 8) & 0xff]
600 | fp_maskr[3][l & 0xff]
601 | fp_maskr[4][r >> 24]
602 | fp_maskr[5][(r >> 16) & 0xff]
603 | fp_maskr[6][(r >> 8) & 0xff]
604 | fp_maskr[7][r & 0xff];
605 return 0;
606}
607
608#define DES_OUT_BUFSIZE 21
609
610static char *
611des_crypt(struct des_ctx *ctx, char output[21], const unsigned char *key, const unsigned char *setting)
612{
613 uint32_t salt, l, r0, r1, keybuf[2];
614 uint8_t *p, *q;
615
616 /*
617 * Copy the key, shifting each character up by one bit
618 * and padding with zeros.
619 */
620 q = (uint8_t *)keybuf;
621 while (q - (uint8_t *)keybuf - 8) {
622 *q++ = *key << 1;
623 if (*(q - 1))
624 key++;
625 }
626 des_setkey(ctx, (char *)keybuf);
627
628 /*
629 * setting - 2 bytes of salt
630 * key - up to 8 characters
631 */
632 salt = (ascii_to_bin(setting[1]) << 6)
633 | ascii_to_bin(setting[0]);
634
635 output[0] = setting[0];
636 /*
637 * If the encrypted password that the salt was extracted from
638 * is only 1 character long, the salt will be corrupted. We
639 * need to ensure that the output string doesn't have an extra
640 * NUL in it!
641 */
642 output[1] = setting[1] ? setting[1] : output[0];
643
644 p = (uint8_t *)output + 2;
645
646 setup_salt(ctx, salt);
647 /*
648 * Do it.
649 */
650 do_des(ctx, 0L, 0L, &r0, &r1, 25 /* count */);
651
652 /*
653 * Now encode the result...
654 */
655 l = (r0 >> 8);
656 *p++ = ascii64[(l >> 18) & 0x3f];
657 *p++ = ascii64[(l >> 12) & 0x3f];
658 *p++ = ascii64[(l >> 6) & 0x3f];
659 *p++ = ascii64[l & 0x3f];
660
661 l = (r0 << 16) | ((r1 >> 16) & 0xffff);
662 *p++ = ascii64[(l >> 18) & 0x3f];
663 *p++ = ascii64[(l >> 12) & 0x3f];
664 *p++ = ascii64[(l >> 6) & 0x3f];
665 *p++ = ascii64[l & 0x3f];
666
667 l = r1 << 2;
668 *p++ = ascii64[(l >> 12) & 0x3f];
669 *p++ = ascii64[(l >> 6) & 0x3f];
670 *p++ = ascii64[l & 0x3f];
671 *p = 0;
672
673 return output;
674}
675
676// des_setkey never fails
677
678#undef C
679#undef init_perm
680#undef final_perm
681#undef m_sbox
682#undef D
683#undef const_ctx
684#undef saltbits
685#undef old_salt
686#undef old_rawkey0
687#undef old_rawkey1
688#undef un_pbox
689#undef inv_comp_perm
690#undef inv_key_perm
691#undef en_keysl
692#undef en_keysr
693#undef de_keysl
694#undef de_keysr
695#undef ip_maskl
696#undef ip_maskr
697#undef fp_maskl
698#undef fp_maskr
699#undef key_perm_maskl
700#undef key_perm_maskr
701#undef comp_maskl
702#undef comp_maskr
703#undef psbox
diff --git a/libbb/pw_encrypt_md5.c b/libbb/pw_encrypt_md5.c
new file mode 100644
index 000000000..42eb13440
--- /dev/null
+++ b/libbb/pw_encrypt_md5.c
@@ -0,0 +1,656 @@
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 *
65 * Since SuSv3 does not require crypt_r, modified again August 7, 2002
66 * by Erik Andersen to remove reentrance stuff...
67 */
68
69/*
70 * Valid values are 1 (fastest/largest) to 3 (smallest/slowest).
71 */
72#define MD5_SIZE_OVER_SPEED 3
73
74/**********************************************************************/
75
76/* MD5 context. */
77struct MD5Context {
78 uint32_t state[4]; /* state (ABCD) */
79 uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
80 unsigned char buffer[64]; /* input buffer */
81};
82
83static void __md5_Init(struct MD5Context *);
84static void __md5_Update(struct MD5Context *, const unsigned char *, unsigned int);
85static void __md5_Pad(struct MD5Context *);
86static void __md5_Final(unsigned char [16], struct MD5Context *);
87static void __md5_Transform(uint32_t [4], const unsigned char [64]);
88
89
90#define MD5_MAGIC_STR "$1$"
91#define MD5_MAGIC_LEN (sizeof(MD5_MAGIC_STR) - 1)
92static const unsigned char __md5__magic[] = MD5_MAGIC_STR;
93
94
95#ifdef i386
96#define __md5_Encode memcpy
97#define __md5_Decode memcpy
98#else /* i386 */
99
100/*
101 * __md5_Encodes input (uint32_t) into output (unsigned char). Assumes len is
102 * a multiple of 4.
103 */
104
105static void
106__md5_Encode(unsigned char *output, uint32_t *input, unsigned int len)
107{
108 unsigned int i, j;
109
110 for (i = 0, j = 0; j < len; i++, j += 4) {
111 output[j] = input[i];
112 output[j+1] = (input[i] >> 8);
113 output[j+2] = (input[i] >> 16);
114 output[j+3] = (input[i] >> 24);
115 }
116}
117
118/*
119 * __md5_Decodes input (unsigned char) into output (uint32_t). Assumes len is
120 * a multiple of 4.
121 */
122
123static void
124__md5_Decode(uint32_t *output, const unsigned char *input, unsigned int len)
125{
126 unsigned int i, j;
127
128 for (i = 0, j = 0; j < len; i++, j += 4)
129 output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
130 (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
131}
132#endif /* i386 */
133
134/* F, G, H and I are basic MD5 functions. */
135#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
136#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
137#define H(x, y, z) ((x) ^ (y) ^ (z))
138#define I(x, y, z) ((y) ^ ((x) | ~(z)))
139
140/* ROTATE_LEFT rotates x left n bits. */
141#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
142
143/*
144 * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
145 * Rotation is separate from addition to prevent recomputation.
146 */
147#define FF(a, b, c, d, x, s, ac) { \
148 (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
149 (a) = ROTATE_LEFT((a), (s)); \
150 (a) += (b); \
151 }
152#define GG(a, b, c, d, x, s, ac) { \
153 (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
154 (a) = ROTATE_LEFT((a), (s)); \
155 (a) += (b); \
156 }
157#define HH(a, b, c, d, x, s, ac) { \
158 (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
159 (a) = ROTATE_LEFT((a), (s)); \
160 (a) += (b); \
161 }
162#define II(a, b, c, d, x, s, ac) { \
163 (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
164 (a) = ROTATE_LEFT((a), (s)); \
165 (a) += (b); \
166 }
167
168/* MD5 initialization. Begins an MD5 operation, writing a new context. */
169
170static void __md5_Init(struct MD5Context *context)
171{
172 context->count[0] = context->count[1] = 0;
173
174 /* Load magic initialization constants. */
175 context->state[0] = 0x67452301;
176 context->state[1] = 0xefcdab89;
177 context->state[2] = 0x98badcfe;
178 context->state[3] = 0x10325476;
179}
180
181/*
182 * MD5 block update operation. Continues an MD5 message-digest
183 * operation, processing another message block, and updating the
184 * context.
185 */
186
187static void __md5_Update(struct MD5Context *context, const unsigned char *input, unsigned int inputLen)
188{
189 unsigned int i, idx, partLen;
190
191 /* Compute number of bytes mod 64 */
192 idx = (context->count[0] >> 3) & 0x3F;
193
194 /* Update number of bits */
195 context->count[0] += (inputLen << 3);
196 if (context->count[0] < (inputLen << 3))
197 context->count[1]++;
198 context->count[1] += (inputLen >> 29);
199
200 partLen = 64 - idx;
201
202 /* Transform as many times as possible. */
203 if (inputLen >= partLen) {
204 memcpy(&context->buffer[idx], input, partLen);
205 __md5_Transform(context->state, context->buffer);
206
207 for (i = partLen; i + 63 < inputLen; i += 64)
208 __md5_Transform(context->state, &input[i]);
209
210 idx = 0;
211 } else
212 i = 0;
213
214 /* Buffer remaining input */
215 memcpy(&context->buffer[idx], &input[i], inputLen - i);
216}
217
218/*
219 * MD5 padding. Adds padding followed by original length.
220 */
221
222static void __md5_Pad(struct MD5Context *context)
223{
224 unsigned char bits[8];
225 unsigned int idx, padLen;
226 unsigned char PADDING[64];
227
228 memset(PADDING, 0, sizeof(PADDING));
229 PADDING[0] = 0x80;
230
231 /* Save number of bits */
232 __md5_Encode(bits, context->count, 8);
233
234 /* Pad out to 56 mod 64. */
235 idx = (context->count[0] >> 3) & 0x3f;
236 padLen = (idx < 56) ? (56 - idx) : (120 - idx);
237 __md5_Update(context, PADDING, padLen);
238
239 /* Append length (before padding) */
240 __md5_Update(context, bits, 8);
241}
242
243/*
244 * MD5 finalization. Ends an MD5 message-digest operation, writing the
245 * the message digest and zeroizing the context.
246 */
247
248static void __md5_Final(unsigned char digest[16], struct MD5Context *context)
249{
250 /* Do padding. */
251 __md5_Pad(context);
252
253 /* Store state in digest */
254 __md5_Encode(digest, context->state, 16);
255
256 /* Zeroize sensitive information. */
257 memset(context, 0, sizeof(*context));
258}
259
260/* MD5 basic transformation. Transforms state based on block. */
261
262static void __md5_Transform(uint32_t state[4], const unsigned char block[64])
263{
264 uint32_t a, b, c, d, x[16];
265#if MD5_SIZE_OVER_SPEED > 1
266 uint32_t temp;
267 const unsigned char *ps;
268
269 static const unsigned char S[] = {
270 7, 12, 17, 22,
271 5, 9, 14, 20,
272 4, 11, 16, 23,
273 6, 10, 15, 21
274 };
275#endif /* MD5_SIZE_OVER_SPEED > 1 */
276
277#if MD5_SIZE_OVER_SPEED > 0
278 const uint32_t *pc;
279 const unsigned char *pp;
280 int i;
281
282 static const uint32_t C[] = {
283 /* round 1 */
284 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
285 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
286 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
287 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
288 /* round 2 */
289 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
290 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
291 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
292 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
293 /* round 3 */
294 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
295 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
296 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
297 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
298 /* round 4 */
299 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
300 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
301 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
302 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
303 };
304
305 static const unsigned char P[] = {
306 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
307 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
308 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
309 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */
310 };
311
312#endif /* MD5_SIZE_OVER_SPEED > 0 */
313
314 __md5_Decode(x, block, 64);
315
316 a = state[0]; b = state[1]; c = state[2]; d = state[3];
317
318#if MD5_SIZE_OVER_SPEED > 2
319 pc = C; pp = P; ps = S - 4;
320
321 for (i = 0; i < 64; i++) {
322 if ((i & 0x0f) == 0) ps += 4;
323 temp = a;
324 switch (i>>4) {
325 case 0:
326 temp += F(b, c, d);
327 break;
328 case 1:
329 temp += G(b, c, d);
330 break;
331 case 2:
332 temp += H(b, c, d);
333 break;
334 case 3:
335 temp += I(b, c, d);
336 break;
337 }
338 temp += x[*pp++] + *pc++;
339 temp = ROTATE_LEFT(temp, ps[i & 3]);
340 temp += b;
341 a = d; d = c; c = b; b = temp;
342 }
343#elif MD5_SIZE_OVER_SPEED > 1
344 pc = C; pp = P; ps = S;
345
346 /* Round 1 */
347 for (i = 0; i < 16; i++) {
348 FF(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
349 temp = d; d = c; c = b; b = a; a = temp;
350 }
351
352 /* Round 2 */
353 ps += 4;
354 for (; i < 32; i++) {
355 GG(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
356 temp = d; d = c; c = b; b = a; a = temp;
357 }
358 /* Round 3 */
359 ps += 4;
360 for (; i < 48; i++) {
361 HH(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
362 temp = d; d = c; c = b; b = a; a = temp;
363 }
364
365 /* Round 4 */
366 ps += 4;
367 for (; i < 64; i++) {
368 II(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
369 temp = d; d = c; c = b; b = a; a = temp;
370 }
371#elif MD5_SIZE_OVER_SPEED > 0
372 pc = C; pp = P;
373
374 /* Round 1 */
375 for (i = 0; i < 4; i++) {
376 FF(a, b, c, d, x[*pp], 7, *pc); pp++; pc++;
377 FF(d, a, b, c, x[*pp], 12, *pc); pp++; pc++;
378 FF(c, d, a, b, x[*pp], 17, *pc); pp++; pc++;
379 FF(b, c, d, a, x[*pp], 22, *pc); pp++; pc++;
380 }
381
382 /* Round 2 */
383 for (i = 0; i < 4; i++) {
384 GG(a, b, c, d, x[*pp], 5, *pc); pp++; pc++;
385 GG(d, a, b, c, x[*pp], 9, *pc); pp++; pc++;
386 GG(c, d, a, b, x[*pp], 14, *pc); pp++; pc++;
387 GG(b, c, d, a, x[*pp], 20, *pc); pp++; pc++;
388 }
389 /* Round 3 */
390 for (i = 0; i < 4; i++) {
391 HH(a, b, c, d, x[*pp], 4, *pc); pp++; pc++;
392 HH(d, a, b, c, x[*pp], 11, *pc); pp++; pc++;
393 HH(c, d, a, b, x[*pp], 16, *pc); pp++; pc++;
394 HH(b, c, d, a, x[*pp], 23, *pc); pp++; pc++;
395 }
396
397 /* Round 4 */
398 for (i = 0; i < 4; i++) {
399 II(a, b, c, d, x[*pp], 6, *pc); pp++; pc++;
400 II(d, a, b, c, x[*pp], 10, *pc); pp++; pc++;
401 II(c, d, a, b, x[*pp], 15, *pc); pp++; pc++;
402 II(b, c, d, a, x[*pp], 21, *pc); pp++; pc++;
403 }
404#else
405 /* Round 1 */
406#define S11 7
407#define S12 12
408#define S13 17
409#define S14 22
410 FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
411 FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
412 FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
413 FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
414 FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
415 FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
416 FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
417 FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
418 FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
419 FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
420 FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
421 FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
422 FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
423 FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
424 FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
425 FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
426
427 /* Round 2 */
428#define S21 5
429#define S22 9
430#define S23 14
431#define S24 20
432 GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
433 GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
434 GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
435 GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
436 GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
437 GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
438 GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
439 GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
440 GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
441 GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
442 GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
443 GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
444 GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
445 GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
446 GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
447 GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
448
449 /* Round 3 */
450#define S31 4
451#define S32 11
452#define S33 16
453#define S34 23
454 HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
455 HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
456 HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
457 HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
458 HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
459 HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
460 HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
461 HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
462 HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
463 HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
464 HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
465 HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
466 HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
467 HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
468 HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
469 HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
470
471 /* Round 4 */
472#define S41 6
473#define S42 10
474#define S43 15
475#define S44 21
476 II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
477 II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
478 II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
479 II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
480 II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
481 II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
482 II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
483 II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
484 II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
485 II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
486 II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
487 II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
488 II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
489 II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
490 II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
491 II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
492#endif
493
494 state[0] += a;
495 state[1] += b;
496 state[2] += c;
497 state[3] += d;
498
499 /* Zeroize sensitive information. */
500 memset(x, 0, sizeof(x));
501}
502
503
504static void
505__md5_to64(char *s, unsigned long v, int n)
506{
507 while (--n >= 0) {
508 *s++ = ascii64[v & 0x3f];
509 v >>= 6;
510 }
511}
512
513/*
514 * UNIX password
515 *
516 * Use MD5 for what it is best at...
517 */
518#define MD5_OUT_BUFSIZE 120
519
520static char *
521md5_crypt(char passwd[120], const unsigned char *pw, const unsigned char *salt)
522{
523 const unsigned char *sp, *ep;
524 char *p;
525 unsigned char final[17]; /* final[16] exists only to aid in looping */
526 int sl, pl, i, pw_len;
527 struct MD5Context ctx, ctx1;
528 unsigned long l;
529
530 /* Refine the Salt first */
531 sp = salt;
532
533// always true for bbox
534// /* If it starts with the magic string, then skip that */
535// if (!strncmp(sp, __md5__magic, MD5_MAGIC_LEN))
536 sp += MD5_MAGIC_LEN;
537
538 /* It stops at the first '$', max 8 chars */
539 for (ep = sp; *ep && *ep != '$' && ep < (sp+8); ep++)
540 continue;
541
542 /* get the length of the true salt */
543 sl = ep - sp;
544
545 __md5_Init(&ctx);
546
547 /* The password first, since that is what is most unknown */
548 pw_len = strlen((char*)pw);
549 __md5_Update(&ctx, pw, pw_len);
550
551 /* Then our magic string */
552 __md5_Update(&ctx, __md5__magic, MD5_MAGIC_LEN);
553
554 /* Then the raw salt */
555 __md5_Update(&ctx, sp, sl);
556
557 /* Then just as many characters of the MD5(pw, salt, pw) */
558 __md5_Init(&ctx1);
559 __md5_Update(&ctx1, pw, pw_len);
560 __md5_Update(&ctx1, sp, sl);
561 __md5_Update(&ctx1, pw, pw_len);
562 __md5_Final(final, &ctx1);
563 for (pl = pw_len; pl > 0; pl -= 16)
564 __md5_Update(&ctx, final, pl > 16 ? 16 : pl);
565
566 /* Don't leave anything around in vm they could use. */
567//TODO: the above comment seems to be wrong. final is used later.
568 memset(final, 0, sizeof(final));
569
570 /* Then something really weird... */
571 for (i = pw_len; i; i >>= 1) {
572 __md5_Update(&ctx, ((i & 1) ? final : (const unsigned char *) pw), 1);
573 }
574
575 /* Now make the output string */
576 passwd[0] = '$';
577 passwd[1] = '1';
578 passwd[2] = '$';
579 strncpy(passwd + 3, (char*)sp, sl);
580 passwd[sl + 3] = '$';
581 passwd[sl + 4] = '\0';
582
583 __md5_Final(final, &ctx);
584
585 /*
586 * and now, just to make sure things don't run too fast
587 * On a 60 Mhz Pentium this takes 34 msec, so you would
588 * need 30 seconds to build a 1000 entry dictionary...
589 */
590 for (i = 0; i < 1000; i++) {
591 __md5_Init(&ctx1);
592 if (i & 1)
593 __md5_Update(&ctx1, pw, pw_len);
594 else
595 __md5_Update(&ctx1, final, 16);
596
597 if (i % 3)
598 __md5_Update(&ctx1, sp, sl);
599
600 if (i % 7)
601 __md5_Update(&ctx1, pw, pw_len);
602
603 if (i & 1)
604 __md5_Update(&ctx1, final, 16);
605 else
606 __md5_Update(&ctx1, pw, pw_len);
607 __md5_Final(final, &ctx1);
608 }
609
610 p = passwd + sl + 4; /*strlen(passwd);*/
611
612 final[16] = final[5];
613 for (i = 0; i < 5; i++) {
614 l = (final[i] << 16) | (final[i+6] << 8) | final[i+12];
615 __md5_to64(p, l, 4); p += 4;
616 }
617 l = final[11];
618 __md5_to64(p, l, 2); p += 2;
619 *p = '\0';
620
621 /* Don't leave anything around in vm they could use. */
622 memset(final, 0, sizeof(final));
623
624 return passwd;
625}
626
627#undef MD5_SIZE_OVER_SPEED
628#undef MD5_MAGIC_STR
629#undef MD5_MAGIC_LEN
630#undef __md5_Encode
631#undef __md5_Decode
632#undef F
633#undef G
634#undef H
635#undef I
636#undef ROTATE_LEFT
637#undef FF
638#undef GG
639#undef HH
640#undef II
641#undef S11
642#undef S12
643#undef S13
644#undef S14
645#undef S21
646#undef S22
647#undef S23
648#undef S24
649#undef S31
650#undef S32
651#undef S33
652#undef S34
653#undef S41
654#undef S42
655#undef S43
656#undef S44
diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c
index 5dc7a9bf0..230ab0fc9 100644
--- a/loginutils/chpasswd.c
+++ b/loginutils/chpasswd.c
@@ -47,7 +47,7 @@ int chpasswd_main(int argc ATTRIBUTE_UNUSED, char **argv)
47 strcpy(salt, "$1$"); 47 strcpy(salt, "$1$");
48 rnd = crypt_make_salt(salt + 3, 4, rnd); 48 rnd = crypt_make_salt(salt + 3, 4, rnd);
49 } 49 }
50 pass = pw_encrypt(pass, salt); 50 pass = pw_encrypt(pass, salt, 0);
51 } 51 }
52 52
53 /* This is rather complex: if user is not found in /etc/shadow, 53 /* This is rather complex: if user is not found in /etc/shadow,
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c
index 68f5e8074..1acbc6db0 100644
--- a/loginutils/cryptpw.c
+++ b/loginutils/cryptpw.c
@@ -7,6 +7,30 @@
7 7
8#include "libbb.h" 8#include "libbb.h"
9 9
10#define TESTING 0
11
12/*
13set TESTING to 1 and pipe some file through this script
14if you played with bbox's crypt implementation.
15
16while read line; do
17 n=`./busybox cryptpw -a des -- "$line"`
18 o=`./busybox_old cryptpw -a des -- "$line"`
19 test "$n" != "$o" && {
20 echo n="$n"
21 echo o="$o"
22 exit
23 }
24 n=`./busybox cryptpw -- "$line"`
25 o=`./busybox_old cryptpw -- "$line"`
26 test "$n" != "$o" && {
27 echo n="$n"
28 echo o="$o"
29 exit
30 }
31done
32 */
33
10int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 34int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
11int cryptpw_main(int argc ATTRIBUTE_UNUSED, char **argv) 35int cryptpw_main(int argc ATTRIBUTE_UNUSED, char **argv)
12{ 36{
@@ -18,11 +42,17 @@ int cryptpw_main(int argc ATTRIBUTE_UNUSED, char **argv)
18 //((uint32_t*)&salt)[0] = '$' + '1'*0x100 + '$'*0x10000; 42 //((uint32_t*)&salt)[0] = '$' + '1'*0x100 + '$'*0x10000;
19 /* Hope one day gcc will do it itself (inlining strcpy) */ 43 /* Hope one day gcc will do it itself (inlining strcpy) */
20 crypt_make_salt(salt + 3, 4, 0); /* md5 */ 44 crypt_make_salt(salt + 3, 4, 0); /* md5 */
45#if TESTING
46 strcpy(salt + 3, "ajg./bcf");
47#endif
21 } else { 48 } else {
22 crypt_make_salt(salt, 1, 0); /* des */ 49 crypt_make_salt(salt, 1, 0); /* des */
50#if TESTING
51 strcpy(salt, "a.");
52#endif
23 } 53 }
24 54
25 puts(pw_encrypt(argv[optind] ? argv[optind] : xmalloc_fgetline(stdin), salt)); 55 puts(pw_encrypt(argv[optind] ? argv[optind] : xmalloc_fgetline(stdin), salt, 1));
26 56
27 return 0; 57 return 0;
28} 58}
diff --git a/loginutils/passwd.c b/loginutils/passwd.c
index 3353db1fa..fad226c00 100644
--- a/loginutils/passwd.c
+++ b/loginutils/passwd.c
@@ -24,7 +24,7 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo)
24 orig = bb_askpass(0, "Old password:"); /* returns ptr to static */ 24 orig = bb_askpass(0, "Old password:"); /* returns ptr to static */
25 if (!orig) 25 if (!orig)
26 goto err_ret; 26 goto err_ret;
27 cipher = pw_encrypt(orig, pw->pw_passwd); /* returns ptr to static */ 27 cipher = pw_encrypt(orig, pw->pw_passwd, 1); /* returns ptr to static */
28 if (strcmp(cipher, pw->pw_passwd) != 0) { 28 if (strcmp(cipher, pw->pw_passwd) != 0) {
29 syslog(LOG_WARNING, "incorrect password for '%s'", 29 syslog(LOG_WARNING, "incorrect password for '%s'",
30 pw->pw_name); 30 pw->pw_name);
@@ -56,7 +56,7 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo)
56 crypt_make_salt(salt + 3, 4, 0); 56 crypt_make_salt(salt + 3, 4, 0);
57 } 57 }
58 /* pw_encrypt returns ptr to static */ 58 /* pw_encrypt returns ptr to static */
59 ret = xstrdup(pw_encrypt(newp, salt)); 59 ret = xstrdup(pw_encrypt(newp, salt, 1));
60 /* whee, success! */ 60 /* whee, success! */
61 61
62 err_ret: 62 err_ret:
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c
index 17bb15efa..f52ce8a95 100644
--- a/loginutils/sulogin.c
+++ b/loginutils/sulogin.c
@@ -81,7 +81,7 @@ int sulogin_main(int argc ATTRIBUTE_UNUSED, char **argv)
81 bb_info_msg("Normal startup"); 81 bb_info_msg("Normal startup");
82 return 0; 82 return 0;
83 } 83 }
84 if (strcmp(pw_encrypt(cp, pwd->pw_passwd), pwd->pw_passwd) == 0) { 84 if (strcmp(pw_encrypt(cp, pwd->pw_passwd, 1), pwd->pw_passwd) == 0) {
85 break; 85 break;
86 } 86 }
87 bb_do_delay(FAIL_DELAY); 87 bb_do_delay(FAIL_DELAY);
diff --git a/networking/httpd.c b/networking/httpd.c
index 4da7e5c65..78c6f4d1d 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -1733,7 +1733,7 @@ static int checkPerm(const char *path, const char *request)
1733 && pp[3] == '$' && pp[4] 1733 && pp[3] == '$' && pp[4]
1734 ) { 1734 ) {
1735 pp++; 1735 pp++;
1736 cipher = pw_encrypt(u+1, pp); 1736 cipher = pw_encrypt(u+1, pp, 1);
1737 if (strcmp(cipher, pp) == 0) 1737 if (strcmp(cipher, pp) == 0)
1738 goto set_remoteuser_var; /* Ok */ 1738 goto set_remoteuser_var; /* Ok */
1739 /* unauthorized */ 1739 /* unauthorized */
@@ -2352,7 +2352,7 @@ int httpd_main(int argc ATTRIBUTE_UNUSED, char **argv)
2352#endif 2352#endif
2353#if ENABLE_FEATURE_HTTPD_AUTH_MD5 2353#if ENABLE_FEATURE_HTTPD_AUTH_MD5
2354 if (opt & OPT_MD5) { 2354 if (opt & OPT_MD5) {
2355 puts(pw_encrypt(pass, "$1$")); 2355 puts(pw_encrypt(pass, "$1$", 1));
2356 return 0; 2356 return 0;
2357 } 2357 }
2358#endif 2358#endif