Rewrite csrand_interval() as a wrapper around csrand_uniform()

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>
This commit is contained in:
Alejandro Colomar 2022-12-30 19:46:09 +01:00 committed by Serge Hallyn
parent 31375d48ca
commit 1db190cb66
3 changed files with 11 additions and 27 deletions

View 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);

View 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;
}

View 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)