summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2016-05-17 21:05:49 +0000
committertedu <tedu@openbsd.org>2016-05-17 21:05:49 +0000
commit83a0fc521db1eeb5a15be2825f2131768b37819b (patch)
treeb062b807507974bc698701d76762828ac7a14679 /sys
parentFix "skeyinit username" run as root. Also reduce the pledge (diff)
downloadwireguard-openbsd-83a0fc521db1eeb5a15be2825f2131768b37819b.tar.xz
wireguard-openbsd-83a0fc521db1eeb5a15be2825f2131768b37819b.zip
Change the random event buffer from a queue to an endless ring. This way
we don't drop any events when the queue is full. They are instead mixed into previous events. The mixing function selected is addition instead of xor to reduce the possibility that new values effectively erase existing ones. Convert some types to u_int to ensure defined overflow. ok deraadt djm
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/rnd.c42
-rw-r--r--sys/dev/rndvar.h4
2 files changed, 19 insertions, 27 deletions
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c
index 0f6c5660407..83583764426 100644
--- a/sys/dev/rnd.c
+++ b/sys/dev/rnd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rnd.c,v 1.179 2016/02/19 19:15:59 stefan Exp $ */
+/* $OpenBSD: rnd.c,v 1.180 2016/05/17 21:05:49 tedu Exp $ */
/*
* Copyright (c) 2011 Theo de Raadt.
@@ -227,7 +227,7 @@ struct rand_event {
u_int re_val;
} rnd_event_space[QEVLEN];
/* index of next free slot */
-int rnd_event_idx;
+u_int rnd_event_idx;
struct timeout rnd_timeout;
struct rndstats rndstats;
@@ -257,6 +257,9 @@ rnd_get(void)
{
if (rnd_event_idx == 0)
return NULL;
+ /* if it wrapped around, start dequeuing at the end */
+ if (rnd_event_idx > QEVLEN)
+ rnd_event_idx = QEVLEN;
return &rnd_event_space[--rnd_event_idx];
}
@@ -264,13 +267,15 @@ rnd_get(void)
static __inline struct rand_event *
rnd_put(void)
{
- if (rnd_event_idx == QEVLEN)
- return NULL;
+ u_int idx = rnd_event_idx++;
+
+ /* allow wrapping. caller will use xor. */
+ idx = idx % QEVLEN;
- return &rnd_event_space[rnd_event_idx++];
+ return &rnd_event_space[idx];
}
-static __inline int
+static __inline u_int
rnd_qlen(void)
{
return rnd_event_idx;
@@ -284,11 +289,9 @@ rnd_qlen(void)
* The number "val" is also added to the pool - it should somehow describe
* the type of event which just happened. Currently the values of 0-255
* are for keyboard scan codes, 256 and upwards - for interrupts.
- * On the i386, this is assumed to be at most 16 bits, and the high bits
- * are used for a high-resolution timer.
*/
void
-enqueue_randomness(int state, int val)
+enqueue_randomness(u_int state, u_int val)
{
int delta, delta2, delta3;
struct timer_rand_state *p;
@@ -297,7 +300,7 @@ enqueue_randomness(int state, int val)
u_int time, nbits;
#ifdef DIAGNOSTIC
- if (state < 0 || state >= RND_SRC_NUM)
+ if (state >= RND_SRC_NUM)
return;
#endif
@@ -362,28 +365,17 @@ enqueue_randomness(int state, int val)
mtx_enter(&entropylock);
if (!p->dont_count_entropy) {
- /*
- * the logic is to drop low-entropy entries,
- * in hope for dequeuing to be more randomfull
- */
- if (rnd_qlen() > QEVSLOW && nbits < QEVSBITS) {
- rndstats.rnd_drople++;
- goto done;
- }
p->last_time = time;
p->last_delta = delta3;
p->last_delta2 = delta2;
}
- if ((rep = rnd_put()) == NULL) {
- rndstats.rnd_drops++;
- goto done;
- }
+ rep = rnd_put();
rep->re_state = p;
rep->re_nbits = nbits;
- rep->re_time = ts.tv_nsec ^ (ts.tv_sec << 20);
- rep->re_val = val;
+ rep->re_time += ts.tv_nsec ^ (ts.tv_sec << 20);
+ rep->re_val += val;
rndstats.rnd_enqs++;
rndstats.rnd_ed[nbits]++;
@@ -393,7 +385,7 @@ enqueue_randomness(int state, int val)
if (rnd_qlen() > QEVSLOW/2 && timeout_initialized(&rnd_timeout) &&
!timeout_pending(&rnd_timeout))
timeout_add(&rnd_timeout, 1);
-done:
+
mtx_leave(&entropylock);
}
diff --git a/sys/dev/rndvar.h b/sys/dev/rndvar.h
index 024115491d7..3eac8ab1c91 100644
--- a/sys/dev/rndvar.h
+++ b/sys/dev/rndvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rndvar.h,v 1.36 2015/02/07 01:19:40 deraadt Exp $ */
+/* $OpenBSD: rndvar.h,v 1.37 2016/05/17 21:05:49 tedu Exp $ */
/*
* Copyright (c) 1996,2000 Michael Shalayeff.
@@ -71,7 +71,7 @@ extern struct rndstats rndstats;
void random_start(void);
-void enqueue_randomness(int, int);
+void enqueue_randomness(unsigned int, unsigned int);
void suspend_randomness(void);
void resume_randomness(char *, size_t);