The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/random/randomdev.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2000-2004 Mark R V Murray
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer
   10  *    in this position and unchanged.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  *
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD: releng/8.1/sys/dev/random/randomdev.c 185254 2008-11-24 17:39:39Z cperciva $");
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/bus.h>
   34 #include <sys/conf.h>
   35 #include <sys/fcntl.h>
   36 #include <sys/filio.h>
   37 #include <sys/kernel.h>
   38 #include <sys/kthread.h>
   39 #include <sys/lock.h>
   40 #include <sys/malloc.h>
   41 #include <sys/module.h>
   42 #include <sys/mutex.h>
   43 #include <sys/poll.h>
   44 #include <sys/priv.h>
   45 #include <sys/proc.h>
   46 #include <sys/selinfo.h>
   47 #include <sys/uio.h>
   48 #include <sys/unistd.h>
   49 
   50 #include <machine/bus.h>
   51 #include <machine/cpu.h>
   52 
   53 #include <dev/random/randomdev.h>
   54 
   55 #define RANDOM_MINOR    0
   56 
   57 static d_close_t random_close;
   58 static d_read_t random_read;
   59 static d_write_t random_write;
   60 static d_ioctl_t random_ioctl;
   61 static d_poll_t random_poll;
   62 
   63 static struct cdevsw random_cdevsw = {
   64         .d_version = D_VERSION,
   65         .d_close = random_close,
   66         .d_read = random_read,
   67         .d_write = random_write,
   68         .d_ioctl = random_ioctl,
   69         .d_poll = random_poll,
   70         .d_name = "random",
   71 };
   72 
   73 struct random_systat random_systat;
   74 
   75 /* For use with make_dev(9)/destroy_dev(9). */
   76 static struct cdev *random_dev;
   77 
   78 /* Used to fake out unused random calls in random_systat */
   79 void
   80 random_null_func(void)
   81 {
   82 }
   83 
   84 /* ARGSUSED */
   85 static int
   86 random_close(struct cdev *dev __unused, int flags, int fmt __unused,
   87     struct thread *td)
   88 {
   89         if ((flags & FWRITE) && (priv_check(td, PRIV_RANDOM_RESEED) == 0)
   90             && (securelevel_gt(td->td_ucred, 0) == 0)) {
   91                 (*random_systat.reseed)();
   92                 random_systat.seeded = 1;
   93                 arc4rand(NULL, 0, 1);   /* Reseed arc4random as well. */
   94         }
   95 
   96         return (0);
   97 }
   98 
   99 /* ARGSUSED */
  100 static int
  101 random_read(struct cdev *dev __unused, struct uio *uio, int flag)
  102 {
  103         int c, error = 0;
  104         void *random_buf;
  105 
  106         /* Blocking logic */
  107         if (!random_systat.seeded)
  108                 error = (*random_systat.block)(flag);
  109 
  110         /* The actual read */
  111         if (!error) {
  112 
  113                 random_buf = (void *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
  114 
  115                 while (uio->uio_resid > 0 && !error) {
  116                         c = MIN(uio->uio_resid, PAGE_SIZE);
  117                         c = (*random_systat.read)(random_buf, c);
  118                         error = uiomove(random_buf, c, uio);
  119                 }
  120 
  121                 free(random_buf, M_TEMP);
  122 
  123         }
  124 
  125         return (error);
  126 }
  127 
  128 /* ARGSUSED */
  129 static int
  130 random_write(struct cdev *dev __unused, struct uio *uio, int flag __unused)
  131 {
  132         int c, error = 0;
  133         void *random_buf;
  134 
  135         random_buf = (void *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
  136 
  137         while (uio->uio_resid > 0) {
  138                 c = MIN((int)uio->uio_resid, PAGE_SIZE);
  139                 error = uiomove(random_buf, c, uio);
  140                 if (error)
  141                         break;
  142                 (*random_systat.write)(random_buf, c);
  143         }
  144 
  145         free(random_buf, M_TEMP);
  146 
  147         return (error);
  148 }
  149 
  150 /* ARGSUSED */
  151 static int
  152 random_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t addr __unused,
  153     int flags __unused, struct thread *td __unused)
  154 {
  155         int error = 0;
  156 
  157         switch (cmd) {
  158                 /* Really handled in upper layer */
  159         case FIOASYNC:
  160         case FIONBIO:
  161                 break;
  162         default:
  163                 error = ENOTTY;
  164         }
  165         return (error);
  166 }
  167 
  168 /* ARGSUSED */
  169 static int
  170 random_poll(struct cdev *dev __unused, int events, struct thread *td)
  171 {
  172         int revents = 0;
  173 
  174         if (events & (POLLIN | POLLRDNORM)) {
  175                 if (random_systat.seeded)
  176                         revents = events & (POLLIN | POLLRDNORM);
  177                 else
  178                         revents = (*random_systat.poll) (events,td);
  179         }
  180         return (revents);
  181 }
  182 
  183 /* ARGSUSED */
  184 static int
  185 random_modevent(module_t mod __unused, int type, void *data __unused)
  186 {
  187         int error = 0;
  188 
  189         switch (type) {
  190         case MOD_LOAD:
  191                 random_ident_hardware(&random_systat);
  192                 (*random_systat.init)();
  193 
  194                 if (bootverbose)
  195                         printf("random: <entropy source, %s>\n",
  196                             random_systat.ident);
  197 
  198                 random_dev = make_dev(&random_cdevsw, RANDOM_MINOR,
  199                     UID_ROOT, GID_WHEEL, 0666, "random");
  200                 make_dev_alias(random_dev, "urandom");  /* XXX Deprecated */
  201 
  202                 break;
  203 
  204         case MOD_UNLOAD:
  205                 (*random_systat.deinit)();
  206 
  207                 destroy_dev(random_dev);
  208 
  209                 break;
  210 
  211         case MOD_SHUTDOWN:
  212                 break;
  213 
  214         default:
  215                 error = EOPNOTSUPP;
  216                 break;
  217 
  218         }
  219         return (error);
  220 }
  221 
  222 DEV_MODULE(random, random_modevent, NULL);
  223 MODULE_VERSION(random, 1);

Cache object: 30d7180186ea3170191c589e4cad84d7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.