Merge pull request #377 from besser82/topic/besser82/salt_c_random
libmisc/salt.c: Obtain random bytes from /dev/urandom.
This commit is contained in:
commit
b3b1f5d4a4
@ -11,11 +11,10 @@
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
@ -74,7 +73,7 @@
|
||||
#define GENSALT_SETTING_SIZE 100
|
||||
|
||||
/* local function prototypes */
|
||||
static void seedRNG (void);
|
||||
static long read_random_bytes (void);
|
||||
static /*@observer@*/const char *gensalt (size_t salt_size);
|
||||
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||
static long shadow_random (long min, long max);
|
||||
@ -125,23 +124,27 @@ static /*@observer@*/char *l64a (long value)
|
||||
}
|
||||
#endif /* !HAVE_L64A */
|
||||
|
||||
static void seedRNG (void)
|
||||
/* Read sizeof (long) random bytes from /dev/urandom. */
|
||||
static long read_random_bytes (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
static int seeded = 0;
|
||||
long randval = 0;
|
||||
FILE *f = fopen ("/dev/urandom", "r");
|
||||
|
||||
if (0 == seeded) {
|
||||
(void) gettimeofday (&tv, NULL);
|
||||
srandom (tv.tv_sec ^ tv.tv_usec ^ getpid ());
|
||||
seeded = 1;
|
||||
if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval))
|
||||
{
|
||||
fprintf (shadow_logfd,
|
||||
_("Unable to read from /dev/urandom.\n"));
|
||||
|
||||
fclose(f);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
return randval;
|
||||
}
|
||||
|
||||
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||
/* It is not clear what is the maximum value of random().
|
||||
* We assume 2^31-1.*/
|
||||
#define RANDOM_MAX 0x7FFFFFFF
|
||||
|
||||
/*
|
||||
* Return a random number between min and max (both included).
|
||||
*
|
||||
@ -151,8 +154,9 @@ static long shadow_random (long min, long max)
|
||||
{
|
||||
double drand;
|
||||
long ret;
|
||||
seedRNG ();
|
||||
drand = (double) (max - min + 1) * random () / RANDOM_MAX;
|
||||
|
||||
drand = (double) (read_random_bytes () & 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);
|
||||
@ -216,7 +220,14 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, /*@null@*/int *pref
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the result buffer is long enough. */
|
||||
/*
|
||||
* 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);
|
||||
@ -274,7 +285,14 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, /*@null@*/int *p
|
||||
rounds = 19;
|
||||
}
|
||||
|
||||
/* Check if the result buffer is long enough. */
|
||||
/*
|
||||
* Check if the result buffer is long enough.
|
||||
* We are going to write three bytes,
|
||||
* plus one byte for the terminator.
|
||||
* XX$
|
||||
* 000
|
||||
* 123
|
||||
*/
|
||||
assert (GENSALT_SETTING_SIZE > buf_begin + 3);
|
||||
|
||||
(void) snprintf (buf + buf_begin, 4, "%2.2lu$", rounds);
|
||||
@ -308,8 +326,15 @@ static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, /*@null@*/int *p
|
||||
cost = Y_COST_MAX;
|
||||
}
|
||||
|
||||
/* Check if the result buffer is long enough. */
|
||||
assert (GENSALT_SETTING_SIZE > buf_begin + 3);
|
||||
/*
|
||||
* Check if the result buffer is long enough.
|
||||
* We are going to write four bytes,
|
||||
* plus one byte for the terminator.
|
||||
* jXX$
|
||||
* 0000
|
||||
* 1234
|
||||
*/
|
||||
assert (GENSALT_SETTING_SIZE > buf_begin + 4);
|
||||
|
||||
buf[buf_begin + 0] = 'j';
|
||||
if (cost < 3) {
|
||||
@ -333,10 +358,9 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
|
||||
|
||||
assert (salt_size >= MIN_SALT_SIZE &&
|
||||
salt_size <= MAX_SALT_SIZE);
|
||||
seedRNG ();
|
||||
strcat (salt, l64a (random()));
|
||||
strcat (salt, l64a (read_random_bytes ()));
|
||||
do {
|
||||
strcat (salt, l64a (random()));
|
||||
strcat (salt, l64a (read_random_bytes ()));
|
||||
} while (strlen (salt) < salt_size);
|
||||
|
||||
salt[salt_size] = '\0';
|
||||
|
Loading…
Reference in New Issue
Block a user