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 } 347