diff options
-rw-r--r-- | libbb/pw_encrypt_sha.c | 41 | ||||
-rw-r--r-- | loginutils/cryptpw.c | 9 |
2 files changed, 44 insertions, 6 deletions
diff --git a/libbb/pw_encrypt_sha.c b/libbb/pw_encrypt_sha.c index 9acbabb3b..08b064750 100644 --- a/libbb/pw_encrypt_sha.c +++ b/libbb/pw_encrypt_sha.c | |||
@@ -57,14 +57,16 @@ sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) | |||
57 | if (strncmp(salt_data, str_rounds, 7) == 0) { | 57 | if (strncmp(salt_data, str_rounds, 7) == 0) { |
58 | /* 7 == strlen("rounds=") */ | 58 | /* 7 == strlen("rounds=") */ |
59 | char *endp; | 59 | char *endp; |
60 | unsigned srounds = bb_strtou(salt_data + 7, &endp, 10); | 60 | cnt = bb_strtou(salt_data + 7, &endp, 10); |
61 | if (*endp == '$') { | 61 | if (*endp == '$') { |
62 | salt_data = endp + 1; | 62 | salt_data = endp + 1; |
63 | rounds = srounds; | 63 | rounds = cnt; |
64 | if (rounds < ROUNDS_MIN) | 64 | if (rounds < ROUNDS_MIN) |
65 | rounds = ROUNDS_MIN; | 65 | rounds = ROUNDS_MIN; |
66 | if (rounds > ROUNDS_MAX) | 66 | if (rounds > ROUNDS_MAX) |
67 | rounds = ROUNDS_MAX; | 67 | rounds = ROUNDS_MAX; |
68 | /* add "rounds=NNNNN$" to result */ | ||
69 | resptr += sprintf(resptr, str_rounds, rounds); | ||
68 | } | 70 | } |
69 | } | 71 | } |
70 | salt_len = strchrnul(salt_data, '$') - salt_data; | 72 | salt_len = strchrnul(salt_data, '$') - salt_data; |
@@ -73,8 +75,7 @@ sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) | |||
73 | /* xstrdup assures suitable alignment; also we will use it | 75 | /* xstrdup assures suitable alignment; also we will use it |
74 | as a scratch space later. */ | 76 | as a scratch space later. */ |
75 | salt_data = xstrndup(salt_data, salt_len); | 77 | salt_data = xstrndup(salt_data, salt_len); |
76 | if (rounds != ROUNDS_DEFAULT) /* add "rounds=NNNNN$" */ | 78 | /* add "salt$" to result */ |
77 | resptr += sprintf(resptr, str_rounds, rounds); | ||
78 | strcpy(resptr, salt_data); | 79 | strcpy(resptr, salt_data); |
79 | resptr += salt_len; | 80 | resptr += salt_len; |
80 | *resptr++ = '$'; | 81 | *resptr++ = '$'; |
@@ -195,8 +196,25 @@ do { \ | |||
195 | resptr = to64(resptr, w, N); \ | 196 | resptr = to64(resptr, w, N); \ |
196 | } while (0) | 197 | } while (0) |
197 | if (is_sha512 == '5') { | 198 | if (is_sha512 == '5') { |
199 | unsigned i = 0; | ||
200 | unsigned j = 10; | ||
201 | unsigned k = 20; | ||
202 | /* strange swap of one byte (see below why) */ | ||
203 | unsigned char alt_result_31 = alt_result[31]; | ||
204 | alt_result[31] = alt_result[1]; | ||
205 | while (1) { | ||
206 | b64_from_24bit(alt_result[i], alt_result[j], alt_result[k], 4); | ||
207 | if (i == 9) | ||
208 | break; | ||
209 | i += 21; i = (((i >> 4) & 2) + i) & 0x1f; | ||
210 | j += 21; j = (((j >> 4) & 2) + j) & 0x1f; | ||
211 | k += 21; k = (((k >> 4) & 2) + k) & 0x1f; | ||
212 | } | ||
213 | b64_from_24bit(0, alt_result_31, alt_result[30], 3); | ||
214 | /* was: | ||
198 | b64_from_24bit(alt_result[0], alt_result[10], alt_result[20], 4); | 215 | b64_from_24bit(alt_result[0], alt_result[10], alt_result[20], 4); |
199 | b64_from_24bit(alt_result[21], alt_result[1], alt_result[11], 4); | 216 | b64_from_24bit(alt_result[21], alt_result[1], alt_result[11], 4); |
217 | ...............................^^^^^^^^^^^^^ why [1] and not [31]? | ||
200 | b64_from_24bit(alt_result[12], alt_result[22], alt_result[2], 4); | 218 | b64_from_24bit(alt_result[12], alt_result[22], alt_result[2], 4); |
201 | b64_from_24bit(alt_result[3], alt_result[13], alt_result[23], 4); | 219 | b64_from_24bit(alt_result[3], alt_result[13], alt_result[23], 4); |
202 | b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4); | 220 | b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4); |
@@ -206,7 +224,21 @@ do { \ | |||
206 | b64_from_24bit(alt_result[18], alt_result[28], alt_result[8], 4); | 224 | b64_from_24bit(alt_result[18], alt_result[28], alt_result[8], 4); |
207 | b64_from_24bit(alt_result[9], alt_result[19], alt_result[29], 4); | 225 | b64_from_24bit(alt_result[9], alt_result[19], alt_result[29], 4); |
208 | b64_from_24bit(0, alt_result[31], alt_result[30], 3); | 226 | b64_from_24bit(0, alt_result[31], alt_result[30], 3); |
227 | */ | ||
209 | } else { | 228 | } else { |
229 | unsigned i = 0; | ||
230 | unsigned j = 21; | ||
231 | unsigned k = 42; | ||
232 | while (1) { | ||
233 | b64_from_24bit(alt_result[i], alt_result[j], alt_result[k], 4); | ||
234 | if (i == 62) | ||
235 | break; | ||
236 | i += 22; i = ((i >> 6) + i) & 0x3f; | ||
237 | j += 22; j = ((j >> 6) + j) & 0x3f; | ||
238 | k += 22; k = ((k >> 6) + k) & 0x3f; | ||
239 | } | ||
240 | b64_from_24bit(0, 0, alt_result[63], 2); | ||
241 | /* was: | ||
210 | b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4); | 242 | b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4); |
211 | b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4); | 243 | b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4); |
212 | b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4); | 244 | b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4); |
@@ -229,6 +261,7 @@ do { \ | |||
229 | b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4); | 261 | b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4); |
230 | b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4); | 262 | b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4); |
231 | b64_from_24bit(0, 0, alt_result[63], 2); | 263 | b64_from_24bit(0, 0, alt_result[63], 2); |
264 | */ | ||
232 | } | 265 | } |
233 | /* *resptr = '\0'; - xzalloc did it */ | 266 | /* *resptr = '\0'; - xzalloc did it */ |
234 | #undef b64_from_24bit | 267 | #undef b64_from_24bit |
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c index d76deac20..0c1a9a0db 100644 --- a/loginutils/cryptpw.c +++ b/loginutils/cryptpw.c | |||
@@ -34,7 +34,7 @@ done | |||
34 | int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 34 | int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
35 | int cryptpw_main(int argc UNUSED_PARAM, char **argv) | 35 | int cryptpw_main(int argc UNUSED_PARAM, char **argv) |
36 | { | 36 | { |
37 | char salt[sizeof("$N$") + 16]; | 37 | char salt[sizeof("$N$") + 16 + TESTING*100]; |
38 | char *opt_a; | 38 | char *opt_a; |
39 | int opts; | 39 | int opts; |
40 | 40 | ||
@@ -54,7 +54,12 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv) | |||
54 | salt[1] = '5' + (strcmp(opt_a, "sha512") == 0); | 54 | salt[1] = '5' + (strcmp(opt_a, "sha512") == 0); |
55 | crypt_make_salt(salt + 3, 16/2, 0); /* sha */ | 55 | crypt_make_salt(salt + 3, 16/2, 0); /* sha */ |
56 | #if TESTING | 56 | #if TESTING |
57 | strcpy(salt, "$6$em7yVj./Mv5n1V5X"); | 57 | strcpy(salt, "$5$rounds=5000$toolongsaltstring"); |
58 | // with "This is just a test" as password, should produce: | ||
59 | // "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8mGRcvxa5" | ||
60 | strcpy(salt, "$6$rounds=5000$toolongsaltstring"); | ||
61 | // with "This is just a test" as password, should produce: | ||
62 | // "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQzQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" | ||
58 | #endif | 63 | #endif |
59 | } else | 64 | } else |
60 | #endif | 65 | #endif |