Address multiple problems with rnd(4)/cprng(9):
1) Add a per-cpu CPRNG to handle short reads from /dev/urandom so that programs like perl don't drain the entropy pool dry by repeatedly opening, reading 4 bytes, closing. 2) Really fix the locking around reseeds and destroys. 3) Fix the opportunistic-reseed strategy so it actually works, reseeding existing RNGs once each (as they are used, so idle RNGs don't get reseeded) until the pool is half empty or newly full again.
This commit is contained in:
parent
8d59073313
commit
8e1a1c9f45
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: rnd.4,v 1.18 2011/12/17 21:21:59 wiz Exp $
|
||||
.\" $NetBSD: rnd.4,v 1.19 2012/04/17 02:50:39 tls Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1997 Michael Graff
|
||||
.\" All rights reserved.
|
||||
|
@ -52,13 +52,32 @@ SP 800-90) which is used to generate values returned to userspace when
|
|||
the pseudo-device is read.
|
||||
.Pp
|
||||
The pseudodevice is cloning, which means that each time it is opened,
|
||||
a new instance of the stream generator is created.
|
||||
a new instance of the stream generator may be created.
|
||||
Interposing a stream
|
||||
generator between the entropy pool and readers in this manner protects
|
||||
readers from each other (each reader's random stream is generated from a
|
||||
unique key) and protects all users of the entropy pool from any attack
|
||||
which might correlate its successive outputs to each other, such as
|
||||
iterative guessing attacks.
|
||||
.Pp
|
||||
Certain programs make very short reads from
|
||||
.Pa /dev/urandom
|
||||
each time they begin execution. One program with this behavior is
|
||||
.Xr perl 1 .
|
||||
If such a program is run repeatedly (for example from a network
|
||||
service or shell script), the resulting repeated keying of the stream
|
||||
generator can quickly drain the entropy pool dry. As an optimization
|
||||
for such cases, a separate per-CPU instance of the stream generator
|
||||
is used to handle reads from
|
||||
.Pa /dev/urandom
|
||||
which are smaller than the key length of the underlying cipher. Any
|
||||
read of a larger size causes an immediate allocation of a private
|
||||
instance of the stream generator for the reader. Since all stream
|
||||
generators are automatically rekeyed upon use when sufficient entropy
|
||||
is available, the shared short-request generators do still offer
|
||||
some protection against other consumers of
|
||||
.Pa /dev/urandom ,
|
||||
though less than is provided for consumers making larger requests.
|
||||
.Sh USER ACCESS
|
||||
User code can obtain random values from the kernel in two ways.
|
||||
.Pp
|
||||
|
@ -190,6 +209,20 @@ The device is a tape device.
|
|||
The device is a terminal, mouse, or other user input device.
|
||||
.It Dv RND_TYPE_RNG
|
||||
The device is a random number generator.
|
||||
.It Dv RND_TYPE_SKEW
|
||||
The "device" is a measurement of the skew between two clocks, such as a
|
||||
periodic device interrupt and the system timecounter, a timecounter and
|
||||
an audio codec, or some other source of pairs of events where each
|
||||
member of each pair is derived from a different instance of some
|
||||
recurring physical process.
|
||||
.It Dv RND_TYPE_ENV
|
||||
The device is an environmental sensor such as a temperature sensor or
|
||||
a fan speed sensor.
|
||||
.It Dv RND_TYPE_VM
|
||||
The "device" consists of timings of virtual memory system events.
|
||||
.It Dv RND_TYPE_POWER
|
||||
The device is a sensor returning changes in the power state of the
|
||||
system, such as battery charge state or A/C adapter state.
|
||||
.El
|
||||
.Pp
|
||||
.Va flags
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rndpseudo.c,v 1.7 2012/03/30 20:15:18 drochner Exp $ */
|
||||
/* $NetBSD: rndpseudo.c,v 1.8 2012/04/17 02:50:38 tls Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.7 2012/03/30 20:15:18 drochner Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.8 2012/04/17 02:50:38 tls Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_compat_netbsd.h"
|
||||
|
@ -54,6 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.7 2012/03/30 20:15:18 drochner Exp $
|
|||
#include <sys/pool.h>
|
||||
#include <sys/kauth.h>
|
||||
#include <sys/cprng.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <sys/rnd.h>
|
||||
|
@ -95,6 +96,11 @@ extern int rnd_debug;
|
|||
static pool_cache_t rp_pc;
|
||||
static pool_cache_t rp_cpc;
|
||||
|
||||
/*
|
||||
* The per-CPU RNGs used for short requests
|
||||
*/
|
||||
cprng_strong_t **rp_cpurngs;
|
||||
|
||||
/*
|
||||
* A context. cprng plus a smidge.
|
||||
*/
|
||||
|
@ -193,6 +199,9 @@ rndattach(int num)
|
|||
mutex_spin_enter(&rndpool_mtx);
|
||||
rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1);
|
||||
mutex_spin_exit(&rndpool_mtx);
|
||||
|
||||
rp_cpurngs = kmem_zalloc(maxcpus * sizeof(cprng_strong_t *),
|
||||
KM_SLEEP);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -251,8 +260,10 @@ rnd_read(struct file * fp, off_t *offp, struct uio *uio,
|
|||
kauth_cred_t cred, int flags)
|
||||
{
|
||||
rp_ctx_t *ctx = fp->f_data;
|
||||
cprng_strong_t *cprng;
|
||||
u_int8_t *bf;
|
||||
int strength, ret;
|
||||
struct cpu_info *ci = curcpu();
|
||||
|
||||
DPRINTF(RND_DEBUG_READ,
|
||||
("Random: Read of %zu requested, flags 0x%08x\n",
|
||||
|
@ -261,14 +272,35 @@ rnd_read(struct file * fp, off_t *offp, struct uio *uio,
|
|||
if (uio->uio_resid == 0)
|
||||
return (0);
|
||||
|
||||
if (ctx->cprng == NULL) {
|
||||
rnd_alloc_cprng(ctx);
|
||||
if (__predict_false(ctx->cprng == NULL)) {
|
||||
return EIO;
|
||||
if (ctx->hard || uio->uio_resid > NIST_BLOCK_KEYLEN_BYTES) {
|
||||
if (ctx->cprng == NULL) {
|
||||
rnd_alloc_cprng(ctx);
|
||||
}
|
||||
cprng = ctx->cprng;
|
||||
} else {
|
||||
int index = cpu_index(ci);
|
||||
|
||||
if (__predict_false(rp_cpurngs[index] == NULL)) {
|
||||
char rngname[32];
|
||||
|
||||
snprintf(rngname, sizeof(rngname),
|
||||
"%s-short", cpu_name(ci));
|
||||
rp_cpurngs[index] =
|
||||
cprng_strong_create(rngname, IPL_NONE,
|
||||
CPRNG_INIT_ANY |
|
||||
CPRNG_REKEY_ANY);
|
||||
}
|
||||
cprng = rp_cpurngs[index];
|
||||
}
|
||||
|
||||
if (__predict_false(cprng == NULL)) {
|
||||
printf("NULL rng!\n");
|
||||
return EIO;
|
||||
}
|
||||
|
||||
strength = cprng_strong_strength(ctx->cprng);
|
||||
KASSERT(!mutex_owned(&cprng->reseed.mtx));
|
||||
|
||||
strength = cprng_strong_strength(cprng);
|
||||
ret = 0;
|
||||
bf = pool_cache_get(rp_pc, PR_WAITOK);
|
||||
while (uio->uio_resid > 0) {
|
||||
|
@ -284,7 +316,7 @@ rnd_read(struct file * fp, off_t *offp, struct uio *uio,
|
|||
n = want;
|
||||
}
|
||||
|
||||
nread = cprng_strong(ctx->cprng, bf, n,
|
||||
nread = cprng_strong(cprng, bf, n,
|
||||
(fp->f_flag & FNONBLOCK) ? FNONBLOCK : 0);
|
||||
if (nread != n) {
|
||||
if (fp->f_flag & FNONBLOCK) {
|
||||
|
@ -294,6 +326,7 @@ rnd_read(struct file * fp, off_t *offp, struct uio *uio,
|
|||
}
|
||||
goto out;
|
||||
}
|
||||
/* KASSERT(!mutex_owned(&cprng->reseed.mtx)); */
|
||||
ret = uiomove((void *)bf, nread, uio);
|
||||
if (ret != 0 || n < want) {
|
||||
goto out;
|
||||
|
@ -302,9 +335,10 @@ rnd_read(struct file * fp, off_t *offp, struct uio *uio,
|
|||
out:
|
||||
if (ctx->bytesonkey >= strength) {
|
||||
/* Force reseed of underlying DRBG (prediction resistance) */
|
||||
cprng_strong_deplete(ctx->cprng);
|
||||
cprng_strong_deplete(cprng);
|
||||
ctx->bytesonkey = 0;
|
||||
}
|
||||
|
||||
pool_cache_put(rp_pc, bf);
|
||||
return (ret);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_rndpool.c,v 1.1 2012/02/02 19:43:07 tls Exp $ */
|
||||
/* $NetBSD: kern_rndpool.c,v 1.2 2012/04/17 02:50:38 tls Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_rndpool.c,v 1.1 2012/02/02 19:43:07 tls Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_rndpool.c,v 1.2 2012/04/17 02:50:38 tls Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -52,7 +52,8 @@ __KERNEL_RCSID(0, "$NetBSD: kern_rndpool.c,v 1.1 2012/02/02 19:43:07 tls Exp $")
|
|||
/*
|
||||
* Let others know: the pool is full.
|
||||
*/
|
||||
int rnd_full;
|
||||
int rnd_full = 0; /* Flag: is the pool full? */
|
||||
int rnd_filled = 0; /* Count: how many times filled? */
|
||||
|
||||
static inline void rndpool_add_one_word(rndpool_t *, u_int32_t);
|
||||
|
||||
|
@ -216,6 +217,7 @@ rndpool_add_data(rndpool_t *rp, void *p, u_int32_t len, u_int32_t entropy)
|
|||
if (rp->stats.curentropy > RND_POOLBITS) {
|
||||
rp->stats.discarded += (rp->stats.curentropy - RND_POOLBITS);
|
||||
rp->stats.curentropy = RND_POOLBITS;
|
||||
rnd_filled++;
|
||||
rnd_full = 1;
|
||||
}
|
||||
}
|
||||
|
@ -246,7 +248,9 @@ rndpool_extract_data(rndpool_t *rp, void *p, u_int32_t len, u_int32_t mode)
|
|||
buf = p;
|
||||
remain = len;
|
||||
|
||||
rnd_full = 0;
|
||||
if (rp->stats.curentropy < RND_POOLBITS / 2) {
|
||||
rnd_full = 0;
|
||||
}
|
||||
|
||||
if (mode == RND_EXTRACT_ANY)
|
||||
good = 1;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_rndq.c,v 1.2 2012/04/10 14:02:27 tls Exp $ */
|
||||
/* $NetBSD: kern_rndq.c,v 1.3 2012/04/17 02:50:38 tls Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.2 2012/04/10 14:02:27 tls Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.3 2012/04/17 02:50:38 tls Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
@ -221,6 +221,16 @@ rnd_wakeup_readers(void)
|
|||
*/
|
||||
mutex_spin_enter(&rndsink_mtx);
|
||||
TAILQ_FOREACH_SAFE(sink, &rnd_sinks, tailq, tsink) {
|
||||
if (!mutex_tryenter(&sink->mtx)) {
|
||||
#ifdef RND_VERBOSE
|
||||
printf("rnd_wakeup_readers: "
|
||||
"skipping busy rndsink\n");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
KASSERT(RSTATE_PENDING == sink->state);
|
||||
|
||||
if ((sink->len + RND_ENTROPY_THRESHOLD) * 8 <
|
||||
rndpool_get_entropy_count(&rnd_pool)) {
|
||||
/* We have enough entropy to sink some here. */
|
||||
|
@ -230,13 +240,12 @@ rnd_wakeup_readers(void)
|
|||
panic("could not extract estimated "
|
||||
"entropy from pool");
|
||||
}
|
||||
/* Skip if busy, else mark in-progress */
|
||||
if (!mutex_tryenter(&sink->mtx)) {
|
||||
continue;
|
||||
}
|
||||
sink->state = RSTATE_HASBITS;
|
||||
/* Move this sink to the list of pending callbacks */
|
||||
TAILQ_REMOVE(&rnd_sinks, sink, tailq);
|
||||
TAILQ_INSERT_HEAD(&sunk, sink, tailq);
|
||||
} else {
|
||||
mutex_exit(&sink->mtx);
|
||||
}
|
||||
}
|
||||
mutex_spin_exit(&rndsink_mtx);
|
||||
|
@ -269,6 +278,7 @@ rnd_wakeup_readers(void)
|
|||
" (cb %p, arg %p).\n",
|
||||
(int)sink->len, sink->name, sink->cb, sink->arg);
|
||||
#endif
|
||||
sink->state = RSTATE_HASBITS;
|
||||
sink->cb(sink->arg);
|
||||
TAILQ_REMOVE(&sunk, sink, tailq);
|
||||
mutex_spin_exit(&sink->mtx);
|
||||
|
@ -976,16 +986,19 @@ rndsink_attach(rndsink_t *rs)
|
|||
#endif
|
||||
|
||||
KASSERT(mutex_owned(&rs->mtx));
|
||||
KASSERT(rs->state = RSTATE_PENDING);
|
||||
|
||||
mutex_spin_enter(&rndsink_mtx);
|
||||
TAILQ_INSERT_TAIL(&rnd_sinks, rs, tailq);
|
||||
mutex_spin_exit(&rndsink_mtx);
|
||||
|
||||
mutex_spin_enter(&rnd_mtx);
|
||||
if (rnd_timeout_pending == 0) {
|
||||
rnd_timeout_pending = 1;
|
||||
callout_schedule(&rnd_callout, 1);
|
||||
}
|
||||
mutex_spin_exit(&rnd_mtx);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -995,7 +1008,6 @@ rndsink_detach(rndsink_t *rs)
|
|||
#ifdef RND_VERBOSE
|
||||
printf("rnd: entropy sink \"%s\" no longer wants data.\n", rs->name);
|
||||
#endif
|
||||
|
||||
KASSERT(mutex_owned(&rs->mtx));
|
||||
|
||||
mutex_spin_enter(&rndsink_mtx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: subr_cprng.c,v 1.7 2012/04/10 15:12:40 tls Exp $ */
|
||||
/* $NetBSD: subr_cprng.c,v 1.8 2012/04/17 02:50:39 tls Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
|
@ -46,7 +46,7 @@
|
|||
|
||||
#include <sys/cprng.h>
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.7 2012/04/10 15:12:40 tls Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.8 2012/04/17 02:50:39 tls Exp $");
|
||||
|
||||
void
|
||||
cprng_init(void)
|
||||
|
@ -71,42 +71,83 @@ cprng_counter(void)
|
|||
return (tv.tv_sec * 1000000 + tv.tv_usec);
|
||||
}
|
||||
|
||||
static void
|
||||
cprng_strong_doreseed(cprng_strong_t *const c)
|
||||
{
|
||||
uint32_t cc = cprng_counter();
|
||||
|
||||
KASSERT(mutex_owned(&c->mtx));
|
||||
KASSERT(mutex_owned(&c->reseed.mtx));
|
||||
KASSERT(c->reseed.len == NIST_BLOCK_KEYLEN_BYTES);
|
||||
|
||||
if (nist_ctr_drbg_reseed(&c->drbg, c->reseed.data, c->reseed.len,
|
||||
&cc, sizeof(cc))) {
|
||||
panic("cprng %s: nist_ctr_drbg_reseed failed.", c->name);
|
||||
}
|
||||
#ifdef RND_VERBOSE
|
||||
printf("cprng %s: reseeded with rnd_filled = %d\n", c->name,
|
||||
rnd_filled);
|
||||
#endif
|
||||
c->entropy_serial = rnd_filled;
|
||||
c->reseed.state = RSTATE_IDLE;
|
||||
if (c->flags & CPRNG_USE_CV) {
|
||||
cv_broadcast(&c->cv);
|
||||
}
|
||||
selnotify(&c->selq, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cprng_strong_sched_reseed(cprng_strong_t *const c)
|
||||
{
|
||||
KASSERT(mutex_owned(&c->mtx));
|
||||
if (!(c->reseed_pending) && mutex_tryenter(&c->reseed.mtx)) {
|
||||
c->reseed_pending = 1;
|
||||
c->reseed.len = NIST_BLOCK_KEYLEN_BYTES;
|
||||
rndsink_attach(&c->reseed);
|
||||
if (mutex_tryenter(&c->reseed.mtx)) {
|
||||
switch (c->reseed.state) {
|
||||
case RSTATE_IDLE:
|
||||
c->reseed.state = RSTATE_PENDING;
|
||||
c->reseed.len = NIST_BLOCK_KEYLEN_BYTES;
|
||||
rndsink_attach(&c->reseed);
|
||||
break;
|
||||
case RSTATE_HASBITS:
|
||||
/* Just rekey the underlying generator now. */
|
||||
cprng_strong_doreseed(c);
|
||||
break;
|
||||
case RSTATE_PENDING:
|
||||
if (c->entropy_serial != rnd_filled) {
|
||||
rndsink_detach(&c->reseed);
|
||||
rndsink_attach(&c->reseed);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
panic("cprng %s: bad reseed state %d",
|
||||
c->name, c->reseed.state);
|
||||
break;
|
||||
}
|
||||
mutex_spin_exit(&c->reseed.mtx);
|
||||
}
|
||||
#ifdef RND_VERBOSE
|
||||
else {
|
||||
printf("cprng %s: skipping sched_reseed, sink busy\n",
|
||||
c->name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
cprng_strong_reseed(void *const arg)
|
||||
{
|
||||
cprng_strong_t *c = arg;
|
||||
uint8_t key[NIST_BLOCK_KEYLEN_BYTES];
|
||||
uint32_t cc = cprng_counter();
|
||||
|
||||
KASSERT(mutex_owned(&c->reseed.mtx));
|
||||
KASSERT(RSTATE_HASBITS == c->reseed.state);
|
||||
|
||||
if (!mutex_tryenter(&c->mtx)) {
|
||||
#ifdef RND_VERBOSE
|
||||
printf("cprng: sink %s cprng busy, no reseed\n", c->reseed.name);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (c->reseed.len != sizeof(key)) {
|
||||
panic("cprng_strong_reseed: bad entropy length %d "
|
||||
" (expected %d)", (int)c->reseed.len, (int)sizeof(key));
|
||||
}
|
||||
if (nist_ctr_drbg_reseed(&c->drbg, c->reseed.data, c->reseed.len,
|
||||
&cc, sizeof(cc))) {
|
||||
panic("cprng %s: nist_ctr_drbg_reseed failed.", c->name);
|
||||
}
|
||||
c->reseed_pending = 0;
|
||||
if (c->flags & CPRNG_USE_CV) {
|
||||
cv_broadcast(&c->cv);
|
||||
}
|
||||
selnotify(&c->selq, 0, 0);
|
||||
cprng_strong_doreseed(c);
|
||||
mutex_exit(&c->mtx);
|
||||
}
|
||||
|
||||
|
@ -124,9 +165,10 @@ cprng_strong_create(const char *const name, int ipl, int flags)
|
|||
}
|
||||
c->flags = flags;
|
||||
strlcpy(c->name, name, sizeof(c->name));
|
||||
c->reseed_pending = 0;
|
||||
c->reseed.state = RSTATE_IDLE;
|
||||
c->reseed.cb = cprng_strong_reseed;
|
||||
c->reseed.arg = c;
|
||||
c->entropy_serial = rnd_filled;
|
||||
mutex_init(&c->reseed.mtx, MUTEX_DEFAULT, IPL_VM);
|
||||
strlcpy(c->reseed.name, name, sizeof(c->reseed.name));
|
||||
|
||||
|
@ -253,15 +295,15 @@ cprng_strong(cprng_strong_t *const c, void *const p, size_t len, int flags)
|
|||
if (__predict_false(c->drbg.reseed_counter >
|
||||
(NIST_CTR_DRBG_RESEED_INTERVAL / 2))) {
|
||||
cprng_strong_sched_reseed(c);
|
||||
}
|
||||
|
||||
if (rnd_full) {
|
||||
if (!c->rekeyed_on_full) {
|
||||
c->rekeyed_on_full++;
|
||||
} else if (rnd_full) {
|
||||
if (c->entropy_serial != rnd_filled) {
|
||||
#ifdef RND_VERBOSE
|
||||
printf("cprng %s: reseeding from full pool "
|
||||
"(serial %d vs pool %d)\n", c->name,
|
||||
c->entropy_serial, rnd_filled);
|
||||
#endif
|
||||
cprng_strong_sched_reseed(c);
|
||||
}
|
||||
} else {
|
||||
c->rekeyed_on_full = 0;
|
||||
}
|
||||
|
||||
mutex_exit(&c->mtx);
|
||||
|
@ -280,7 +322,7 @@ cprng_strong_destroy(cprng_strong_t *c)
|
|||
}
|
||||
seldestroy(&c->selq);
|
||||
|
||||
if (c->reseed_pending) {
|
||||
if (RSTATE_PENDING == c->reseed.state) {
|
||||
rndsink_detach(&c->reseed);
|
||||
}
|
||||
mutex_spin_exit(&c->reseed.mtx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cprng.h,v 1.4 2011/12/17 20:05:40 tls Exp $ */
|
||||
/* $NetBSD: cprng.h,v 1.5 2012/04/17 02:50:39 tls Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
|
@ -85,7 +85,7 @@ typedef struct _cprng_strong {
|
|||
int flags;
|
||||
char name[16];
|
||||
int reseed_pending;
|
||||
int rekeyed_on_full;
|
||||
int entropy_serial;
|
||||
rndsink_t reseed;
|
||||
} cprng_strong_t;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rnd.h,v 1.30 2012/04/10 14:02:28 tls Exp $ */
|
||||
/* $NetBSD: rnd.h,v 1.31 2012/04/17 02:50:39 tls Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
|
@ -127,9 +127,16 @@ typedef struct krndsource {
|
|||
rngtest_t *test; /* test data for RNG type sources */
|
||||
} krndsource_t;
|
||||
|
||||
enum rsink_st {
|
||||
RSTATE_IDLE = 0,
|
||||
RSTATE_PENDING,
|
||||
RSTATE_HASBITS
|
||||
};
|
||||
|
||||
typedef struct rndsink {
|
||||
TAILQ_ENTRY(rndsink) tailq; /* the queue */
|
||||
kmutex_t mtx; /* lock to seed or unregister */
|
||||
enum rsink_st state; /* in-use? filled? */
|
||||
void (*cb)(void *); /* callback function when ready */
|
||||
void *arg; /* callback function argument */
|
||||
char name[16]; /* sink name */
|
||||
|
@ -178,6 +185,7 @@ rnd_add_uint32(krndsource_t *kr, uint32_t val)
|
|||
}
|
||||
|
||||
extern int rnd_full;
|
||||
extern int rnd_filled;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
|
Loading…
Reference in New Issue