1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  *
  21  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  22  * Use is subject to license terms.
  23  *
  24  * Copyright 2017 Joyent, Inc.
  25  */
  26 
  27 
  28 /*
  29  * Random number generator pseudo-driver
  30  *
  31  * This is a lightweight driver which calls in to the Kernel Cryptographic
  32  * Framework to do the real work. Kernel modules should NOT depend on this
  33  * driver for /dev/random kernel API.
  34  *
  35  * Applications may ask for 2 types of random bits:
  36  * . High quality random by reading from /dev/random. The output is extracted
  37  *   only when a minimum amount of entropy is available.
  38  * . Pseudo-random, by reading from /dev/urandom, that can be generated any
  39  *   time.
  40  */
  41 
  42 #include <sys/types.h>
  43 #include <sys/errno.h>
  44 #include <sys/stat.h>
  45 
  46 #include <sys/file.h>
  47 #include <sys/open.h>
  48 #include <sys/poll.h>
  49 #include <sys/uio.h>
  50 #include <sys/cred.h>
  51 #include <sys/modctl.h>
  52 #include <sys/conf.h>
  53 #include <sys/ddi.h>
  54 #include <sys/sunddi.h>
  55 #include <sys/random.h>
  56 #include <sys/crypto/impl.h>
  57 
  58 #define DEVRANDOM               0
  59 #define DEVURANDOM              1
  60 
  61 #define HASHSIZE                20      /* Assuming a SHA1 hash algorithm */
  62 #define WRITEBUFSIZE            512     /* Size of buffer for write request */
  63 #define MAXRETBYTES             1040    /* Max bytes returned per read. */
  64                                         /* Must be a multiple of HASHSIZE */
  65 static dev_info_t *rnd_dip;
  66 
  67 static int rnd_open(dev_t *, int, int, cred_t *);
  68 static int rnd_close(dev_t, int, int, cred_t *);
  69 static int rnd_read(dev_t, struct uio *, cred_t *);
  70 static int rnd_write(dev_t, struct uio *, cred_t *);
  71 static int rnd_chpoll(dev_t, short, int, short *, struct pollhead **);
  72 static int rnd_attach(dev_info_t *, ddi_attach_cmd_t);
  73 static int rnd_detach(dev_info_t *, ddi_detach_cmd_t);
  74 static int rnd_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
  75 
  76 /* DDI declarations */
  77 static struct cb_ops rnd_cb_ops = {
  78         rnd_open,               /* open */
  79         rnd_close,              /* close */
  80         nodev,                  /* strategy */
  81         nodev,                  /* print */
  82         nodev,                  /* dump */
  83         rnd_read,               /* read */
  84         rnd_write,              /* write */
  85         nodev,                  /* ioctl */
  86         nodev,                  /* devmap */
  87         nodev,                  /* mmap */
  88         nodev,                  /* segmap */
  89         rnd_chpoll,             /* chpoll */
  90         ddi_prop_op,            /* prop_op */
  91         NULL,                   /* streamtab  */
  92         (D_NEW | D_MP),         /* cb_flag */
  93         CB_REV,                 /* cb_rev */
  94         nodev,                  /* aread */
  95         nodev                   /* awrite */
  96 };
  97 
  98 static struct dev_ops rnd_ops = {
  99         DEVO_REV,               /* devo_rev, */
 100         0,                      /* refcnt  */
 101         rnd_getinfo,            /* get_dev_info */
 102         nulldev,                /* identify */
 103         nulldev,                /* probe */
 104         rnd_attach,             /* attach */
 105         rnd_detach,             /* detach */
 106         nodev,                  /* reset */
 107         &rnd_cb_ops,                /* driver operations */
 108         NULL,                   /* bus operations */
 109         NULL,                   /* power */
 110         ddi_quiesce_not_needed,         /* quiesce */
 111 };
 112 
 113 /* Modlinkage */
 114 static struct modldrv modldrv = {
 115         &mod_driverops,
 116         "random number device",
 117         &rnd_ops
 118 };
 119 
 120 static struct modlinkage modlinkage = { MODREV_1, { &modldrv, NULL } };
 121 
 122 
 123 /* DDI glue */
 124 
 125 int
 126 _init(void)
 127 {
 128         return (mod_install(&modlinkage));
 129 }
 130 
 131 int
 132 _fini(void)
 133 {
 134         return (mod_remove(&modlinkage));
 135 }
 136 
 137 int
 138 _info(struct modinfo *modinfop)
 139 {
 140         return (mod_info(&modlinkage, modinfop));
 141 }
 142 
 143 static int
 144 rnd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 145 {
 146         if (cmd != DDI_ATTACH)
 147                 return (DDI_FAILURE);
 148 
 149         if (ddi_create_minor_node(dip, "random", S_IFCHR, DEVRANDOM,
 150             DDI_PSEUDO, 0) == DDI_FAILURE) {
 151                 ddi_remove_minor_node(dip, NULL);
 152                 return (DDI_FAILURE);
 153         }
 154         if (ddi_create_minor_node(dip, "urandom", S_IFCHR, DEVURANDOM,
 155             DDI_PSEUDO, 0) == DDI_FAILURE) {
 156                 ddi_remove_minor_node(dip, NULL);
 157                 return (DDI_FAILURE);
 158         }
 159 
 160         rnd_dip = dip;
 161 
 162         return (DDI_SUCCESS);
 163 }
 164 
 165 static int
 166 rnd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 167 {
 168         if (cmd != DDI_DETACH)
 169                 return (DDI_FAILURE);
 170 
 171         rnd_dip = NULL;
 172         ddi_remove_minor_node(dip, NULL);
 173 
 174         return (DDI_SUCCESS);
 175 }
 176 
 177 /*ARGSUSED*/
 178 static int
 179 rnd_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
 180 {
 181         int error;
 182 
 183         switch (infocmd) {
 184         case DDI_INFO_DEVT2DEVINFO:
 185                 *result = rnd_dip;
 186                 error = DDI_SUCCESS;
 187                 break;
 188         case DDI_INFO_DEVT2INSTANCE:
 189                 *result = (void *)0;
 190                 error = DDI_SUCCESS;
 191                 break;
 192         default:
 193                 error = DDI_FAILURE;
 194         }
 195         return (error);
 196 }
 197 
 198 /*ARGSUSED3*/
 199 static int
 200 rnd_open(dev_t *devp, int flag, int otyp, cred_t *credp)
 201 {
 202         switch (getminor(*devp)) {
 203         case DEVRANDOM:
 204                 if (!kcf_rngprov_check())
 205                         return (ENXIO);
 206                 break;
 207         case DEVURANDOM:
 208                 break;
 209         default:
 210                 return (ENXIO);
 211         }
 212         if (otyp != OTYP_CHR)
 213                 return (EINVAL);
 214 
 215         if (flag & FEXCL)
 216                 return (EINVAL);
 217         return (0);
 218 }
 219 
 220 /*ARGSUSED*/
 221 static int
 222 rnd_close(dev_t dev, int flag, int otyp, cred_t *credp)
 223 {
 224         return (0);
 225 }
 226 
 227 /*ARGSUSED2*/
 228 static int
 229 rnd_read(dev_t dev, struct uio *uiop, cred_t *credp)
 230 {
 231         size_t len;
 232         minor_t devno;
 233         int error = 0;
 234         int nbytes = 0;
 235         uint8_t random_bytes[2 * HASHSIZE];
 236 
 237         devno = getminor(dev);
 238 
 239         while (error == 0 && uiop->uio_resid > 0) {
 240                 len = min(sizeof (random_bytes), uiop->uio_resid);
 241                 switch (devno) {
 242                 case DEVRANDOM:
 243                         error = kcf_rnd_get_bytes(random_bytes, len,
 244                             uiop->uio_fmode & (FNDELAY|FNONBLOCK));
 245                         break;
 246                 case DEVURANDOM:
 247                         error = kcf_rnd_get_pseudo_bytes(random_bytes, len);
 248                         break;
 249                 default:
 250                         return (ENXIO);
 251                 }
 252 
 253                 if (error == 0) {
 254                         /*
 255                          * /dev/[u]random is not a seekable device. To prevent
 256                          * uio offset from growing and eventually exceeding
 257                          * the maximum, reset the offset here for every call.
 258                          */
 259                         uiop->uio_loffset = 0;
 260                         error = uiomove(random_bytes, len, UIO_READ, uiop);
 261 
 262                         nbytes += len;
 263 
 264                         if (devno == DEVRANDOM && nbytes >= MAXRETBYTES)
 265                                 break;
 266 
 267                 } else if ((error == EAGAIN) && (nbytes > 0)) {
 268                         error = 0;
 269                         break;
 270                 }
 271         }
 272         return (error);
 273 }
 274 
 275 /*ARGSUSED*/
 276 static int
 277 rnd_write(dev_t dev, struct uio *uiop, cred_t *credp)
 278 {
 279         int error;
 280         uint8_t buf[WRITEBUFSIZE];
 281         size_t bytes;
 282         minor_t devno;
 283 
 284         devno = getminor(dev);
 285 
 286         while (uiop->uio_resid > 0) {
 287                 bytes = min(sizeof (buf), uiop->uio_resid);
 288 
 289                 /* See comments in rnd_read() */
 290                 uiop->uio_loffset = 0;
 291                 if ((error = uiomove(buf, bytes, UIO_WRITE, uiop)) != 0)
 292                         return (error);
 293 
 294                 switch (devno) {
 295                 case DEVRANDOM:
 296                         if ((error = random_add_entropy(buf, bytes, 0)) != 0)
 297                                 return (error);
 298                         break;
 299                 case DEVURANDOM:
 300                         if ((error = random_add_pseudo_entropy(buf, bytes,
 301                             0)) != 0)
 302                                 return (error);
 303                         break;
 304                 default:
 305                         return (ENXIO);
 306                 }
 307         }
 308 
 309         return (0);
 310 }
 311 
 312 static struct pollhead urnd_pollhd;
 313 
 314 /*
 315  * poll(2) is supported as follows:
 316  * . Only POLLIN, POLLOUT, and POLLRDNORM events are supported.
 317  * . POLLOUT always succeeds.
 318  * . POLLIN and POLLRDNORM from /dev/urandom always succeeds.
 319  * . POLLIN and POLLRDNORM from /dev/random will block until a
 320  *   minimum amount of entropy is available.
 321  */
 322 static int
 323 rnd_chpoll(dev_t dev, short events, int anyyet, short *reventsp,
 324     struct pollhead **phpp)
 325 {
 326         switch (getminor(dev)) {
 327         case DEVURANDOM:
 328                 *reventsp = events & (POLLOUT | POLLIN | POLLRDNORM);
 329 
 330                 /*
 331                  * A non NULL pollhead pointer should be returned in case
 332                  * user polls for 0 events.
 333                  */
 334                 if ((*reventsp == 0 && !anyyet) || (events & POLLET))
 335                         *phpp = &urnd_pollhd;
 336 
 337                 break;
 338         case DEVRANDOM:
 339                 kcf_rnd_chpoll(events, anyyet, reventsp, phpp);
 340                 break;
 341         default:
 342                 return (ENXIO);
 343         }
 344 
 345         return (0);
 346 }