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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 * 22 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 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 }; 111 112 /* Modlinkage */ 113 static struct modldrv modldrv = { 114 &mod_driverops, 115 "random number device v%I%", 116 &rnd_ops 117 }; 118 119 static struct modlinkage modlinkage = { MODREV_1, { &modldrv, NULL } }; 120 121 122 /* DDI glue */ 123 124 int 125 _init(void) 126 { 127 return (mod_install(&modlinkage)); 128 } 129 130 int 131 _fini(void) 132 { 133 return (mod_remove(&modlinkage)); 134 } 135 136 int 137 _info(struct modinfo *modinfop) 138 { 139 return (mod_info(&modlinkage, modinfop)); 140 } 141 142 static int 143 rnd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 144 { 145 if (cmd != DDI_ATTACH) 146 return (DDI_FAILURE); 147 148 if (ddi_create_minor_node(dip, "random", S_IFCHR, DEVRANDOM, 149 DDI_PSEUDO, 0) == DDI_FAILURE) { 150 ddi_remove_minor_node(dip, NULL); 151 return (DDI_FAILURE); 152 } 153 if (ddi_create_minor_node(dip, "urandom", S_IFCHR, DEVURANDOM, 154 DDI_PSEUDO, 0) == DDI_FAILURE) { 155 ddi_remove_minor_node(dip, NULL); 156 return (DDI_FAILURE); 157 } 158 159 rnd_dip = dip; 160 161 return (DDI_SUCCESS); 162 } 163 164 static int 165 rnd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 166 { 167 if (cmd != DDI_DETACH) 168 return (DDI_FAILURE); 169 170 rnd_dip = NULL; 171 ddi_remove_minor_node(dip, NULL); 172 173 return (DDI_SUCCESS); 174 } 175 176 /*ARGSUSED*/ 177 static int 178 rnd_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 179 { 180 int error; 181 182 switch (infocmd) { 183 case DDI_INFO_DEVT2DEVINFO: 184 *result = rnd_dip; 185 error = DDI_SUCCESS; 186 break; 187 case DDI_INFO_DEVT2INSTANCE: 188 *result = (void *)0; 189 error = DDI_SUCCESS; 190 break; 191 default: 192 error = DDI_FAILURE; 193 } 194 return (error); 195 } 196 197 /*ARGSUSED3*/ 198 static int 199 rnd_open(dev_t *devp, int flag, int otyp, cred_t *credp) 200 { 201 switch (getminor(*devp)) { 202 case DEVRANDOM: 203 if (!kcf_rngprov_check()) 204 return (ENXIO); 205 break; 206 case DEVURANDOM: 207 break; 208 default: 209 return (ENXIO); 210 } 211 if (otyp != OTYP_CHR) 212 return (EINVAL); 213 214 if (flag & FEXCL) 215 return (EINVAL); 216 return (0); 217 } 218 219 /*ARGSUSED*/ 220 static int 221 rnd_close(dev_t dev, int flag, int otyp, cred_t *credp) 222 { 223 return (0); 224 } 225 226 /*ARGSUSED2*/ 227 static int 228 rnd_read(dev_t dev, struct uio *uiop, cred_t *credp) 229 { 230 size_t len; 231 minor_t devno; 232 int error = 0; 233 int nbytes = 0; 234 uint8_t random_bytes[2 * HASHSIZE]; 235 236 devno = getminor(dev); 237 238 while (error == 0 && uiop->uio_resid > 0) { 239 len = min(sizeof (random_bytes), uiop->uio_resid); 240 switch (devno) { 241 case DEVRANDOM: 242 error = kcf_rnd_get_bytes(random_bytes, len, 243 uiop->uio_fmode & (FNDELAY|FNONBLOCK), B_TRUE); 244 break; 245 case DEVURANDOM: 246 error = kcf_rnd_get_pseudo_bytes(random_bytes, len); 247 break; 248 default: 249 return (ENXIO); 250 } 251 252 if (error == 0) { 253 /* 254 * /dev/[u]random is not a seekable device. To prevent 255 * uio offset from growing and eventually exceeding 256 * the maximum, reset the offset here for every call. 257 */ 258 uiop->uio_loffset = 0; 259 error = uiomove(random_bytes, len, UIO_READ, uiop); 260 261 nbytes += len; 262 263 if (nbytes >= MAXRETBYTES) 264 break; 265 266 } else if ((error == EAGAIN) && (nbytes > 0)) { 267 error = 0; 268 break; 269 } 270 } 271 return (error); 272 } 273 274 /*ARGSUSED*/ 275 static int 276 rnd_write(dev_t dev, struct uio *uiop, cred_t *credp) 277 { 278 int error; 279 uint8_t buf[WRITEBUFSIZE]; 280 size_t bytes; 281 282 while (uiop->uio_resid > 0) { 283 bytes = min(sizeof (buf), uiop->uio_resid); 284 285 /* See comments in rnd_read() */ 286 uiop->uio_loffset = 0; 287 if ((error = uiomove(buf, bytes, UIO_WRITE, uiop)) != 0) 288 return (error); 289 290 /* Add bytes to the pool but don't change the entropy level */ 291 if ((error = random_add_entropy(buf, bytes, 0)) != 0) 292 return (error); 293 } 294 295 return (0); 296 } 297 298 /* 299 * poll(2) is supported as follows: 300 * . Only POLLIN, POLLOUT, and POLLRDNORM events are valid. 301 * . POLLOUT always succeeds. 302 * . POLLIN and POLLRDNORM from /dev/urandom always succeeds. 303 * . POLLIN and POLLRDNORM from /dev/random will block until a 304 * minimum amount of entropy is available. 305 */ 306 static int 307 rnd_chpoll(dev_t dev, short events, int anyyet, short *reventsp, 308 struct pollhead **phpp) 309 { 310 switch (getminor(dev)) { 311 case DEVURANDOM: 312 *reventsp = events & (POLLOUT | POLLIN | POLLRDNORM); 313 314 /* We're being polled for non-supported events */ 315 if (*reventsp == 0 && !anyyet) 316 return (EINVAL); 317 318 break; 319 case DEVRANDOM: 320 *reventsp = events & POLLOUT; 321 322 /* Either POLLOUT only or unsupported event */ 323 if ((events & (POLLIN | POLLRDNORM)) == 0) { 324 if (*reventsp == 0 && !anyyet) 325 return (EINVAL); 326 break; 327 } 328 329 kcf_rnd_chpoll(anyyet, reventsp, phpp); 330 break; 331 default: 332 return (ENXIO); 333 } 334 335 return (0); 336 } 337