]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
Rewrite csrand_interval() as a wrapper around csrand_uniform()
authorAlejandro Colomar <alx@kernel.org>
Fri, 30 Dec 2022 18:46:09 +0000 (19:46 +0100)
committerSerge Hallyn <serge@hallyn.com>
Sat, 28 Jan 2023 03:48:37 +0000 (21:48 -0600)
The old code didn't produce very good random numbers.  It had a bias.
And that was from performing some unnecessary floating-point
calculations that overcomplicate the problem.

Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Cc: Cristian Rodríguez <crrodriguez@opensuse.org>
Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Cc: Björn Esser <besser82@fedoraproject.org>
Cc: Yann Droneaud <ydroneaud@opteya.com>
Cc: Joseph Myers <joseph@codesourcery.com>
Cc: Sam James <sam@gentoo.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
lib/prototypes.h
libmisc/csrand.c
libmisc/salt.c

index 722d6d98947e2778f332871f66fcda9592b3c26d..03870ad7a6fc3d672f34ff9ef6604dfe05a97cdb 100644 (file)
@@ -359,6 +359,7 @@ extern void pw_free (/*@out@*/ /*@only@*/struct passwd *pwent);
 /* csrand.c */
 unsigned long csrand (void);
 unsigned long csrand_uniform (unsigned long n);
+unsigned long csrand_interval (unsigned long min, unsigned long max);
 
 /* remove_tree.c */
 extern int remove_tree (const char *root, bool remove_root);
index 0cc999723093cf49231b1214303b77cdac1d8417..f06b95792a4b4175cfde6de7739286f4bf6349f7 100644 (file)
@@ -85,3 +85,13 @@ csrand_uniform(unsigned long n)
 
        return r;
 }
+
+
+/*
+ * Return a uniformly-distributed CS random value in the interval [min, max].
+ */
+unsigned long
+csrand_interval(unsigned long min, unsigned long max)
+{
+       return csrand_uniform(max - min + 1) + min;
+}
index c3f3d23a6c24f5bf55aa04c2c3d0506c3a3da071..103fb1cffd6370c941e50d36938f9487bb1cc853 100644 (file)
@@ -89,9 +89,6 @@
 #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)
-static unsigned long csrand_interval (unsigned long min, unsigned long max);
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
 #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);
@@ -106,30 +103,6 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, unsigned long co
 #endif /* USE_YESCRYPT */
 
 
-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
-/*
- * Return a random number between min and max (both included).
- *
- * It favors slightly the higher numbers.
- */
-static unsigned long csrand_interval (unsigned long min, unsigned long max)
-{
-       double drand;
-       long ret;
-
-       drand = (double) (csrand () & RAND_MAX) / (double) RAND_MAX;
-       drand *= (double) (max - min + 1);
-       /* On systems were this is not random() range is lower, we favor
-        * higher numbers of salt. */
-       ret = (long) (max + 1 - drand);
-       /* And we catch limits, and use the highest number */
-       if ((ret < min) || (ret > max)) {
-               ret = max;
-       }
-       return ret;
-}
-#endif /* USE_SHA_CRYPT || USE_BCRYPT */
-
 #ifdef USE_SHA_CRYPT
 /* Return the the rounds number for the SHA crypt methods. */
 static /*@observer@*/unsigned long SHA_get_salt_rounds (/*@null@*/const int *prefered_rounds)