random: Read /dev/random in the background with eloop read socket

This makes it more likely to be able to fetch the 20 octet seed from
/dev/random in cases where other programs may also be competing for
this.
This commit is contained in:
Jouni Malinen 2011-03-22 23:15:00 +02:00
parent c4bb881743
commit d47fa330b8
4 changed files with 91 additions and 2 deletions

View file

@ -1,6 +1,6 @@
/*
* Random number generator
* Copyright (c) 2010, Jouni Malinen <j@w1.fi>
* Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -34,6 +34,7 @@
#endif /* __linux__ */
#include "utils/common.h"
#include "utils/eloop.h"
#include "sha1.h"
#include "random.h"
@ -53,6 +54,7 @@ static unsigned int pool_pos = 0;
static u8 dummy_key[20];
#ifdef __linux__
static size_t dummy_key_avail = 0;
static int random_fd = -1;
#endif /* __linux__ */
static unsigned int own_pool_ready = 0;
@ -260,3 +262,76 @@ void random_mark_pool_ready(void)
wpa_printf(MSG_DEBUG, "random: Mark internal entropy pool to be "
"ready (count=%u/%u)", own_pool_ready, MIN_READY_MARK);
}
#ifdef __linux__
static void random_close_fd(void)
{
if (random_fd >= 0) {
eloop_unregister_read_sock(random_fd);
close(random_fd);
random_fd = -1;
}
}
static void random_read_fd(int sock, void *eloop_ctx, void *sock_ctx)
{
ssize_t res;
if (dummy_key_avail == sizeof(dummy_key)) {
random_close_fd();
return;
}
res = read(sock, dummy_key + dummy_key_avail,
sizeof(dummy_key) - dummy_key_avail);
if (res < 0) {
wpa_printf(MSG_ERROR, "random: Cannot read from /dev/random: "
"%s", strerror(errno));
return;
}
wpa_printf(MSG_DEBUG, "random: Got %u/%u bytes from /dev/random",
(unsigned) res,
(unsigned) (sizeof(dummy_key) - dummy_key_avail));
dummy_key_avail += res;
if (dummy_key_avail == sizeof(dummy_key))
random_close_fd();
}
#endif /* __linux__ */
void random_init(void)
{
#ifdef __linux__
if (random_fd >= 0)
return;
random_fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
if (random_fd < 0) {
#ifndef CONFIG_NO_STDOUT_DEBUG
int error = errno;
perror("open(/dev/random)");
wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s",
strerror(error));
#endif /* CONFIG_NO_STDOUT_DEBUG */
return;
}
wpa_printf(MSG_DEBUG, "random: Trying to read entropy from "
"/dev/random");
eloop_register_read_sock(random_fd, random_read_fd, NULL, NULL);
#endif /* __linux__ */
}
void random_deinit(void)
{
#ifdef __linux__
random_close_fd();
#endif /* __linux__ */
}

View file

@ -1,6 +1,6 @@
/*
* Random number generator
* Copyright (c) 2010, Jouni Malinen <j@w1.fi>
* Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -16,11 +16,15 @@
#define RANDOM_H
#ifdef CONFIG_NO_RANDOM_POOL
#define random_init() do { } while (0)
#define random_deinit() do { } while (0)
#define random_add_randomness(b, l) do { } while (0)
#define random_get_bytes(b, l) os_get_random((b), (l))
#define random_pool_ready() 1
#define random_mark_pool_ready() do { } while (0)
#else /* CONFIG_NO_RANDOM_POOL */
void random_init(void);
void random_deinit(void);
void random_add_randomness(const void *buf, size_t len);
int random_get_bytes(void *buf, size_t len);
int random_pool_ready(void);