From 6b1e3d7e734f85a08c2e4414764f03a7f880b3e6 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Thu, 13 Nov 2008 12:23:46 +0000 Subject: libbb: remove glibc-style bloat from sha_crypt. -1130 bytes. cryptpw: add more difficult test vectors. --- libbb/pw_encrypt_sha.c | 41 +++++++++++++++++++++++++++++++++++++---- 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) if (strncmp(salt_data, str_rounds, 7) == 0) { /* 7 == strlen("rounds=") */ char *endp; - unsigned srounds = bb_strtou(salt_data + 7, &endp, 10); + cnt = bb_strtou(salt_data + 7, &endp, 10); if (*endp == '$') { salt_data = endp + 1; - rounds = srounds; + rounds = cnt; if (rounds < ROUNDS_MIN) rounds = ROUNDS_MIN; if (rounds > ROUNDS_MAX) rounds = ROUNDS_MAX; + /* add "rounds=NNNNN$" to result */ + resptr += sprintf(resptr, str_rounds, rounds); } } salt_len = strchrnul(salt_data, '$') - salt_data; @@ -73,8 +75,7 @@ sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) /* xstrdup assures suitable alignment; also we will use it as a scratch space later. */ salt_data = xstrndup(salt_data, salt_len); - if (rounds != ROUNDS_DEFAULT) /* add "rounds=NNNNN$" */ - resptr += sprintf(resptr, str_rounds, rounds); + /* add "salt$" to result */ strcpy(resptr, salt_data); resptr += salt_len; *resptr++ = '$'; @@ -195,8 +196,25 @@ do { \ resptr = to64(resptr, w, N); \ } while (0) if (is_sha512 == '5') { + unsigned i = 0; + unsigned j = 10; + unsigned k = 20; + /* strange swap of one byte (see below why) */ + unsigned char alt_result_31 = alt_result[31]; + alt_result[31] = alt_result[1]; + while (1) { + b64_from_24bit(alt_result[i], alt_result[j], alt_result[k], 4); + if (i == 9) + break; + i += 21; i = (((i >> 4) & 2) + i) & 0x1f; + j += 21; j = (((j >> 4) & 2) + j) & 0x1f; + k += 21; k = (((k >> 4) & 2) + k) & 0x1f; + } + b64_from_24bit(0, alt_result_31, alt_result[30], 3); + /* was: b64_from_24bit(alt_result[0], alt_result[10], alt_result[20], 4); b64_from_24bit(alt_result[21], alt_result[1], alt_result[11], 4); + ...............................^^^^^^^^^^^^^ why [1] and not [31]? b64_from_24bit(alt_result[12], alt_result[22], alt_result[2], 4); b64_from_24bit(alt_result[3], alt_result[13], alt_result[23], 4); b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4); @@ -206,7 +224,21 @@ do { \ b64_from_24bit(alt_result[18], alt_result[28], alt_result[8], 4); b64_from_24bit(alt_result[9], alt_result[19], alt_result[29], 4); b64_from_24bit(0, alt_result[31], alt_result[30], 3); + */ } else { + unsigned i = 0; + unsigned j = 21; + unsigned k = 42; + while (1) { + b64_from_24bit(alt_result[i], alt_result[j], alt_result[k], 4); + if (i == 62) + break; + i += 22; i = ((i >> 6) + i) & 0x3f; + j += 22; j = ((j >> 6) + j) & 0x3f; + k += 22; k = ((k >> 6) + k) & 0x3f; + } + b64_from_24bit(0, 0, alt_result[63], 2); + /* was: b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4); b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4); b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4); @@ -229,6 +261,7 @@ do { \ b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4); b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4); b64_from_24bit(0, 0, alt_result[63], 2); + */ } /* *resptr = '\0'; - xzalloc did it */ #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 int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int cryptpw_main(int argc UNUSED_PARAM, char **argv) { - char salt[sizeof("$N$") + 16]; + char salt[sizeof("$N$") + 16 + TESTING*100]; char *opt_a; int opts; @@ -54,7 +54,12 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv) salt[1] = '5' + (strcmp(opt_a, "sha512") == 0); crypt_make_salt(salt + 3, 16/2, 0); /* sha */ #if TESTING - strcpy(salt, "$6$em7yVj./Mv5n1V5X"); + strcpy(salt, "$5$rounds=5000$toolongsaltstring"); + // with "This is just a test" as password, should produce: + // "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8mGRcvxa5" + strcpy(salt, "$6$rounds=5000$toolongsaltstring"); + // with "This is just a test" as password, should produce: + // "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQzQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" #endif } else #endif -- cgit v1.2.3