diff --git a/include/randutils.h b/include/randutils.h index 5b863d04c..690bf5e54 100644 --- a/include/randutils.h +++ b/include/randutils.h @@ -11,7 +11,7 @@ extern int rand_get_number(int low_n, int high_n); /* /dev/urandom based with fallback to rand() */ extern int random_get_fd(void); -extern void ul_random_get_bytes(void *buf, size_t nbytes); +extern int ul_random_get_bytes(void *buf, size_t nbytes); extern const char *random_tell_source(void); #endif diff --git a/lib/randutils.c b/lib/randutils.c index b473577af..39edf4e78 100644 --- a/lib/randutils.c +++ b/lib/randutils.c @@ -102,7 +102,12 @@ int random_get_fd(void) #define UL_RAND_READ_ATTEMPTS 8 #define UL_RAND_READ_DELAY 125000 /* microseconds */ -void ul_random_get_bytes(void *buf, size_t nbytes) +/* + * Write @nbytes random bytes into @buf. + * + * Returns 0 for good quality of random bytes or 1 for weak quality. + */ +int ul_random_get_bytes(void *buf, size_t nbytes) { unsigned char *cp = (unsigned char *)buf; size_t i, n = nbytes; @@ -118,7 +123,7 @@ void ul_random_get_bytes(void *buf, size_t nbytes) n -= x; cp += x; lose_counter = 0; - + errno = 0; } else if (errno == ENOSYS) { /* kernel without getrandom() */ break; @@ -177,6 +182,8 @@ void ul_random_get_bytes(void *buf, size_t nbytes) sizeof(ul_jrand_seed)-sizeof(unsigned short)); } #endif + + return n != 0; } diff --git a/libuuid/man/uuid_generate.3 b/libuuid/man/uuid_generate.3 index 0043c625f..dccecd658 100644 --- a/libuuid/man/uuid_generate.3 +++ b/libuuid/man/uuid_generate.3 @@ -49,7 +49,10 @@ The .B uuid_generate function creates a new universally unique identifier (UUID). The uuid will be generated based on high-quality randomness from +.IR getrandom(2) , .IR /dev/urandom , +or +.IR /dev/random if available. If it is not available, then .B uuid_generate will use an alternative algorithm which uses the current time, the @@ -59,8 +62,7 @@ using a pseudo-random generator. The .B uuid_generate_random function forces the use of the all-random UUID format, even if -a high-quality random number generator (i.e., -.IR /dev/urandom ) +a high-quality random number generator is not available, in which case a pseudo-random generator will be substituted. Note that the use of a pseudo-random generator may compromise the uniqueness of UUIDs diff --git a/libuuid/src/gen_uuid.c b/libuuid/src/gen_uuid.c index 50039fc2e..d353fa1a0 100644 --- a/libuuid/src/gen_uuid.c +++ b/libuuid/src/gen_uuid.c @@ -499,11 +499,11 @@ int uuid_generate_time_safe(uuid_t out) } -void __uuid_generate_random(uuid_t out, int *num) +int __uuid_generate_random(uuid_t out, int *num) { uuid_t buf; struct uuid uu; - int i, n; + int i, n, r = 0; if (!num || !*num) n = 1; @@ -511,7 +511,8 @@ void __uuid_generate_random(uuid_t out, int *num) n = *num; for (i = 0; i < n; i++) { - ul_random_get_bytes(buf, sizeof(buf)); + if (ul_random_get_bytes(buf, sizeof(buf))) + r = -1; uuid_unpack(buf, &uu); uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000; @@ -520,6 +521,8 @@ void __uuid_generate_random(uuid_t out, int *num) uuid_pack(&uu, out); out += sizeof(uuid_t); } + + return r; } void uuid_generate_random(uuid_t out) @@ -531,27 +534,15 @@ void uuid_generate_random(uuid_t out) } /* - * Check whether good random source (/dev/random or /dev/urandom) - * is available. - */ -static int have_random_source(void) -{ - return (access("/dev/random", R_OK) == 0 || - access("/dev/urandom", R_OK) == 0); -} - - -/* - * This is the generic front-end to uuid_generate_random and - * uuid_generate_time. It uses uuid_generate_random only if - * /dev/urandom is available, since otherwise we won't have - * high-quality randomness. + * This is the generic front-end to __uuid_generate_random and + * uuid_generate_time. It uses __uuid_generate_random output + * only if high-quality randomness is available. */ void uuid_generate(uuid_t out) { - if (have_random_source()) - uuid_generate_random(out); - else + int num = 1; + + if (__uuid_generate_random(out, &num)) uuid_generate_time(out); } diff --git a/libuuid/src/uuidd.h b/libuuid/src/uuidd.h index e55c86f2f..fbe821ff3 100644 --- a/libuuid/src/uuidd.h +++ b/libuuid/src/uuidd.h @@ -49,6 +49,6 @@ #define UUIDD_MAX_OP UUIDD_OP_BULK_RANDOM_UUID extern int __uuid_generate_time(uuid_t out, int *num); -extern void __uuid_generate_random(uuid_t out, int *num); +extern int __uuid_generate_random(uuid_t out, int *num); #endif /* _UUID_UUID_H */