Module Name: src Committed By: riastradh Date: Mon Jul 1 15:22:00 UTC 2013
Modified Files: src/sys/dev: rndpseudo.c src/sys/kern: subr_cprng.c src/sys/sys: cprng.h rnd.h src/usr.bin/fstat: misc.c Log Message: Fix races in /dev/u?random initialization and accounting. - Push /dev/random `information-theoretic' accounting into cprng(9). - Use percpu(9) for the per-CPU CPRNGs. - Use atomics with correct memory barriers for lazy CPRNG creation. - Remove /dev/random file kmem grovelling from fstat(1). To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/sys/dev/rndpseudo.c cvs rdiff -u -r1.20 -r1.21 src/sys/kern/subr_cprng.c cvs rdiff -u -r1.7 -r1.8 src/sys/sys/cprng.h cvs rdiff -u -r1.38 -r1.39 src/sys/sys/rnd.h cvs rdiff -u -r1.12 -r1.13 src/usr.bin/fstat/misc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/rndpseudo.c diff -u src/sys/dev/rndpseudo.c:1.13 src/sys/dev/rndpseudo.c:1.14 --- src/sys/dev/rndpseudo.c:1.13 Sun Jun 23 02:35:24 2013 +++ src/sys/dev/rndpseudo.c Mon Jul 1 15:22:00 2013 @@ -1,11 +1,12 @@ -/* $NetBSD: rndpseudo.c,v 1.13 2013/06/23 02:35:24 riastradh Exp $ */ +/* $NetBSD: rndpseudo.c,v 1.14 2013/07/01 15:22:00 riastradh Exp $ */ /*- - * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. + * Copyright (c) 1997-2013 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation - * by Michael Graff <explo...@flame.org> and Thor Lancelot Simon. + * by Michael Graff <explo...@flame.org>, Thor Lancelot Simon, and + * Taylor R. Campbell. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.13 2013/06/23 02:35:24 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.14 2013/07/01 15:22:00 riastradh Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -56,6 +57,7 @@ __KERNEL_RCSID(0, "$NetBSD: rndpseudo.c, #include <sys/cprng.h> #include <sys/cpu.h> #include <sys/stat.h> +#include <sys/percpu.h> #include <sys/rnd.h> #ifdef COMPAT_50 @@ -88,18 +90,26 @@ extern int rnd_debug; #endif /* - * The size of a temporary buffer, kmem_alloc()ed when needed, and used for - * reading and writing data. + * The size of a temporary buffer for reading and writing entropy. */ #define RND_TEMP_BUFFER_SIZE 512 -static pool_cache_t rp_pc; -static pool_cache_t rp_cpc; +static pool_cache_t rnd_temp_buffer_cache; + +/* + * Per-open state -- a lazily initialized CPRNG. + */ +struct rnd_ctx { + struct cprng_strong *rc_cprng; + bool rc_hard; +}; + +static pool_cache_t rnd_ctx_cache; /* * The per-CPU RNGs used for short requests */ -cprng_strong_t **rp_cpurngs; +static percpu_t *percpu_urandom_cprng; /* * Our random pool. This is defined here rather than using the general @@ -164,190 +174,223 @@ rndpseudo_counter(void) } /* - * "Attach" the random device. This is an (almost) empty stub, since - * pseudo-devices don't get attached until after config, after the - * entropy sources will attach. We just use the timing of this event - * as another potential source of initial entropy. + * `Attach' the random device. We use the timing of this event as + * another potential source of initial entropy. */ void rndattach(int num) { - u_int32_t c; + uint32_t c; - /* Trap unwary players who don't call rnd_init() early */ + /* Trap unwary players who don't call rnd_init() early. */ KASSERT(rnd_ready); - rp_pc = pool_cache_init(RND_TEMP_BUFFER_SIZE, 0, 0, 0, - "rndtemp", NULL, IPL_NONE, - NULL, NULL, NULL); - rp_cpc = pool_cache_init(sizeof(rp_ctx_t), 0, 0, 0, - "rndctx", NULL, IPL_NONE, - NULL, NULL, NULL); + rnd_temp_buffer_cache = pool_cache_init(RND_TEMP_BUFFER_SIZE, 0, 0, 0, + "rndtemp", NULL, IPL_NONE, NULL, NULL, NULL); + rnd_ctx_cache = pool_cache_init(sizeof(struct rnd_ctx), 0, 0, 0, + "rndctx", NULL, IPL_NONE, NULL, NULL, NULL); + percpu_urandom_cprng = percpu_alloc(sizeof(struct cprng_strong *)); - /* mix in another counter */ + /* Mix in another counter. */ c = rndpseudo_counter(); mutex_spin_enter(&rndpool_mtx); - rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1); + rndpool_add_data(&rnd_pool, &c, sizeof(c), 1); mutex_spin_exit(&rndpool_mtx); - - rp_cpurngs = kmem_zalloc(maxcpus * sizeof(cprng_strong_t *), - KM_SLEEP); } int -rndopen(dev_t dev, int flag, int ifmt, - struct lwp *l) +rndopen(dev_t dev, int flags, int fmt, struct lwp *l) { - rp_ctx_t *ctx; - file_t *fp; - int fd, hard, error = 0; + bool hard; + struct file *fp; + int fd; + int error; switch (minor(dev)) { - case RND_DEV_URANDOM: - hard = 0; + case RND_DEV_URANDOM: + hard = false; break; - case RND_DEV_RANDOM: - hard = 1; + + case RND_DEV_RANDOM: + hard = true; break; - default: + + default: return ENXIO; } - ctx = pool_cache_get(rp_cpc, PR_WAITOK); - if ((error = fd_allocfile(&fp, &fd)) != 0) { - pool_cache_put(rp_cpc, ctx); - return error; - } - ctx->cprng = NULL; - ctx->hard = hard; - ctx->bytesonkey = 0; - mutex_init(&ctx->interlock, MUTEX_DEFAULT, IPL_NONE); - return fd_clone(fp, fd, flag, &rnd_fileops, ctx); + error = fd_allocfile(&fp, &fd); + if (error) + return error; + + /* + * Allocate a context, but don't create a CPRNG yet -- do that + * lazily because it consumes entropy from the system entropy + * pool, which (currently) has the effect of depleting it and + * causing readers from /dev/random to block. If this is + * /dev/urandom and the process is about to send only short + * reads to it, then we will be using a per-CPU CPRNG anyway. + */ + struct rnd_ctx *const ctx = pool_cache_get(rnd_ctx_cache, PR_WAITOK); + ctx->rc_cprng = NULL; + ctx->rc_hard = hard; + + error = fd_clone(fp, fd, flags, &rnd_fileops, ctx); + KASSERT(error == EMOVEFD); + + return error; } -static void -rnd_alloc_cprng(rp_ctx_t *ctx) +/* + * Fetch a /dev/u?random context's CPRNG, or create and save one if + * necessary. + */ +static struct cprng_strong * +rnd_ctx_cprng(struct rnd_ctx *ctx) { - char personalization_buf[64]; - struct lwp *l = curlwp; - int cflags = ctx->hard ? CPRNG_USE_CV : - CPRNG_INIT_ANY|CPRNG_REKEY_ANY; - - mutex_enter(&ctx->interlock); - if (__predict_true(ctx->cprng == NULL)) { - snprintf(personalization_buf, - sizeof(personalization_buf), - "%d%llud%d", l->l_proc->p_pid, - (unsigned long long int)l->l_ncsw, l->l_cpticks); - ctx->cprng = cprng_strong_create(personalization_buf, - IPL_NONE, cflags); - } - membar_sync(); - mutex_exit(&ctx->interlock); + struct cprng_strong *cprng, *tmp = NULL; + + /* Fast path: if someone has already allocated a CPRNG, use it. */ + cprng = ctx->rc_cprng; + if (__predict_true(cprng != NULL)) { + /* Make sure the CPU hasn't prefetched cprng's guts. */ + membar_consumer(); + goto out; + } + + /* Slow path: create a CPRNG. Allocate before taking locks. */ + char name[64]; + struct lwp *const l = curlwp; + (void)snprintf(name, sizeof(name), "%d %"PRIu64" %u", + (int)l->l_proc->p_pid, l->l_ncsw, l->l_cpticks); + const int flags = (ctx->rc_hard? (CPRNG_USE_CV | CPRNG_HARD) : + (CPRNG_INIT_ANY | CPRNG_REKEY_ANY)); + tmp = cprng_strong_create(name, IPL_NONE, flags); + + /* Publish cprng's guts before the pointer to them. */ + membar_producer(); + + /* Attempt to publish tmp, unless someone beat us. */ + cprng = atomic_cas_ptr(&ctx->rc_cprng, NULL, tmp); + if (__predict_false(cprng != NULL)) { + /* Make sure the CPU hasn't prefetched cprng's guts. */ + membar_consumer(); + goto out; + } + + /* Published. Commit tmp. */ + cprng = tmp; + tmp = NULL; + +out: if (tmp != NULL) + cprng_strong_destroy(tmp); + KASSERT(cprng != NULL); + return cprng; +} + +/* + * Fetch a per-CPU CPRNG, or create and save one if necessary. + */ +static struct cprng_strong * +rnd_percpu_cprng(void) +{ + struct cprng_strong **cprngp, *cprng, *tmp; + + /* Fast path: if there already is a CPRNG for this CPU, use it. */ + cprngp = percpu_getref(percpu_urandom_cprng); + cprng = *cprngp; + if (__predict_true(cprng != NULL)) + goto out; + percpu_putref(percpu_urandom_cprng); + + /* + * Slow path: create a CPRNG named by this CPU. + * + * XXX The CPU of the name may be different from the CPU to + * which it is assigned, because we need to choose a name and + * allocate a cprng while preemption is enabled. This could be + * fixed by changing the cprng_strong API (e.g., by adding a + * cprng_strong_setname or by separating allocation from + * initialization), but it's not clear that's worth the + * trouble. + */ + char name[32]; + (void)snprintf(name, sizeof(name), "urandom%u", cpu_index(curcpu())); + tmp = cprng_strong_create(name, IPL_NONE, + (CPRNG_INIT_ANY | CPRNG_REKEY_ANY)); + + /* Try again, but we may have been preempted and lost a race. */ + cprngp = percpu_getref(percpu_urandom_cprng); + cprng = *cprngp; + if (__predict_false(cprng != NULL)) + goto out; + + /* Commit the CPRNG we just created. */ + cprng = tmp; + tmp = NULL; + *cprngp = cprng; + +out: percpu_putref(percpu_urandom_cprng); + if (tmp != NULL) + cprng_strong_destroy(tmp); + KASSERT(cprng != NULL); + return cprng; } static int -rnd_read(struct file * fp, off_t *offp, struct uio *uio, - kauth_cred_t cred, int flags) +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(); + int error; DPRINTF(RND_DEBUG_READ, - ("Random: Read of %zu requested, flags 0x%08x\n", - uio->uio_resid, flags)); + ("Random: Read of %zu requested, flags 0x%08x\n", + uio->uio_resid, flags)); if (uio->uio_resid == 0) - return (0); + return 0; - 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]; - } + struct rnd_ctx *const ctx = fp->f_data; + uint8_t *const buf = pool_cache_get(rnd_temp_buffer_cache, PR_WAITOK); - if (__predict_false(cprng == NULL)) { - printf("NULL rng!\n"); - return EIO; - } + /* + * Choose a CPRNG to use -- either the per-open CPRNG, if this + * is /dev/random or a long read, or the per-CPU one otherwise. + * + * XXX NIST_BLOCK_KEYLEN_BYTES is a detail of the cprng(9) + * implementation and as such should not be mentioned here. + */ + struct cprng_strong *const cprng = + ((ctx->rc_hard || (uio->uio_resid > NIST_BLOCK_KEYLEN_BYTES))? + rnd_ctx_cprng(ctx) : rnd_percpu_cprng()); - strength = cprng_strong_strength(cprng); - ret = 0; - bf = pool_cache_get(rp_pc, PR_WAITOK); + /* + * Generate the data in RND_TEMP_BUFFER_SIZE chunks. + */ while (uio->uio_resid > 0) { - int n, nread, want; - - want = MIN(RND_TEMP_BUFFER_SIZE, uio->uio_resid); - - /* XXX is this _really_ what's wanted? */ - if (ctx->hard) { -#ifdef RND_VERBOSE - printf("rnd: hard, want = %d, strength = %d, " - "bytesonkey = %d\n", (int)want, (int)strength, - (int)ctx->bytesonkey); -#endif - n = MIN(want, strength - ctx->bytesonkey); - if (n < 1) { -#ifdef RND_VERBOSE - printf("rnd: BAD BAD BAD: n = %d, want = %d, " - "strength = %d, bytesonkey = %d\n", n, - (int)want, (int)strength, - (int)ctx->bytesonkey); -#endif - } - } else { - n = want; - } + const size_t n_req = MIN(uio->uio_resid, RND_TEMP_BUFFER_SIZE); - nread = cprng_strong(cprng, bf, n, - (fp->f_flag & FNONBLOCK) ? FNONBLOCK : 0); + CTASSERT(RND_TEMP_BUFFER_SIZE <= CPRNG_MAX_LEN); + const size_t n_read = cprng_strong(cprng, buf, n_req, + ((ctx->rc_hard && ISSET(fp->f_flag, FNONBLOCK))? + FNONBLOCK : 0)); - if (ctx->hard && nread > 0) { - if (atomic_add_int_nv(&ctx->bytesonkey, nread) >= - strength) { - cprng_strong_deplete(cprng); - ctx->bytesonkey = 0; - membar_producer(); - } -#ifdef RND_VERBOSE - printf("rnd: new bytesonkey %d\n", ctx->bytesonkey); -#endif - } - if (nread < 1) { - if (fp->f_flag & FNONBLOCK) { - ret = EWOULDBLOCK; - } else { - ret = EINTR; - } - goto out; - } + /* + * Equality will hold unless this is /dev/random, in + * which case we get only as many bytes as are left + * from the CPRNG's `information-theoretic strength' + * since the last rekey. + */ + KASSERT(n_read <= n_req); + KASSERT(ctx->rc_hard || (n_read == n_req)); - ret = uiomove((void *)bf, nread, uio); - if (ret != 0 || n < want) { + error = uiomove(buf, n_read, uio); + if (error) goto out; - } } -out: - pool_cache_put(rp_pc, bf); - return (ret); + +out: pool_cache_put(rnd_temp_buffer_cache, buf); + return error; } static int @@ -371,7 +414,7 @@ rnd_write(struct file *fp, off_t *offp, if (uio->uio_resid == 0) return (0); ret = 0; - bf = pool_cache_get(rp_pc, PR_WAITOK); + bf = pool_cache_get(rnd_temp_buffer_cache, PR_WAITOK); while (uio->uio_resid > 0) { /* * Don't flood the pool. @@ -418,7 +461,7 @@ rnd_write(struct file *fp, off_t *offp, added += n; DPRINTF(RND_DEBUG_WRITE, ("Random: Copied in %d bytes\n", n)); } - pool_cache_put(rp_pc, bf); + pool_cache_put(rnd_temp_buffer_cache, bf); return (ret); } @@ -658,8 +701,8 @@ rnd_ioctl(struct file *fp, u_long cmd, v static int rnd_poll(struct file *fp, int events) { + struct rnd_ctx *const ctx = fp->f_data; int revents; - rp_ctx_t *ctx = fp->f_data; /* * We are always writable. @@ -670,34 +713,29 @@ rnd_poll(struct file *fp, int events) * Save some work if not checking for reads. */ if ((events & (POLLIN | POLLRDNORM)) == 0) - return (revents); + return revents; - if (ctx->cprng == NULL) { - rnd_alloc_cprng(ctx); - if (__predict_false(ctx->cprng == NULL)) { - return EIO; - } - } - - if (ctx->hard) { - revents |= cprng_strong_poll(ctx->cprng, events); - } else { + /* + * For /dev/random, ask the CPRNG, which may require creating + * one. For /dev/urandom, we're always readable. + */ + if (ctx->rc_hard) + revents |= cprng_strong_poll(rnd_ctx_cprng(ctx), events); + else revents |= (events & (POLLIN | POLLRDNORM)); - } - return (revents); + return revents; } static int rnd_stat(struct file *fp, struct stat *st) { - rp_ctx_t *ctx = fp->f_data; + struct rnd_ctx *const ctx = fp->f_data; /* XXX lock, if cprng allocated? why? */ memset(st, 0, sizeof(*st)); st->st_dev = makedev(cdevsw_lookup_major(&rnd_cdevsw), - ctx->hard ? RND_DEV_RANDOM : - RND_DEV_URANDOM); + (ctx->rc_hard? RND_DEV_RANDOM : RND_DEV_URANDOM)); /* XXX leave atimespect, mtimespec, ctimespec = 0? */ st->st_uid = kauth_cred_geteuid(fp->f_cred); @@ -709,14 +747,12 @@ rnd_stat(struct file *fp, struct stat *s static int rnd_close(struct file *fp) { - rp_ctx_t *ctx = fp->f_data; + struct rnd_ctx *const ctx = fp->f_data; - if (ctx->cprng) { - cprng_strong_destroy(ctx->cprng); - } + if (ctx->rc_cprng != NULL) + cprng_strong_destroy(ctx->rc_cprng); fp->f_data = NULL; - mutex_destroy(&ctx->interlock); - pool_cache_put(rp_cpc, ctx); + pool_cache_put(rnd_ctx_cache, ctx); return 0; } @@ -724,14 +760,7 @@ rnd_close(struct file *fp) static int rnd_kqfilter(struct file *fp, struct knote *kn) { - rp_ctx_t *ctx = fp->f_data; - - if (ctx->cprng == NULL) { - rnd_alloc_cprng(ctx); - if (__predict_false(ctx->cprng == NULL)) { - return EIO; - } - } + struct rnd_ctx *const ctx = fp->f_data; - return cprng_strong_kqfilter(ctx->cprng, kn); + return cprng_strong_kqfilter(rnd_ctx_cprng(ctx), kn); } Index: src/sys/kern/subr_cprng.c diff -u src/sys/kern/subr_cprng.c:1.20 src/sys/kern/subr_cprng.c:1.21 --- src/sys/kern/subr_cprng.c:1.20 Mon Jun 24 04:21:20 2013 +++ src/sys/kern/subr_cprng.c Mon Jul 1 15:22:00 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_cprng.c,v 1.20 2013/06/24 04:21:20 riastradh Exp $ */ +/* $NetBSD: subr_cprng.c,v 1.21 2013/07/01 15:22:00 riastradh Exp $ */ /*- * Copyright (c) 2011-2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.20 2013/06/24 04:21:20 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.21 2013/07/01 15:22:00 riastradh Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -99,6 +99,9 @@ struct cprng_strong { struct rndsink *cs_rndsink; bool cs_ready; NIST_CTR_DRBG cs_drbg; + + /* XXX Kludge for /dev/random `information-theoretic' properties. */ + unsigned int cs_remaining; }; struct cprng_strong * @@ -134,6 +137,11 @@ cprng_strong_create(const char *name, in cprng->cs_name); explicit_memset(seed, 0, sizeof(seed)); + if (ISSET(flags, CPRNG_HARD)) + cprng->cs_remaining = NIST_BLOCK_KEYLEN_BYTES; + else + cprng->cs_remaining = 0; + if (!cprng->cs_ready && !ISSET(flags, CPRNG_INIT_ANY)) printf("cprng %s: creating with partial entropy\n", cprng->cs_name); @@ -193,6 +201,27 @@ cprng_strong(struct cprng_strong *cprng, } } + /* + * Debit the entropy if requested. + * + * XXX Kludge for /dev/random `information-theoretic' properties. + */ + if (__predict_false(ISSET(cprng->cs_flags, CPRNG_HARD))) { + KASSERT(0 < cprng->cs_remaining); + KASSERT(cprng->cs_remaining <= NIST_BLOCK_KEYLEN_BYTES); + if (bytes < cprng->cs_remaining) { + cprng->cs_remaining -= bytes; + } else { + bytes = cprng->cs_remaining; + cprng->cs_remaining = NIST_BLOCK_KEYLEN_BYTES; + cprng->cs_ready = false; + rndsink_schedule(cprng->cs_rndsink); + } + KASSERT(bytes <= NIST_BLOCK_KEYLEN_BYTES); + KASSERT(0 < cprng->cs_remaining); + KASSERT(cprng->cs_remaining <= NIST_BLOCK_KEYLEN_BYTES); + } + cprng_strong_generate(cprng, buffer, bytes); result = bytes; @@ -280,19 +309,6 @@ cprng_strong_poll(struct cprng_strong *c } /* - * XXX Kludge for the current /dev/random implementation. - */ -void -cprng_strong_deplete(struct cprng_strong *cprng) -{ - - mutex_enter(&cprng->cs_lock); - cprng->cs_ready = false; - rndsink_schedule(cprng->cs_rndsink); - mutex_exit(&cprng->cs_lock); -} - -/* * XXX Move nist_ctr_drbg_reseed_advised_p and * nist_ctr_drbg_reseed_needed_p into the nist_ctr_drbg API and make * the NIST_CTR_DRBG structure opaque. @@ -315,8 +331,7 @@ nist_ctr_drbg_reseed_needed_p(NIST_CTR_D * Generate some data from the underlying generator. */ static void -cprng_strong_generate(struct cprng_strong *cprng, void *buffer, - size_t bytes) +cprng_strong_generate(struct cprng_strong *cprng, void *buffer, size_t bytes) { const uint32_t cc = cprng_counter(); @@ -343,9 +358,6 @@ cprng_strong_generate(struct cprng_stron /* * If we just exhausted the generator, inform the next user * that we need a reseed. - * - * XXX For /dev/random CPRNGs, the criterion is supposed to be - * `Has this seeding generated 32 bytes?'. */ if (__predict_false(nist_ctr_drbg_reseed_needed_p(&cprng->cs_drbg))) { cprng->cs_ready = false; Index: src/sys/sys/cprng.h diff -u src/sys/sys/cprng.h:1.7 src/sys/sys/cprng.h:1.8 --- src/sys/sys/cprng.h:1.7 Sun Jun 23 02:35:24 2013 +++ src/sys/sys/cprng.h Mon Jul 1 15:22:00 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: cprng.h,v 1.7 2013/06/23 02:35:24 riastradh Exp $ */ +/* $NetBSD: cprng.h,v 1.8 2013/07/01 15:22:00 riastradh Exp $ */ /*- * Copyright (c) 2011-2013 The NetBSD Foundation, Inc. @@ -87,10 +87,12 @@ void cprng_init(void); #define CPRNG_INIT_ANY 0x00000001 #define CPRNG_REKEY_ANY 0x00000002 #define CPRNG_USE_CV 0x00000004 +#define CPRNG_HARD 0x00000008 #define CPRNG_FMT "\177\020\ b\0INIT_ANY\0\ b\1REKEY_ANY\0\ -b\2USE_CV\0" +b\2USE_CV\0\ +b\3HARD\0" cprng_strong_t * cprng_strong_create(const char *, int, int); @@ -100,7 +102,6 @@ size_t cprng_strong(cprng_strong_t *, vo struct knote; /* XXX temp, for /dev/random */ int cprng_strong_kqfilter(cprng_strong_t *, struct knote *); /* XXX " */ int cprng_strong_poll(cprng_strong_t *, int); /* XXX " */ -void cprng_strong_deplete(cprng_strong_t *); /* XXX " */ extern cprng_strong_t *kern_cprng; Index: src/sys/sys/rnd.h diff -u src/sys/sys/rnd.h:1.38 src/sys/sys/rnd.h:1.39 --- src/sys/sys/rnd.h:1.38 Sun Jun 23 02:35:24 2013 +++ src/sys/sys/rnd.h Mon Jul 1 15:22:00 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: rnd.h,v 1.38 2013/06/23 02:35:24 riastradh Exp $ */ +/* $NetBSD: rnd.h,v 1.39 2013/07/01 15:22:00 riastradh Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -41,7 +41,6 @@ #include <sys/sha1.h> #ifdef _KERNEL -#include <sys/mutex.h> #include <sys/queue.h> #endif @@ -234,16 +233,4 @@ typedef struct { #define RNDADDDATA _IOW('R', 105, rnddata_t) /* add data to the pool */ #define RNDGETPOOLSTAT _IOR('R', 106, rndpoolstat_t) /* get statistics */ -#ifdef _KERNEL -/* - * A context. cprng plus a smidge. - */ -typedef struct { - struct cprng_strong *cprng; - int hard; - int bytesonkey; - kmutex_t interlock; -} rp_ctx_t; -#endif - #endif /* !_SYS_RND_H_ */ Index: src/usr.bin/fstat/misc.c diff -u src/usr.bin/fstat/misc.c:1.12 src/usr.bin/fstat/misc.c:1.13 --- src/usr.bin/fstat/misc.c:1.12 Sun Jun 23 02:35:24 2013 +++ src/usr.bin/fstat/misc.c Mon Jul 1 15:22:00 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: misc.c,v 1.12 2013/06/23 02:35:24 riastradh Exp $ */ +/* $NetBSD: misc.c,v 1.13 2013/07/01 15:22:00 riastradh Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: misc.c,v 1.12 2013/06/23 02:35:24 riastradh Exp $"); +__RCSID("$NetBSD: misc.c,v 1.13 2013/07/01 15:22:00 riastradh Exp $"); #define _KMEMUSER #include <stdbool.h> @@ -101,8 +101,6 @@ static struct nlist nl[] = { { .n_name = "vnops" }, #define NL_XENEVT 16 { .n_name = "xenevt_fileops" }, -#define NL_RND 17 - { .n_name = "rnd_fileops" }, #define NL_MAX 18 { .n_name = NULL } }; @@ -196,21 +194,6 @@ p_kqueue(struct file *f) return 0; } -static int -p_rnd(struct file *f) -{ - rp_ctx_t rp; - - if (!KVM_READ(f->f_data, &rp, sizeof(rp))) { - dprintf("can't read rnd at %p for pid %d", f->f_data, Pid); - return 0; - } - (void)printf("* rnd"); - if (rp.hard) - printf(" bytesonkey=%d", rp.bytesonkey); - printf("\n"); - return 0; -} int pmisc(struct file *f, const char *name) { @@ -244,8 +227,6 @@ pmisc(struct file *f, const char *name) return p_kqueue(f); case NL_SEM: return p_sem(f); - case NL_RND: - return p_rnd(f); case NL_TAP: printf("* tap %lu\n", (unsigned long)(intptr_t)f->f_data); return 0;