UTI_GetRandomBytesUrandom(buf, j);
if (j && buf[j - 1] % 2)
c++;
+ if (random() % 10000 == 0) {
+ UTI_ResetGetRandomFunctions();
+ TEST_CHECK(!urandom_file);
+ }
}
TEST_CHECK(c > 46000 && c < 48000);
UTI_GetRandomBytes(buf, j);
if (j && buf[j - 1] % 2)
c++;
+ if (random() % 10000 == 0) {
+ UTI_ResetGetRandomFunctions();
+#if HAVE_GETRANDOM
+ TEST_CHECK(getrandom_buf_available == 0);
+#endif
+ }
}
TEST_CHECK(c > 46000 && c < 48000);
#define DEV_URANDOM "/dev/urandom"
+static FILE *urandom_file = NULL;
+
void
UTI_GetRandomBytesUrandom(void *buf, unsigned int len)
{
- static FILE *f = NULL;
-
- if (!f)
- f = UTI_OpenFile(NULL, DEV_URANDOM, NULL, 'R', 0);
- if (fread(buf, 1, len, f) != len)
+ if (!urandom_file)
+ urandom_file = UTI_OpenFile(NULL, DEV_URANDOM, NULL, 'R', 0);
+ if (fread(buf, 1, len, urandom_file) != len)
LOG_FATAL("Can't read from %s", DEV_URANDOM);
}
/* ================================================== */
#ifdef HAVE_GETRANDOM
+
+static unsigned int getrandom_buf_available = 0;
+
static void
get_random_bytes_getrandom(char *buf, unsigned int len)
{
static char rand_buf[256];
- static unsigned int available = 0, disabled = 0;
+ static unsigned int disabled = 0;
unsigned int i;
for (i = 0; i < len; i++) {
- if (!available) {
+ if (getrandom_buf_available == 0) {
if (disabled)
break;
break;
}
- available = sizeof (rand_buf);
+ getrandom_buf_available = sizeof (rand_buf);
}
- buf[i] = rand_buf[--available];
+ buf[i] = rand_buf[--getrandom_buf_available];
}
if (i < len)
/* ================================================== */
+void
+UTI_ResetGetRandomFunctions(void)
+{
+ if (urandom_file) {
+ fclose(urandom_file);
+ urandom_file = NULL;
+ }
+#ifdef HAVE_GETRANDOM
+ getrandom_buf_available = 0;
+#endif
+}
+
+/* ================================================== */
+
int
UTI_BytesToHex(const void *buf, unsigned int buf_len, char *hex, unsigned int hex_len)
{
generating long-term keys */
extern void UTI_GetRandomBytes(void *buf, unsigned int len);
+/* Close /dev/urandom and drop any cached data used by the GetRandom functions
+ to prevent forked processes getting the same sequence of random numbers */
+extern void UTI_ResetGetRandomFunctions(void);
+
/* Print data in hexadecimal format */
extern int UTI_BytesToHex(const void *buf, unsigned int buf_len, char *hex, unsigned int hex_len);