Let workers fetch entropy from keymgr.

At bootup and every 1800 seconds after that the worker processes will
ask the keymgr for new entropy that they will seed into their PRNG.

Additionally once received the worker calls RAND_poll() to grab
more entropy from the system to be mixed in.
This commit is contained in:
Joris Vink 2017-02-27 21:28:35 -08:00
parent 60a3f60a92
commit f57ca7dcc2
3 changed files with 54 additions and 0 deletions

View File

@ -66,6 +66,8 @@ extern int daemon(int, int);
#define KORE_TLS_VERSION_1_0 1
#define KORE_TLS_VERSION_BOTH 2
#define KORE_RESEED_TIME (1800 * 1000)
#define errno_s strerror(errno)
#define ssl_errno_s ERR_error_string(ERR_get_error(), NULL)
@ -418,6 +420,8 @@ struct kore_timer {
#define KORE_MSG_KEYMGR_REQ 3
#define KORE_MSG_KEYMGR_RESP 4
#define KORE_MSG_SHUTDOWN 5
#define KORE_MSG_ENTROPY_REQ 6
#define KORE_MSG_ENTROPY_RESP 7
/* Predefined message targets. */
#define KORE_MSG_PARENT 1000

View File

@ -51,6 +51,7 @@ static void keymgr_save_randfile(void);
static void keymgr_load_privatekey(struct kore_domain *);
static void keymgr_msg_recv(struct kore_msg *, const void *);
static void keymgr_entropy_request(struct kore_msg *, const void *);
static void keymgr_rsa_encrypt(struct kore_msg *, const void *,
struct key *);
@ -85,6 +86,7 @@ kore_keymgr_run(void)
kore_msg_worker_init();
kore_msg_register(KORE_MSG_KEYMGR_REQ, keymgr_msg_recv);
kore_msg_register(KORE_MSG_ENTROPY_REQ, keymgr_entropy_request);
last_seed = 0;
kore_log(LOG_NOTICE, "key manager started");
@ -263,6 +265,22 @@ keymgr_load_privatekey(struct kore_domain *dom)
TAILQ_INSERT_TAIL(&keys, key, list);
}
static void
keymgr_entropy_request(struct kore_msg *msg, const void *data)
{
u_int8_t buf[RAND_FILE_SIZE];
if (RAND_bytes(buf, sizeof(buf)) != 1) {
kore_log(LOG_WARNING,
"failed to generate entropy for worker %u: %s",
msg->src, ssl_errno_s);
return;
}
/* No cleanse, this stuff is leaked in the kernel path anyway. */
kore_msg_send(msg->src, KORE_MSG_ENTROPY_RESP, buf, sizeof(buf));
}
static void
keymgr_msg_recv(struct kore_msg *msg, const void *data)
{

View File

@ -21,6 +21,10 @@
#include <sys/resource.h>
#include <sys/socket.h>
#if !defined(KORE_NO_TLS)
#include <openssl/rand.h>
#endif
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
@ -71,6 +75,10 @@ static void worker_unlock(void);
static inline int kore_worker_acceptlock_obtain(void);
static inline void kore_worker_acceptlock_release(void);
#if !defined(KORE_NO_TLS)
static void worker_entropy_recv(struct kore_msg *, const void *);
#endif
static struct kore_worker *kore_workers;
static int shm_accept_key;
static struct wlock *accept_lock;
@ -270,6 +278,9 @@ kore_worker_entry(struct kore_worker *kw)
char buf[16];
int quit, had_lock, r;
u_int64_t now, next_lock, netwait;
#if !defined(KORE_NO_TLS)
u_int64_t last_seed;
#endif
worker = kw;
@ -331,6 +342,11 @@ kore_worker_entry(struct kore_worker *kw)
kore_task_init();
#endif
#if !defined(KORE_NO_TLS)
last_seed = 0;
kore_msg_register(KORE_MSG_ENTROPY_RESP, worker_entropy_recv);
#endif
kore_log(LOG_NOTICE, "worker %d started (cpu#%d)", kw->id, kw->cpu);
rcall = kore_runtime_getcall("kore_worker_configure");
@ -364,6 +380,14 @@ kore_worker_entry(struct kore_worker *kw)
if (netwait > 100)
netwait = 100;
#if !defined(KORE_NO_TLS)
if ((now - last_seed) > KORE_RESEED_TIME) {
kore_msg_send(KORE_WORKER_KEYMGR,
KORE_MSG_ENTROPY_REQ, NULL, 0);
last_seed = now;
}
#endif
if (now > next_lock) {
if (kore_worker_acceptlock_obtain()) {
if (had_lock == 0) {
@ -557,3 +581,11 @@ worker_unlock(void)
if (!__sync_bool_compare_and_swap(&(accept_lock->lock), 1, 0))
kore_log(LOG_NOTICE, "worker_unlock(): wasnt locked");
}
#if !defined(KORE_NO_TLS)
static void
worker_entropy_recv(struct kore_msg *msg, const void *data)
{
RAND_seed(data, msg->length);
}
#endif