Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Rework rndsink(9) abstraction and adapt arc4random(9) and cp...



details:   https://anonhg.NetBSD.org/src/rev/3c1ccd884280
branches:  trunk
changeset: 787545:3c1ccd884280
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Jun 23 02:35:23 2013 +0000

description:
Rework rndsink(9) abstraction and adapt arc4random(9) and cprng(9).

rndsink(9):
- Simplify API.
- Simplify locking scheme.
- Add a man page.
- Avoid races in destruction.
- Avoid races in requesting entropy now and scheduling entropy later.

Periodic distribution of entropy to sinks reduces the need for the
last one, but this way we don't need to rely on periodic distribution
(e.g., in a future tickless NetBSD).

rndsinks_lock should probably eventually merge with the rndpool lock,
but we'll put that off for now.

cprng(9):
- Make struct cprng_strong opaque.
- Move rndpseudo.c parts that futz with cprng guts to subr_cprng.c.
- Fix kevent locking.  (Is kevent locking documented anywhere?)
- Stub out rump cprng further until we can rumpify rndsink instead.
- Strip code to grovel through struct cprng_strong in fstat.

diffstat:

 share/man/man9/rndsink.9                    |  147 +++++
 sys/conf/files                              |    3 +-
 sys/dev/rndpseudo.c                         |   65 +--
 sys/kern/kern_rndq.c                        |  133 +----
 sys/kern/kern_rndsink.c                     |  321 +++++++++++++
 sys/kern/subr_cprng.c                       |  687 +++++++++++++++------------
 sys/lib/libkern/arc4random.c                |  249 +++------
 sys/rump/librump/rumpkern/Makefile.rumpkern |    3 +-
 sys/rump/librump/rumpkern/cprng_stub.c      |   71 +-
 sys/sys/cprng.h                             |   82 +--
 sys/sys/rnd.h                               |   24 +-
 sys/sys/rndsink.h                           |   53 ++
 usr.bin/fstat/misc.c                        |   22 +-
 13 files changed, 1087 insertions(+), 773 deletions(-)

diffs (truncated from 2322 to 300 lines):

diff -r 2d4869430ae1 -r 3c1ccd884280 share/man/man9/rndsink.9
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/share/man/man9/rndsink.9  Sun Jun 23 02:35:23 2013 +0000
@@ -0,0 +1,147 @@
+.\"    $NetBSD: rndsink.9,v 1.1 2013/06/23 02:35:23 riastradh Exp $
+.\"
+.\" Copyright (c) 2013 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This documentation is derived from text contributed to The NetBSD
+.\" Foundation by Taylor R. Campbell.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd April 10, 2013
+.Dt RNDSINK 9
+.Os
+.Sh NAME
+.Nm rndsink ,
+.Nm rndsink_create ,
+.Nm rndsink_destroy ,
+.Nm rndsink_request ,
+.Nm rndsink_schedule ,
+.Nd functions to asynchronously request entropy from the system entropy pool
+.Sh SYNOPSIS
+.In sys/rndsink.h
+.Ft struct rndsink *
+.Fn rndsink_create "size_t bytes" "void (*callback)(void *, const void *, size_t)" "void *arg"
+.Ft void
+.Fn rndsink_destroy "struct rndsink *rndsink"
+.Ft bool
+.Fn rndsink_request "struct rndsink *rndsink" "void *buffer" "size_t bytes"
+.Ft void
+.Fn rndsink_schedule "struct rndsink *rndsink"
+.Sh DESCRIPTION
+The
+.Nm
+functions support asynchronous requests for entropy from the system
+entropy pool.
+Users must call
+.Fn rndsink_create
+to create an rndsink which they may then pass to
+.Fn rndsink_request
+to request data from the system entropy pool.
+If full entropy is not available, the system will call a callback when
+entropy is next available.
+Users can schedule a callback without requesting data now using
+.Fn rndsink_schedule .
+When users no longer need an rndsink, they must pass it to
+.Fn rndsink_destroy .
+.Pp
+This API provides direct access to the system entropy pool.
+Most users should use the
+.Xr cprng 9
+API instead, which interposes a cryptographic pseudorandom number
+generator between the user and the entropy pool.
+.Sh FUNCTIONS
+.Bl -tag -width abcd
+.It Fn rndsink_create bytes callback arg
+Create an rndsink for requests of
+.Fa bytes
+bytes of entropy, which must be no more than
+.Dv RNDSINK_MAX_BYTES .
+When requested and enough entropy is available, the system will call
+.Fa callback
+with three arguments:
+.Bl -item -offset indent
+.It
+.Fa arg ,
+an arbitrary user-supplied pointer;
+.It
+a pointer to a buffer containing the bytes of entropy; and
+.It
+the number of bytes in the buffer, which will always be
+.Fa bytes .
+.El
+.Pp
+The callback will be called in soft interrupt context.
+.Pp
+.Fn rndsink_create
+may sleep to allocate memory.
+.It Fn rndsink_destroy rndsink
+Destroy an rndsink.
+.Fn rndsink_destroy
+may sleep to wait for pending callbacks to complete and to deallocate
+memory.
+.It Fn rndsink_request rndsink buffer bytes
+Store
+.Fa bytes
+bytes derived from the system entropy pool in
+.Fa buffer .
+If the bytes have full entropy, return true.
+Otherwise, schedule a callback as if with
+.Fn rndsink_schedule
+and return false.
+In either case,
+.Fn rndsink_request
+will store data in
+.Fa buffer .
+The argument
+.Fa bytes
+must be the same as the argument to
+.Fn rndsink_create
+that was used to create
+.Fa rndsink .
+May be called at
+.Dv IPL_VM
+or lower.
+The caller should use
+.Xr explicit_bzero 3
+to clear
+.Fa buffer
+once it has used the data stored there.
+.It Fn rndsink_schedule rndsink
+Schedule a callback when the system entropy pool has enough entropy.
+If a callback is already scheduled, it remains scheduled.
+May be called at
+.Dv IPL_VM
+or lower.
+.El
+.Sh CODE REFERENCES
+The rndsink API is implemented in
+.Pa sys/kern/kern_rndsink.c
+and
+.Pa sys/sys/rndsink.h .
+.Sh SEE ALSO
+.Xr explicit_bzero 3 ,
+.Xr cprng 9 ,
+.Xr rnd 9
+.Sh HISTORY
+The rndsink API first appeared in
+.Nx 7.0 .
diff -r 2d4869430ae1 -r 3c1ccd884280 sys/conf/files
--- a/sys/conf/files    Sun Jun 23 02:07:04 2013 +0000
+++ b/sys/conf/files    Sun Jun 23 02:35:23 2013 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files,v 1.1073 2013/06/10 20:28:36 christos Exp $
+#      $NetBSD: files,v 1.1074 2013/06/23 02:35:24 riastradh Exp $
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
 
 version        20100430
@@ -1524,6 +1524,7 @@
 file   kern/kern_resource.c
 file   kern/kern_rndpool.c
 file   kern/kern_rndq.c
+file   kern/kern_rndsink.c
 file   kern/kern_runq.c
 file   kern/kern_rwlock.c
 file   kern/kern_rwlock_obj.c
diff -r 2d4869430ae1 -r 3c1ccd884280 sys/dev/rndpseudo.c
--- a/sys/dev/rndpseudo.c       Sun Jun 23 02:07:04 2013 +0000
+++ b/sys/dev/rndpseudo.c       Sun Jun 23 02:35:23 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rndpseudo.c,v 1.12 2013/06/13 00:55:01 tls Exp $       */
+/*     $NetBSD: rndpseudo.c,v 1.13 2013/06/23 02:35:24 riastradh 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.12 2013/06/13 00:55:01 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.13 2013/06/23 02:35:24 riastradh Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -679,12 +679,10 @@
                }       
        }
 
-       if (cprng_strong_ready(ctx->cprng)) {
-               revents |= events & (POLLIN | POLLRDNORM);
+       if (ctx->hard) {
+               revents |= cprng_strong_poll(ctx->cprng, events);
        } else {
-               mutex_enter(&ctx->cprng->mtx);
-               selrecord(curlwp, &ctx->cprng->selq);
-               mutex_exit(&ctx->cprng->mtx);
+               revents |= (events & (POLLIN | POLLRDNORM));
        }
 
        return (revents);
@@ -723,39 +721,10 @@
        return 0;
 }
 
-static void
-filt_rnddetach(struct knote *kn)
-{
-       cprng_strong_t *c = kn->kn_hook;
-
-       mutex_enter(&c->mtx);
-       SLIST_REMOVE(&c->selq.sel_klist, kn, knote, kn_selnext);
-       mutex_exit(&c->mtx);
-}
-
-static int
-filt_rndread(struct knote *kn, long hint)
-{
-       cprng_strong_t *c = kn->kn_hook;
-
-       if (cprng_strong_ready(c)) {
-               kn->kn_data = RND_TEMP_BUFFER_SIZE;
-               return 1;
-       }
-       return 0;
-}
-
-static const struct filterops rnd_seltrue_filtops =
-       { 1, NULL, filt_rnddetach, filt_seltrue };
-
-static const struct filterops rndread_filtops =
-       { 1, NULL, filt_rnddetach, filt_rndread };
-
 static int
 rnd_kqfilter(struct file *fp, struct knote *kn)
 {
        rp_ctx_t *ctx = fp->f_data;
-       struct klist *klist;
 
        if (ctx->cprng == NULL) {
                rnd_alloc_cprng(ctx);
@@ -764,27 +733,5 @@
                }
        }
 
-       mutex_enter(&ctx->cprng->mtx);
-       switch (kn->kn_filter) {
-       case EVFILT_READ:
-               klist = &ctx->cprng->selq.sel_klist;
-               kn->kn_fop = &rndread_filtops;
-               break;
-
-       case EVFILT_WRITE:
-               klist = &ctx->cprng->selq.sel_klist;
-               kn->kn_fop = &rnd_seltrue_filtops;
-               break;
-
-       default:
-               mutex_exit(&ctx->cprng->mtx);
-               return EINVAL;
-       }
-
-       kn->kn_hook = ctx->cprng;
-
-       SLIST_INSERT_HEAD(klist, kn, kn_selnext);
-
-       mutex_exit(&ctx->cprng->mtx);
-       return (0);
+       return cprng_strong_kqfilter(ctx->cprng, kn);
 }
diff -r 2d4869430ae1 -r 3c1ccd884280 sys/kern/kern_rndq.c
--- a/sys/kern/kern_rndq.c      Sun Jun 23 02:07:04 2013 +0000
+++ b/sys/kern/kern_rndq.c      Sun Jun 23 02:35:23 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_rndq.c,v 1.13 2013/06/20 23:21:41 christos Exp $  */
+/*     $NetBSD: kern_rndq.c,v 1.14 2013/06/23 02:35:24 riastradh Exp $ */
 
 /*-
  * Copyright (c) 1997-2013 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.13 2013/06/20 23:21:41 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.14 2013/06/23 02:35:24 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -48,6 +48,7 @@
 #include <sys/callout.h>
 #include <sys/intr.h>
 #include <sys/rnd.h>
+#include <sys/rndsink.h>
 #include <sys/vnode.h>
 #include <sys/pool.h>
 #include <sys/kauth.h>
@@ -104,17 +105,6 @@
 kmutex_t                       rnd_mtx;
 



Home | Main Index | Thread Index | Old Index