[git commit] cryptpw: fix detection of crypt algo from salt (was broken if default isn't DES)

Denys Vlasenko vda.linux at googlemail.com
Sat Jul 19 16:20:01 UTC 2025


commit: https://git.busybox.net/busybox/commit/?id=6979467a62c4bc58eeede0436d06c0cd57649705
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

The symptom is: "cryptpw ... implicit" testsuite tests were failing
if CONFIG_FEATURE_DEFAULT_PASSWD_ALGO is not "des".

function                                             old     new   delta
cryptpw_main                                         223     283     +60
pw_encrypt                                           974     975      +1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 61/0)               Total: 61 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 libbb/pw_encrypt.c   | 11 +++++------
 loginutils/cryptpw.c | 34 +++++++++++++++++++++++++++++-----
 2 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c
index 3b2fea00d..56191b00e 100644
--- a/libbb/pw_encrypt.c
+++ b/libbb/pw_encrypt.c
@@ -37,9 +37,8 @@ char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo)
 #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_YES
 		if ((algo[0]|0x20) == 'y') { /* yescrypt */
 			salt[1] = 'y';
-			len = 24 / 2;
+			len = 22 / 2;
 // The "j9T$" below is the default "yescrypt parameters" encoded by yescrypt_encode_params_r():
-//
 //shadow-4.17.4/src/passwd.c
 //	salt = crypt_make_salt(NULL, NULL);
 //shadow-4.17.4/lib/salt.c
@@ -105,13 +104,13 @@ static char *my_crypt(const char *key, const char *salt)
 	if (salt[0] == '$' && salt[1] && salt[2] == '$') {
 		if (salt[1] == '1')
 			return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt);
-#if ENABLE_USE_BB_CRYPT_YES
-		if (salt[1] == 'y')
-			return yes_crypt(key, salt);
-#endif
 #if ENABLE_USE_BB_CRYPT_SHA
 		if (salt[1] == '5' || salt[1] == '6')
 			return sha_crypt((char*)key, (char*)salt);
+#endif
+#if ENABLE_USE_BB_CRYPT_YES
+		if (salt[1] == 'y')
+			return yes_crypt(key, salt);
 #endif
 	}
 
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c
index c0f6280cd..666deff0b 100644
--- a/loginutils/cryptpw.c
+++ b/loginutils/cryptpw.c
@@ -99,7 +99,7 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv)
 	;
 #endif
 	fd = STDIN_FILENO;
-	opt_m = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO;
+	opt_m = NULL;
 	opt_S = NULL;
 	/* at most two non-option arguments; -P NUM */
 	getopt32long(argv, "^" "sP:+S:m:a:" "\0" "?2",
@@ -113,10 +113,34 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv)
 	if (argv[0] && !opt_S)
 		opt_S = argv[1];
 
-	salt_ptr = crypt_make_pw_salt(salt, opt_m);
-	if (opt_S)
-		/* put user's data after the "$N$" prefix */
-		safe_strncpy(salt_ptr, opt_S, sizeof(salt) - (sizeof("$N$")-1));
+	if (opt_S && !opt_S[0]) {
+		/* mkpasswd 5.6.2 compat: SALT of ""
+		 * is treated as not specified
+		 * (both forms: -S "" and argv[1] of "")
+		 */
+		opt_S = NULL;
+	}
+
+	if (opt_m) {
+		/* "cryptpw -m ALGO PASSWORD [SALT]" */
+		/* generate "$x$" algo prefix + random salt */
+		salt_ptr = crypt_make_pw_salt(salt, opt_m);
+		if (opt_S) {
+			/* "cryptpw -m ALGO PASSWORD SALT" */
+			/* put SALT data after the "$x$" prefix */
+			safe_strncpy(salt_ptr, opt_S, sizeof(salt) - (sizeof("$N$")-1));
+		}
+	} else {
+		if (!opt_S) {
+			/* "cryptpw PASSWORD" */
+			/* generate random salt with default algo */
+			crypt_make_pw_salt(salt, CONFIG_FEATURE_DEFAULT_PASSWD_ALGO);
+		} else {
+			/* "cryptpw PASSWORD '$x$SALT'" */
+			/* use given salt; algo will be detected by pw_encrypt() */
+			safe_strncpy(salt, opt_S, sizeof(salt));
+		}
+	}
 
 	xmove_fd(fd, STDIN_FILENO);
 


More information about the busybox-cvs mailing list