1 /*- 2 * Copyright (c) 2000-2015 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$"); 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/module.h> 41 #include <sys/malloc.h> 42 #include <sys/poll.h> 43 #include <sys/proc.h> 44 #include <sys/random.h> 45 #include <sys/sbuf.h> 46 #include <sys/selinfo.h> 47 #include <sys/sysctl.h> 48 #include <sys/systm.h> 49 #include <sys/uio.h> 50 #include <sys/unistd.h> 51 52 #include <crypto/rijndael/rijndael-api-fst.h> 53 #include <crypto/sha2/sha2.h> 54 55 #include <dev/random/hash.h> 56 #include <dev/random/randomdev.h> 57 #include <dev/random/random_harvestq.h> 58 59 #include "opt_random.h" 60 61 #if defined(RANDOM_DUMMY) && defined(RANDOM_YARROW) 62 #error "Cannot define both RANDOM_DUMMY and RANDOM_YARROW" 63 #endif 64 65 #define RANDOM_UNIT 0 66 67 /* Return the largest number >= x that is a multiple of m */ 68 #define CEIL_TO_MULTIPLE(x, m) ((((x) + (m) - 1)/(m))*(m)) 69 70 static d_read_t randomdev_read; 71 static d_write_t randomdev_write; 72 static d_poll_t randomdev_poll; 73 static d_ioctl_t randomdev_ioctl; 74 75 static struct cdevsw random_cdevsw = { 76 .d_name = "random", 77 .d_version = D_VERSION, 78 .d_read = randomdev_read, 79 .d_write = randomdev_write, 80 .d_poll = randomdev_poll, 81 .d_ioctl = randomdev_ioctl, 82 }; 83 84 /* For use with make_dev(9)/destroy_dev(9). */ 85 static struct cdev *random_dev; 86 87 /* Set up the sysctl root node for the entropy device */ 88 SYSCTL_NODE(_kern, OID_AUTO, random, CTLFLAG_RW, 0, "Cryptographically Secure Random Number Generator"); 89 90 MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers and data structures"); 91 92 #if defined(RANDOM_DUMMY) 93 94 /*- 95 * Dummy "always block" pseudo algorithm, used when there is no real 96 * random(4) driver to provide a CSPRNG. 97 */ 98 99 static u_int 100 dummy_random_zero(void) 101 { 102 103 return (0); 104 } 105 106 static void 107 dummy_random(void) 108 { 109 } 110 111 struct random_algorithm random_alg_context = { 112 .ra_ident = "Dummy", 113 .ra_init_alg = NULL, 114 .ra_deinit_alg = NULL, 115 .ra_pre_read = dummy_random, 116 .ra_read = (random_alg_read_t *)dummy_random_zero, 117 .ra_write = (random_alg_write_t *)dummy_random_zero, 118 .ra_reseed = dummy_random, 119 .ra_seeded = (random_alg_seeded_t *)dummy_random_zero, 120 .ra_event_processor = NULL, 121 .ra_poolcount = 0, 122 }; 123 124 #else /* !defined(RANDOM_DUMMY) */ 125 126 LIST_HEAD(sources_head, random_sources); 127 static struct sources_head source_list = LIST_HEAD_INITIALIZER(source_list); 128 static u_int read_rate; 129 130 static void 131 random_alg_context_ra_init_alg(void *data) 132 { 133 134 random_alg_context.ra_init_alg(data); 135 } 136 137 static void 138 random_alg_context_ra_deinit_alg(void *data) 139 { 140 141 random_alg_context.ra_deinit_alg(data); 142 } 143 144 SYSINIT(random_device, SI_SUB_RANDOM, SI_ORDER_THIRD, random_alg_context_ra_init_alg, NULL); 145 SYSUNINIT(random_device, SI_SUB_RANDOM, SI_ORDER_THIRD, random_alg_context_ra_deinit_alg, NULL); 146 147 #endif /* defined(RANDOM_DUMMY) */ 148 149 static struct selinfo rsel; 150 151 /* 152 * This is the read uio(9) interface for random(4). 153 */ 154 /* ARGSUSED */ 155 static int 156 randomdev_read(struct cdev *dev __unused, struct uio *uio, int flags) 157 { 158 159 return (read_random_uio(uio, (flags & O_NONBLOCK) != 0)); 160 } 161 162 int 163 read_random_uio(struct uio *uio, bool nonblock) 164 { 165 uint8_t *random_buf; 166 int error; 167 ssize_t read_len, total_read, c; 168 169 random_buf = malloc(PAGE_SIZE, M_ENTROPY, M_WAITOK); 170 random_alg_context.ra_pre_read(); 171 /* (Un)Blocking logic */ 172 error = 0; 173 while (!random_alg_context.ra_seeded()) { 174 if (nonblock) { 175 error = EWOULDBLOCK; 176 break; 177 } 178 tsleep(&random_alg_context, 0, "randseed", hz/10); 179 /* keep tapping away at the pre-read until we seed/unblock. */ 180 random_alg_context.ra_pre_read(); 181 printf("random: %s unblock wait\n", __func__); 182 } 183 if (error == 0) { 184 #if !defined(RANDOM_DUMMY) 185 /* XXX: FIX!! Next line as an atomic operation? */ 186 read_rate += (uio->uio_resid + sizeof(uint32_t))/sizeof(uint32_t); 187 #endif 188 total_read = 0; 189 while (uio->uio_resid && !error) { 190 read_len = uio->uio_resid; 191 /* 192 * Belt-and-braces. 193 * Round up the read length to a crypto block size multiple, 194 * which is what the underlying generator is expecting. 195 * See the random_buf size requirements in the Yarrow/Fortuna code. 196 */ 197 read_len = CEIL_TO_MULTIPLE(read_len, RANDOM_BLOCKSIZE); 198 /* Work in chunks page-sized or less */ 199 read_len = MIN(read_len, PAGE_SIZE); 200 random_alg_context.ra_read(random_buf, read_len); 201 c = MIN(uio->uio_resid, read_len); 202 error = uiomove(random_buf, c, uio); 203 total_read += c; 204 } 205 if (total_read != uio->uio_resid && (error == ERESTART || error == EINTR)) 206 /* Return partial read, not error. */ 207 error = 0; 208 } 209 free(random_buf, M_ENTROPY); 210 return (error); 211 } 212 213 /*- 214 * Kernel API version of read_random(). 215 * This is similar to random_alg_read(), 216 * except it doesn't interface with uio(9). 217 * It cannot assumed that random_buf is a multiple of 218 * RANDOM_BLOCKSIZE bytes. 219 */ 220 u_int 221 read_random(void *random_buf, u_int len) 222 { 223 u_int read_len; 224 uint8_t local_buf[len + RANDOM_BLOCKSIZE]; 225 226 KASSERT(random_buf != NULL, ("No suitable random buffer in %s", __func__)); 227 random_alg_context.ra_pre_read(); 228 /* (Un)Blocking logic; if not seeded, return nothing. */ 229 if (random_alg_context.ra_seeded()) { 230 #if !defined(RANDOM_DUMMY) 231 /* XXX: FIX!! Next line as an atomic operation? */ 232 read_rate += (len + sizeof(uint32_t))/sizeof(uint32_t); 233 #endif 234 if (len > 0) { 235 /* 236 * Belt-and-braces. 237 * Round up the read length to a crypto block size multiple, 238 * which is what the underlying generator is expecting. 239 */ 240 read_len = CEIL_TO_MULTIPLE(len, RANDOM_BLOCKSIZE); 241 random_alg_context.ra_read(local_buf, read_len); 242 memcpy(random_buf, local_buf, len); 243 } 244 } else 245 len = 0; 246 return (len); 247 } 248 249 /* ARGSUSED */ 250 static int 251 randomdev_write(struct cdev *dev __unused, struct uio *uio, int flags __unused) 252 { 253 uint8_t *random_buf; 254 int c, error = 0; 255 ssize_t nbytes; 256 257 random_buf = malloc(PAGE_SIZE, M_ENTROPY, M_WAITOK); 258 nbytes = uio->uio_resid; 259 while (uio->uio_resid > 0 && error == 0) { 260 c = MIN(uio->uio_resid, PAGE_SIZE); 261 error = uiomove(random_buf, c, uio); 262 if (error) 263 break; 264 random_alg_context.ra_write(random_buf, c); 265 tsleep(&random_alg_context, 0, "randwr", hz/10); 266 } 267 if (nbytes != uio->uio_resid && (error == ERESTART || error == EINTR)) 268 /* Partial write, not error. */ 269 error = 0; 270 free(random_buf, M_ENTROPY); 271 return (error); 272 } 273 274 /* ARGSUSED */ 275 static int 276 randomdev_poll(struct cdev *dev __unused, int events, struct thread *td __unused) 277 { 278 279 if (events & (POLLIN | POLLRDNORM)) { 280 if (random_alg_context.ra_seeded()) 281 events &= (POLLIN | POLLRDNORM); 282 else 283 selrecord(td, &rsel); 284 } 285 return (events); 286 } 287 288 /* This will be called by the entropy processor when it seeds itself and becomes secure */ 289 void 290 randomdev_unblock(void) 291 { 292 293 selwakeuppri(&rsel, PUSER); 294 wakeup(&random_alg_context); 295 printf("random: unblocking device.\n"); 296 /* Do random(9) a favour while we are about it. */ 297 (void)atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_NONE, ARC4_ENTR_HAVE); 298 } 299 300 /* ARGSUSED */ 301 static int 302 randomdev_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t addr __unused, 303 int flags __unused, struct thread *td __unused) 304 { 305 int error = 0; 306 307 switch (cmd) { 308 /* Really handled in upper layer */ 309 case FIOASYNC: 310 case FIONBIO: 311 break; 312 default: 313 error = ENOTTY; 314 } 315 316 return (error); 317 } 318 319 void 320 random_source_register(struct random_source *rsource) 321 { 322 #if defined(RANDOM_DUMMY) 323 (void)rsource; 324 #else /* !defined(RANDOM_DUMMY) */ 325 struct random_sources *rrs; 326 327 KASSERT(rsource != NULL, ("invalid input to %s", __func__)); 328 329 rrs = malloc(sizeof(*rrs), M_ENTROPY, M_WAITOK); 330 rrs->rrs_source = rsource; 331 332 printf("random: registering fast source %s\n", rsource->rs_ident); 333 LIST_INSERT_HEAD(&source_list, rrs, rrs_entries); 334 #endif /* defined(RANDOM_DUMMY) */ 335 } 336 337 void 338 random_source_deregister(struct random_source *rsource) 339 { 340 #if defined(RANDOM_DUMMY) 341 (void)rsource; 342 #else /* !defined(RANDOM_DUMMY) */ 343 struct random_sources *rrs = NULL; 344 345 KASSERT(rsource != NULL, ("invalid input to %s", __func__)); 346 LIST_FOREACH(rrs, &source_list, rrs_entries) 347 if (rrs->rrs_source == rsource) { 348 LIST_REMOVE(rrs, rrs_entries); 349 break; 350 } 351 if (rrs != NULL) 352 free(rrs, M_ENTROPY); 353 #endif /* defined(RANDOM_DUMMY) */ 354 } 355 356 #if !defined(RANDOM_DUMMY) 357 /* 358 * Run through all fast sources reading entropy for the given 359 * number of rounds, which should be a multiple of the number 360 * of entropy accumulation pools in use; 2 for Yarrow and 32 361 * for Fortuna. 362 * 363 * BEWARE!!! 364 * This function runs inside the RNG thread! Don't do anything silly! 365 */ 366 void 367 random_sources_feed(void) 368 { 369 uint32_t entropy[HARVESTSIZE]; 370 struct random_sources *rrs; 371 u_int i, n, local_read_rate; 372 373 /* 374 * Step over all of live entropy sources, and feed their output 375 * to the system-wide RNG. 376 */ 377 /* XXX: FIX!! Next lines as an atomic operation? */ 378 local_read_rate = read_rate; 379 read_rate = RANDOM_ALG_READ_RATE_MINIMUM; 380 LIST_FOREACH(rrs, &source_list, rrs_entries) { 381 for (i = 0; i < random_alg_context.ra_poolcount*local_read_rate; i++) { 382 n = rrs->rrs_source->rs_read(entropy, sizeof(entropy)); 383 KASSERT((n > 0 && n <= sizeof(entropy)), ("very bad return from rs_read (= %d) in %s", n, __func__)); 384 random_harvest_direct(entropy, n, (n*8)/2, rrs->rrs_source->rs_source); 385 } 386 } 387 explicit_bzero(entropy, sizeof(entropy)); 388 } 389 390 static int 391 random_source_handler(SYSCTL_HANDLER_ARGS) 392 { 393 struct random_sources *rrs; 394 struct sbuf sbuf; 395 int error, count; 396 397 sbuf_new_for_sysctl(&sbuf, NULL, 64, req); 398 count = 0; 399 LIST_FOREACH(rrs, &source_list, rrs_entries) { 400 sbuf_cat(&sbuf, (count++ ? ",'" : "'")); 401 sbuf_cat(&sbuf, rrs->rrs_source->rs_ident); 402 sbuf_cat(&sbuf, "'"); 403 } 404 error = sbuf_finish(&sbuf); 405 sbuf_delete(&sbuf); 406 return (error); 407 } 408 SYSCTL_PROC(_kern_random, OID_AUTO, random_sources, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 409 NULL, 0, random_source_handler, "A", 410 "List of active fast entropy sources."); 411 #endif /* !defined(RANDOM_DUMMY) */ 412 413 /* ARGSUSED */ 414 static int 415 randomdev_modevent(module_t mod __unused, int type, void *data __unused) 416 { 417 int error = 0; 418 419 switch (type) { 420 case MOD_LOAD: 421 printf("random: entropy device external interface\n"); 422 random_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &random_cdevsw, 423 RANDOM_UNIT, NULL, UID_ROOT, GID_WHEEL, 0644, "random"); 424 make_dev_alias(random_dev, "urandom"); /* compatibility */ 425 break; 426 case MOD_UNLOAD: 427 destroy_dev(random_dev); 428 break; 429 case MOD_SHUTDOWN: 430 break; 431 default: 432 error = EOPNOTSUPP; 433 break; 434 } 435 return (error); 436 } 437 438 static moduledata_t randomdev_mod = { 439 "random_device", 440 randomdev_modevent, 441 0 442 }; 443 444 DECLARE_MODULE(random_device, randomdev_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 445 MODULE_VERSION(random_device, 1); 446