/* /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
#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;
n -= x;
cp += x;
lose_counter = 0;
-
+ errno = 0;
} else if (errno == ENOSYS) { /* kernel without getrandom() */
break;
sizeof(ul_jrand_seed)-sizeof(unsigned short));
}
#endif
+
+ return n != 0;
}
.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
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
}
-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;
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;
uuid_pack(&uu, out);
out += sizeof(uuid_t);
}
+
+ return r;
}
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);
}
#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 */