shadow/shadow-add-sm3-crypt-support.patch
yunjia_w ebbcf53efe update version to 4.13
Signed-off-by: yunjia_w <yunjia.wang@huawei.com>
2023-02-08 15:08:43 +08:00

783 lines
29 KiB
Diff

From d7fa75bbd22a08b4e0b8c7e3ccab588c87d23835 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 29 Dec 2021 16:05:56 +0800
Subject: [PATCH] shadow add sm3 crypt support
---
configure.ac | 9 ++++
etc/login.defs | 17 ++++++++
lib/encrypt.c | 3 ++
lib/getdef.c | 4 ++
libmisc/obscure.c | 3 ++
libmisc/salt.c | 106 +++++++++++++++++++++++++++++++++++++++++++---
src/chgpasswd.c | 48 +++++++++++++++------
src/chpasswd.c | 46 ++++++++++++++------
src/newusers.c | 61 +++++++++++++++++++-------
src/passwd.c | 7 ++-
10 files changed, 254 insertions(+), 50 deletions(-)
diff --git a/configure.ac b/configure.ac
index 924254a..dde1de8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -274,6 +274,9 @@ AC_ARG_WITH(libcrack,
AC_ARG_WITH(sha-crypt,
[AS_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])],
[with_sha_crypt=$withval], [with_sha_crypt=yes])
+AC_ARG_WITH(sm3-crypt,
+ [AC_HELP_STRING([--with-sm3-crypt], [allow the SM3 password encryption algorithms @<:@default=yes@:>@])],
+ [with_sm3_crypt=$withval], [with_sm3_crypt=yes])
AC_ARG_WITH(bcrypt,
[AS_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])],
[with_bcrypt=$withval], [with_bcrypt=no])
@@ -307,6 +310,11 @@ if test "$with_sha_crypt" = "yes"; then
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms])
fi
+AM_CONDITIONAL(USE_SM3_CRYPT, test "x$with_sm3_crypt" = "xyes")
+if test "$with_sm3_crypt" = "yes"; then
+ AC_DEFINE(USE_SM3_CRYPT, 1, [Define to allow the SM3 password encryption algorithms])
+fi
+
AM_CONDITIONAL(USE_BCRYPT, test "x$with_bcrypt" = "xyes")
if test "$with_bcrypt" = "yes"; then
AC_DEFINE(USE_BCRYPT, 1, [Define to allow the bcrypt password encryption algorithm])
@@ -752,6 +760,7 @@ echo " tcb support (incomplete): $with_tcb"
echo " shadow group support: $enable_shadowgrp"
echo " S/Key support: $with_skey"
echo " SHA passwords encryption: $with_sha_crypt"
+echo " SM3 passwords encryption: $with_sm3_crypt"
echo " bcrypt passwords encryption: $with_bcrypt"
echo " yescrypt passwords encryption: $with_yescrypt"
echo " nscd support: $with_nscd"
diff --git a/etc/login.defs b/etc/login.defs
index 114dbcd..fd310b7 100644
--- a/etc/login.defs
+++ b/etc/login.defs
@@ -353,6 +353,23 @@ CHFN_RESTRICT rwh
#SHA_CRYPT_MIN_ROUNDS 5000
#SHA_CRYPT_MAX_ROUNDS 5000
+#
+# Only works if ENCRYPT_METHOD is set to SM3.
+#
+# Define the number of SM3 rounds.
+# With a lot of rounds, it is more difficult to brute-force the password.
+# However, more CPU resources will be needed to authenticate users if
+# this value is increased.
+#
+# If not specified, the libc will choose the default number of rounds (5000),
+# which is orders of magnitude too low for modern hardware.
+# The values must be within the 1000-999999999 range.
+# If only one of the MIN or MAX values is set, then this value will be used.
+# If MIN > MAX, the highest value will be used.
+#
+#SM3_CRYPT_MAX_ROUNDS 5000
+#SM3_CRYPT_MIN_ROUNDS 5000
+
#
# Only works if ENCRYPT_METHOD is set to BCRYPT.
#
diff --git a/lib/encrypt.c b/lib/encrypt.c
index c84a255..11b301b 100644
--- a/lib/encrypt.c
+++ b/lib/encrypt.c
@@ -52,6 +52,9 @@
case '6':
method = "SHA512";
break;
+ case 's': // salt = $sm3$...
+ method = "SM3";
+ break;
case 'y':
method = "YESCRYPT";
break;
diff --git a/lib/getdef.c b/lib/getdef.c
index dcd1fe7..9a8089a 100644
--- a/lib/getdef.c
+++ b/lib/getdef.c
@@ -102,6 +102,10 @@ static struct itemdef def_table[] = {
{"SHA_CRYPT_MAX_ROUNDS", NULL},
{"SHA_CRYPT_MIN_ROUNDS", NULL},
#endif
+#ifdef USE_SM3_CRYPT
+ {"SM3_CRYPT_MAX_ROUNDS", NULL},
+ {"SM3_CRYPT_MIN_ROUNDS", NULL},
+#endif
#ifdef USE_BCRYPT
{"BCRYPT_MAX_ROUNDS", NULL},
{"BCRYPT_MIN_ROUNDS", NULL},
diff --git a/libmisc/obscure.c b/libmisc/obscure.c
index 3daaa95..644259d 100644
--- a/libmisc/obscure.c
+++ b/libmisc/obscure.c
@@ -246,6 +246,9 @@ static /*@observer@*//*@null@*/const char *obscure_msg (
|| (strcmp (result, "SHA256") == 0)
|| (strcmp (result, "SHA512") == 0)
#endif
+#ifdef USE_SM3_CRYPT
+ || (strcmp (result, "SM3") == 0)
+#endif
#ifdef USE_BCRYPT
|| (strcmp (result, "BCRYPT") == 0)
#endif
diff --git a/libmisc/salt.c b/libmisc/salt.c
index e5f633a..df4b328 100644
--- a/libmisc/salt.c
+++ b/libmisc/salt.c
@@ -63,6 +63,17 @@
#define SHA_ROUNDS_MAX 999999999
#endif
+#ifdef USE_SM3_CRYPT
+/* Fixed salt len for sm3 crypt. */
+#define SM3_CRYPT_SALT_SIZE 16
+/* Default number of rounds if not explicitly specified. */
+#define SM3_ROUNDS_DEFAULT 5000
+/* Minimum number of rounds. */
+#define SM3_ROUNDS_MIN 1000
+/* Maximum number of rounds. */
+#define SM3_ROUNDS_MAX 999999999
+#endif
+
#ifdef USE_YESCRYPT
/*
* Default number of base64 characters used for the salt.
@@ -95,13 +106,17 @@ static long read_random_bytes (void);
#if !USE_XCRYPT_GENSALT
static /*@observer@*/const char *gensalt (size_t salt_size);
#endif /* !USE_XCRYPT_GENSALT */
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT)
static long shadow_random (long min, long max);
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_SM3_CRYPT*/
#ifdef USE_SHA_CRYPT
static /*@observer@*/unsigned long SHA_get_salt_rounds (/*@null@*/const int *prefered_rounds);
static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds);
#endif /* USE_SHA_CRYPT */
+#ifdef USE_SM3_CRYPT
+static /*@observer@*/const unsigned long SM3_get_salt_rounds (/*@null@*/int *prefered_rounds);
+static /*@observer@*/void SM3_salt_rounds_to_buf (char *buf, unsigned long rounds);
+#endif
#ifdef USE_BCRYPT
static /*@observer@*/unsigned long BCRYPT_get_salt_rounds (/*@null@*/const int *prefered_rounds);
static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds);
@@ -195,7 +210,7 @@ end:
return randval;
}
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT)
/*
* Return a random number between min and max (both included).
*
@@ -217,7 +232,7 @@ static long shadow_random (long min, long max)
}
return ret;
}
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_SM3_CRYPT*/
#ifdef USE_SHA_CRYPT
/* Return the the rounds number for the SHA crypt methods. */
@@ -293,6 +308,80 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long round
}
#endif /* USE_SHA_CRYPT */
+#ifdef USE_SM3_CRYPT
+/* Return the the rounds number for the SM3 crypt methods. */
+static /*@observer@*/const unsigned long SM3_get_salt_rounds (/*@null@*/int *prefered_rounds)
+{
+ unsigned long rounds;
+
+ if (NULL == prefered_rounds) {
+ long min_rounds = getdef_long ("SM3_CRYPT_MIN_ROUNDS", -1);
+ long max_rounds = getdef_long ("SM3_CRYPT_MAX_ROUNDS", -1);
+
+ if ((-1 == min_rounds) && (-1 == max_rounds)) {
+ rounds = SM3_ROUNDS_DEFAULT;
+ }
+ else {
+ if (-1 == min_rounds) {
+ min_rounds = max_rounds;
+ }
+
+ if (-1 == max_rounds) {
+ max_rounds = min_rounds;
+ }
+
+ if (min_rounds > max_rounds) {
+ max_rounds = min_rounds;
+ }
+
+ rounds = (unsigned long) shadow_random (min_rounds, max_rounds);
+ }
+ } else if (0 == *prefered_rounds) {
+ rounds = SM3_ROUNDS_DEFAULT;
+ } else {
+ rounds = (unsigned long) *prefered_rounds;
+ }
+
+ /* Sanity checks. The libc should also check this, but this
+ * protects against a rounds_prefix overflow. */
+ if (rounds < SM3_ROUNDS_MIN) {
+ rounds = SM3_ROUNDS_MIN;
+ }
+
+ if (rounds > SM3_ROUNDS_MAX) {
+ rounds = SM3_ROUNDS_MAX;
+ }
+
+ return rounds;
+}
+
+/*
+ * Fill a salt prefix specifying the rounds number for the SM3 crypt methods
+ * to a buffer.
+ */
+static /*@observer@*/void SM3_salt_rounds_to_buf (char *buf, unsigned long rounds)
+{
+ const size_t buf_begin = strlen (buf);
+
+ /* Nothing to do here if SM3_ROUNDS_DEFAULT is used. */
+ if (rounds == SM3_ROUNDS_DEFAULT) {
+ return;
+ }
+
+ /*
+ * Check if the result buffer is long enough.
+ * We are going to write a maximum of 17 bytes,
+ * plus one byte for the terminator.
+ * rounds=XXXXXXXXX$
+ * 00000000011111111
+ * 12345678901234567
+ */
+ assert (GENSALT_SETTING_SIZE > buf_begin + 17);
+
+ (void) snprintf (buf + buf_begin, 18, "rounds=%lu$", rounds);
+}
+#endif /* USE_SM3_CRYPT */
+
#ifdef USE_BCRYPT
/* Return the the rounds number for the BCRYPT method. */
static /*@observer@*/unsigned long BCRYPT_get_salt_rounds (/*@null@*/const int *prefered_rounds)
@@ -463,7 +552,7 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
* which can both be set inside the login.defs file.
*
* If meth is specified, an additional parameter can be provided.
- * * For the SHA256 and SHA512 method, this specifies the number of rounds
+ * * For the SHA256 and SHA512 and SM3 method, this specifies the number of rounds
* (if not NULL).
* * For the YESCRYPT method, this specifies the cost factor (if not NULL).
*/
@@ -515,6 +604,13 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
rounds = SHA_get_salt_rounds ((int *) arg);
SHA_salt_rounds_to_buf (result, rounds);
#endif /* USE_SHA_CRYPT */
+#ifdef USE_SM3_CRYPT
+ } else if (0 == strcmp (method, "SM3")) {
+ strcpy(result, "$sm3$");
+ salt_len = SM3_CRYPT_SALT_SIZE;
+ rounds = SM3_get_salt_rounds ((int *) arg);
+ SM3_salt_rounds_to_buf (result, rounds);
+#endif /* USE_SM3_CRYPT */
} else if (0 != strcmp (method, "DES")) {
fprintf (log_get_logfd(),
_("Invalid ENCRYPT_METHOD value: '%s'.\n"
diff --git a/src/chgpasswd.c b/src/chgpasswd.c
index d17acb6..9b00520 100644
--- a/src/chgpasswd.c
+++ b/src/chgpasswd.c
@@ -39,15 +39,18 @@
const char *Prog;
static bool eflg = false;
static bool md5flg = false;
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
static bool sflg = false;
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/
static /*@null@*//*@observer@*/const char *crypt_method = NULL;
#define cflg (NULL != crypt_method)
#ifdef USE_SHA_CRYPT
static long sha_rounds = 5000;
#endif
+#ifdef USE_SM3_CRYPT
+static long sm3_rounds = 5000;
+#endif
#ifdef USE_BCRYPT
static long bcrypt_rounds = 13;
#endif
@@ -119,6 +122,9 @@ static /*@noreturn@*/void usage (int status)
#if defined(USE_YESCRYPT)
" YESCRYPT"
#endif
+#if defined(USE_SM3_CRYPT)
+ " SM3"
+ #endif
);
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
@@ -126,11 +132,11 @@ static /*@noreturn@*/void usage (int status)
" the MD5 algorithm\n"),
usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT, SM3\n"
" or YESCRYPT crypt algorithms\n"),
usageout);
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/
(void) fputs ("\n", usageout);
exit (status);
@@ -144,22 +150,22 @@ static /*@noreturn@*/void usage (int status)
static void process_flags (int argc, char **argv)
{
int c;
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
int bad_s;
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/
static struct option long_options[] = {
{"crypt-method", required_argument, NULL, 'c'},
{"encrypted", no_argument, NULL, 'e'},
{"help", no_argument, NULL, 'h'},
{"md5", no_argument, NULL, 'm'},
{"root", required_argument, NULL, 'R'},
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
{"sha-rounds", required_argument, NULL, 's'},
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv,
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
"c:ehmR:s:",
#else
"c:ehmR:",
@@ -180,7 +186,7 @@ static void process_flags (int argc, char **argv)
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
case 's':
sflg = true;
bad_s = 0;
@@ -202,6 +208,12 @@ static void process_flags (int argc, char **argv)
bad_s = 1;
}
#endif /* USE_YESCRYPT */
+#if defined(USE_SM3_CRYPT)
+ if (( (0 == strcmp (crypt_method, "SM3"))
+ && (0 == getlong(optarg, &sm3_rounds)))) {
+ bad_s = 1;
+ }
+#endif /* USE_SM3_CRYPT */
if (bad_s != 0) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -209,7 +221,7 @@ static void process_flags (int argc, char **argv)
usage (E_USAGE);
}
break;
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/
default:
usage (E_USAGE);
@@ -228,7 +240,7 @@ static void process_flags (int argc, char **argv)
*/
static void check_flags (void)
{
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
if (sflg && !cflg) {
fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"),
@@ -259,6 +271,9 @@ static void check_flags (void)
#ifdef USE_YESCRYPT
&& (0 != strcmp (crypt_method, "YESCRYPT"))
#endif /* USE_YESCRYPT */
+#ifdef USE_SM3_CRYPT
+ && (0 != strcmp (crypt_method, "SM3"))
+#endif /* USE_SM3_CRYPT */
) {
fprintf (stderr,
_("%s: unsupported crypt method: %s\n"),
@@ -483,7 +498,7 @@ int main (int argc, char **argv)
if (md5flg) {
crypt_method = "MD5";
}
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
if (sflg) {
#if defined(USE_SHA_CRYPT)
if ( (0 == strcmp (crypt_method, "SHA256"))
@@ -501,6 +516,11 @@ int main (int argc, char **argv)
arg = &yescrypt_cost;
}
#endif /* USE_YESCRYPT */
+#if defined(USE_SM3_CRYPT)
+ if (0 == strcmp (crypt_method, "SM3")) {
+ arg = &sm3_rounds;
+ }
+#endif /* USE_SM3_CRYPT */
}
#endif
salt = crypt_make_salt (crypt_method, arg);
diff --git a/src/chpasswd.c b/src/chpasswd.c
index 48d5178..9003c18 100644
--- a/src/chpasswd.c
+++ b/src/chpasswd.c
@@ -38,7 +38,7 @@
const char *Prog;
static bool eflg = false;
static bool md5flg = false;
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
static bool sflg = false;
#endif
@@ -47,6 +47,9 @@ static /*@null@*//*@observer@*/const char *crypt_method = NULL;
#ifdef USE_SHA_CRYPT
static long sha_rounds = 5000;
#endif
+#ifdef USE_SM3_CRYPT
+static long sm3_rounds = 5000;
+#endif
#ifdef USE_BCRYPT
static long bcrypt_rounds = 13;
#endif
@@ -113,6 +116,9 @@ static /*@noreturn@*/void usage (int status)
#endif
#if defined(USE_YESCRYPT)
" YESCRYPT"
+#endif
+#if defined(USE_SM3_CRYPT)
+ " SM3"
#endif
);
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
@@ -121,11 +127,11 @@ static /*@noreturn@*/void usage (int status)
" the MD5 algorithm\n"),
usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT, SM3\n"
" or YESCRYPT crypt algorithms\n"),
usageout);
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT */
(void) fputs ("\n", usageout);
exit (status);
@@ -139,23 +145,23 @@ static /*@noreturn@*/void usage (int status)
static void process_flags (int argc, char **argv)
{
int c;
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
int bad_s;
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT */
static struct option long_options[] = {
{"crypt-method", required_argument, NULL, 'c'},
{"encrypted", no_argument, NULL, 'e'},
{"help", no_argument, NULL, 'h'},
{"md5", no_argument, NULL, 'm'},
{"root", required_argument, NULL, 'R'},
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
{"sha-rounds", required_argument, NULL, 's'},
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT */
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv,
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
"c:ehmR:s:",
#else
"c:ehmR:",
@@ -176,7 +182,7 @@ static void process_flags (int argc, char **argv)
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
case 's':
sflg = true;
bad_s = 0;
@@ -198,14 +204,20 @@ static void process_flags (int argc, char **argv)
bad_s = 1;
}
#endif /* USE_YESCRYPT */
- if (bad_s != 0) {
+#if defined(USE_SM3_CRYPT)
+ if (( (0 == strcmp (crypt_method, "SM3"))
+ && (0 == getlong(optarg, &sm3_rounds)))) {
+ bad_s = 1;
+ }
+#endif /* USE_SM3_CRYPT */
+ if (bad_s != 0) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (E_USAGE);
}
break;
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/
default:
usage (E_USAGE);
@@ -224,7 +236,7 @@ static void process_flags (int argc, char **argv)
*/
static void check_flags (void)
{
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
if (sflg && !cflg) {
fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"),
@@ -249,6 +261,9 @@ static void check_flags (void)
&&(!IS_CRYPT_METHOD("SHA256"))
&&(!IS_CRYPT_METHOD("SHA512"))
#endif /* USE_SHA_CRYPT */
+#ifdef USE_SM3_CRYPT
+ && (0 != strcmp (crypt_method, "SM3"))
+#endif /* USE_SM3_CRYPT */
#ifdef USE_BCRYPT
&&(!IS_CRYPT_METHOD("BCRYPT"))
#endif /* USE_BCRYPT */
@@ -422,6 +437,11 @@ static const char *get_salt(void)
arg = &yescrypt_cost;
}
#endif /* USE_YESCRYPT */
+#if defined(USE_SM3_CRYPT)
+ if (0 == strcmp (crypt_method, "SM3")) {
+ arg = &sm3_rounds;
+ }
+#endif /* USE_SM3_CRYPT */
}
#endif
return crypt_make_salt (crypt_method, arg);
diff --git a/src/newusers.c b/src/newusers.c
index deeb361..149670e 100644
--- a/src/newusers.c
+++ b/src/newusers.c
@@ -58,12 +58,15 @@ static bool rflg = false; /* create a system account */
#ifndef USE_PAM
static /*@null@*//*@observer@*/char *crypt_method = NULL;
#define cflg (NULL != crypt_method)
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT)
static bool sflg = false;
#endif
#ifdef USE_SHA_CRYPT
static long sha_rounds = 5000;
#endif /* USE_SHA_CRYPT */
+#ifdef USE_SM3_CRYPT
+static long sm3_rounds = 5000;
+#endif /* USE_SM3_CRYPT */
#ifdef USE_BCRYPT
static long bcrypt_rounds = 13;
#endif /* USE_BCRYPT */
@@ -129,6 +132,9 @@ static void usage (int status)
#endif
#if defined(USE_YESCRYPT)
" YESCRYPT"
+#endif
+#if defined(USE_SM3_CRYPT)
+ " SM3"
#endif
);
#endif /* !USE_PAM */
@@ -136,11 +142,11 @@ static void usage (int status)
(void) fputs (_(" -r, --system create system accounts\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT, SM3\n"
" or YESCRYPT crypt algorithms\n"),
usageout);
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT */
#endif /* !USE_PAM */
(void) fputs ("\n", usageout);
@@ -436,6 +442,13 @@ static int update_passwd (struct passwd *pwd, const char *password)
}
}
#endif /* USE_YESCRYPT */
+#if defined(USE_SM3_CRYPT)
+ if (sflg) {
+ if (0 == strcmp (crypt_method, "SM3")) {
+ crypt_arg = &sm3_rounds;
+ }
+ }
+#endif /* USE_SM3_CRYPT */
}
if ((NULL != crypt_method) && (0 == strcmp(crypt_method, "NONE"))) {
@@ -492,6 +505,13 @@ static int add_passwd (struct passwd *pwd, const char *password)
}
}
#endif /* USE_PAM */
+#if defined(USE_SM3_CRYPT)
+ if (sflg) {
+ if (0 == strcmp (crypt_method, "SM3")) {
+ crypt_arg = &sm3_rounds;
+ }
+ }
+#endif /* USE_SM3_CRYPT */
}
/*
@@ -609,9 +629,9 @@ static void process_flags (int argc, char **argv)
{
int c;
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
int bad_s;
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT */
#endif /* !USE_PAM */
static struct option long_options[] = {
{"badname", no_argument, NULL, 'b'},
@@ -622,20 +642,20 @@ static void process_flags (int argc, char **argv)
{"system", no_argument, NULL, 'r'},
{"root", required_argument, NULL, 'R'},
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
{"sha-rounds", required_argument, NULL, 's'},
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT */
#endif /* !USE_PAM */
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv,
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
"c:bhrs:",
-#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */
+#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT && !USE_SM3_CRYPT */
"c:bhr",
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT */
#else /* USE_PAM */
"bhr",
#endif
@@ -658,7 +678,7 @@ static void process_flags (int argc, char **argv)
case 'R': /* no-op, handled in process_root_flag () */
break;
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
case 's':
sflg = true;
bad_s = 0;
@@ -680,14 +700,20 @@ static void process_flags (int argc, char **argv)
bad_s = 1;
}
#endif /* USE_YESCRYPT */
- if (bad_s != 0) {
+#if defined(USE_SM3_CRYPT)
+ if (( (0 == strcmp (crypt_method, "SM3"))
+ && (0 == getlong(optarg, &sm3_rounds)))) {
+ bad_s = 1;
+ }
+#endif /* USE_SM3_CRYPT */
+ if (bad_s != 0) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (EXIT_FAILURE);
}
break;
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT */
#endif /* !USE_PAM */
default:
usage (EXIT_FAILURE);
@@ -721,14 +747,14 @@ static void process_flags (int argc, char **argv)
static void check_flags (void)
{
#ifndef USE_PAM
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT)
if (sflg && !cflg) {
fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"),
Prog, "-s", "-c");
usage (EXIT_FAILURE);
}
-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT */
if (cflg) {
if ( (0 != strcmp (crypt_method, "DES"))
@@ -738,6 +764,9 @@ static void check_flags (void)
&& (0 != strcmp (crypt_method, "SHA256"))
&& (0 != strcmp (crypt_method, "SHA512"))
#endif /* USE_SHA_CRYPT */
+#ifdef USE_SM3_CRYPT
+ && (0 != strcmp (crypt_method, "SM3"))
+#endif /* USE_SM3_CRYPT */
#ifdef USE_BCRYPT
&& (0 != strcmp (crypt_method, "BCRYPT"))
#endif /* USE_BCRYPT */
diff --git a/src/passwd.c b/src/passwd.c
index 8c6f81a..00711da 100644
--- a/src/passwd.c
+++ b/src/passwd.c
@@ -84,7 +84,7 @@ static bool spw_locked = false;
#ifndef USE_PAM
/*
* Size of the biggest passwd:
- * $6$ 3
+ * $sm3$ 5
* rounds= 7
* 999999999 9
* $ 1
@@ -93,7 +93,7 @@ static bool spw_locked = false;
* SHA512 123
* nul 1
*
- * total 161
+ * total 163
*/
static char crypt_passwd[256];
static bool do_update_pwd = false;
@@ -263,6 +263,9 @@ static int new_password (const struct passwd *pw)
#ifdef USE_YESCRYPT
|| (strcmp (method, "YESCRYPT") == 0)
#endif /* USE_YESCRYPT*/
+#ifdef USE_SM3_CRYPT
+ || (strcmp (method, "SM3") == 0)
+#endif /* USE_SM3_CRYPT*/
) {
pass_max_len = -1;
--
2.27.0