1 /* $OpenBSD: rnd.c,v 1.230 2024/12/30 02:46:00 guenther Exp $ */ 2 3 /* 4 * Copyright (c) 2011,2020 Theo de Raadt. 5 * Copyright (c) 2008 Damien Miller. 6 * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff. 7 * Copyright (c) 2013 Markus Friedl. 8 * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, and the entire permission notice in its entirety, 16 * including the disclaimer of warranties. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. The name of the author may not be used to endorse or promote 21 * products derived from this software without specific prior 22 * written permission. 23 * 24 * ALTERNATIVELY, this product may be distributed under the terms of 25 * the GNU Public License, in which case the provisions of the GPL are 26 * required INSTEAD OF the above restrictions. (This clause is 27 * necessary due to a potential bad interaction between the GPL and 28 * the restrictions contained in a BSD-style copyright.) 29 * 30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 31 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 33 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 34 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 36 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 38 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 40 * OF THE POSSIBILITY OF SUCH DAMAGE. 41 */ 42 43 /* 44 * The bootblocks pre-fill the kernel .openbsd.randomdata section with seed 45 * material (on-disk from previous boot, hopefully mixed with a hardware rng). 46 * The first arc4random(9) call initializes this seed material as a chacha 47 * state. Calls can be done early in kernel bootstrap code -- early use is 48 * encouraged. 49 * 50 * After the kernel timeout subsystem is initialized, random_start() prepares 51 * the entropy collection mechanism enqueue_randomness() and timeout-driven 52 * mixing into the chacha state. The first submissions come from device 53 * probes, later on interrupt-time submissions are more common. Entropy 54 * data (and timing information) get mixed over the entropy input ring 55 * rnd_event_space[] -- the goal is to collect damage. 56 * 57 * Based upon timeouts, a selection of the entropy ring rnd_event_space[] 58 * CRC bit-distributed and XOR mixed into entropy_pool[]. 59 * 60 * From time to time, entropy_pool[] is SHA512-whitened, mixed with time 61 * information again, XOR'd with the inner and outer states of the existing 62 * chacha state, to create a new chacha state. 63 * 64 * During early boot (until cold=0), enqueue operations are immediately 65 * dequeued, and mixed into the chacha. 66 */ 67 68 #include <sys/param.h> 69 #include <sys/event.h> 70 #include <sys/ioctl.h> 71 #include <sys/malloc.h> 72 #include <sys/timeout.h> 73 #include <sys/atomic.h> 74 #include <sys/task.h> 75 #include <sys/msgbuf.h> 76 #include <sys/mount.h> 77 #include <sys/syscallargs.h> 78 #include <sys/syslimits.h> 79 80 #include <crypto/sha2.h> 81 82 #define KEYSTREAM_ONLY 83 #include <crypto/chacha_private.h> 84 85 #include <uvm/uvm_extern.h> 86 87 /* 88 * For the purposes of better mixing, we use the CRC-32 polynomial as 89 * well to make a twisted Generalized Feedback Shift Register 90 * 91 * (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR generators. ACM 92 * Transactions on Modeling and Computer Simulation 2(3):179-194. 93 * Also see M. Matsumoto & Y. Kurita, 1994. Twisted GFSR generators 94 * II. ACM Transactions on Modeling and Computer Simulation 4:254-266) 95 */ 96 97 /* 98 * Stirring polynomial over GF(2). Used in add_entropy_words() below. 99 * 100 * The polynomial terms are chosen to be evenly spaced (minimum RMS 101 * distance from evenly spaced; except for the last tap, which is 1 to 102 * get the twisting happening as fast as possible. 103 * 104 * The resultant polynomial is: 105 * 2^POOLWORDS + 2^POOL_TAP1 + 2^POOL_TAP2 + 2^POOL_TAP3 + 2^POOL_TAP4 + 1 106 */ 107 #define POOLWORDS 2048 108 #define POOLBYTES (POOLWORDS*4) 109 #define POOLMASK (POOLWORDS - 1) 110 #define POOL_TAP1 1638 111 #define POOL_TAP2 1231 112 #define POOL_TAP3 819 113 #define POOL_TAP4 411 114 115 /* 116 * Raw entropy collection from device drivers; at interrupt context or not. 117 * enqueue_randomness() is used to submit data into the entropy input ring. 118 */ 119 120 #define QEVLEN 128 /* must be a power of 2 */ 121 #define QEVCONSUME 8 /* how many events to consume a time */ 122 123 #define KEYSZ 32 124 #define IVSZ 8 125 #define BLOCKSZ 64 126 #define RSBUFSZ (16*BLOCKSZ) 127 #define EBUFSIZE KEYSZ + IVSZ 128 129 struct rand_event { 130 u_int re_time; 131 u_int re_val; 132 } rnd_event_space[QEVLEN]; 133 134 u_int rnd_event_cons; 135 u_int rnd_event_prod; 136 int rnd_cold = 1; 137 int rnd_slowextract = 1; 138 139 void rnd_reinit(void *v); /* timeout to start reinit */ 140 void rnd_init(void *); /* actually do the reinit */ 141 142 static u_int32_t entropy_pool[POOLWORDS]; 143 u_int32_t entropy_pool0[POOLWORDS] __attribute__((section(".openbsd.randomdata"))); 144 145 void dequeue_randomness(void *); 146 void add_entropy_words(const u_int32_t *, u_int); 147 void extract_entropy(u_int8_t *) 148 __attribute__((__bounded__(__minbytes__,1,EBUFSIZE))); 149 150 struct timeout rnd_timeout = TIMEOUT_INITIALIZER(dequeue_randomness, NULL); 151 152 int filt_randomread(struct knote *, long); 153 void filt_randomdetach(struct knote *); 154 int filt_randomwrite(struct knote *, long); 155 156 static void _rs_seed(u_char *, size_t); 157 static void _rs_clearseed(const void *p, size_t s); 158 159 const struct filterops randomread_filtops = { 160 .f_flags = FILTEROP_ISFD, 161 .f_attach = NULL, 162 .f_detach = filt_randomdetach, 163 .f_event = filt_randomread, 164 }; 165 166 const struct filterops randomwrite_filtops = { 167 .f_flags = FILTEROP_ISFD, 168 .f_attach = NULL, 169 .f_detach = filt_randomdetach, 170 .f_event = filt_randomwrite, 171 }; 172 173 /* 174 * This function mixes entropy and timing into the entropy input ring. 175 */ 176 static void 177 add_event_data(u_int val) 178 { 179 struct rand_event *rep; 180 int e; 181 182 e = (atomic_inc_int_nv(&rnd_event_prod) - 1) & (QEVLEN-1); 183 rep = &rnd_event_space[e]; 184 rep->re_time += cpu_rnd_messybits(); 185 rep->re_val += val; 186 } 187 188 void 189 enqueue_randomness(u_int val) 190 { 191 add_event_data(val); 192 193 if (rnd_cold) { 194 dequeue_randomness(NULL); 195 rnd_init(NULL); 196 if (!cold) 197 rnd_cold = 0; 198 } else if (!timeout_pending(&rnd_timeout) && 199 (rnd_event_prod - rnd_event_cons) > QEVCONSUME) { 200 rnd_slowextract = min(rnd_slowextract * 2, 5000); 201 timeout_add_msec(&rnd_timeout, rnd_slowextract * 10); 202 } 203 } 204 205 /* 206 * This function merges entropy ring information into the buffer using 207 * a polynomial to spread the bits. 208 */ 209 void 210 add_entropy_words(const u_int32_t *buf, u_int n) 211 { 212 /* derived from IEEE 802.3 CRC-32 */ 213 static const u_int32_t twist_table[8] = { 214 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, 215 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 216 }; 217 static u_int entropy_add_ptr; 218 static u_char entropy_input_rotate; 219 220 for (; n--; buf++) { 221 u_int32_t w = (*buf << entropy_input_rotate) | 222 (*buf >> ((32 - entropy_input_rotate) & 31)); 223 u_int i = entropy_add_ptr = 224 (entropy_add_ptr - 1) & POOLMASK; 225 /* 226 * Normally, we add 7 bits of rotation to the pool. 227 * At the beginning of the pool, add an extra 7 bits 228 * rotation, so that successive passes spread the 229 * input bits across the pool evenly. 230 */ 231 entropy_input_rotate = 232 (entropy_input_rotate + (i ? 7 : 14)) & 31; 233 234 /* XOR pool contents corresponding to polynomial terms */ 235 w ^= entropy_pool[(i + POOL_TAP1) & POOLMASK] ^ 236 entropy_pool[(i + POOL_TAP2) & POOLMASK] ^ 237 entropy_pool[(i + POOL_TAP3) & POOLMASK] ^ 238 entropy_pool[(i + POOL_TAP4) & POOLMASK] ^ 239 entropy_pool[(i + 1) & POOLMASK] ^ 240 entropy_pool[i]; /* + 2^POOLWORDS */ 241 242 entropy_pool[i] = (w >> 3) ^ twist_table[w & 7]; 243 } 244 } 245 246 /* 247 * Pulls entropy out of the queue and merges it into the pool with the 248 * CRC. This takes a mix of fresh entries from the producer end of the 249 * queue and entries from the consumer end of the queue which are 250 * likely to have collected more damage. 251 */ 252 void 253 dequeue_randomness(void *v) 254 { 255 u_int32_t buf[2]; 256 u_int startp, startc, i; 257 258 /* Some very new damage */ 259 startp = rnd_event_prod - QEVCONSUME; 260 for (i = 0; i < QEVCONSUME; i++) { 261 u_int e = (startp + i) & (QEVLEN-1); 262 263 buf[0] = rnd_event_space[e].re_time; 264 buf[1] = rnd_event_space[e].re_val; 265 add_entropy_words(buf, 2); 266 } 267 /* and some probably more damaged */ 268 startc = atomic_add_int_nv(&rnd_event_cons, QEVCONSUME) - QEVCONSUME; 269 for (i = 0; i < QEVCONSUME; i++) { 270 u_int e = (startc + i) & (QEVLEN-1); 271 272 buf[0] = rnd_event_space[e].re_time; 273 buf[1] = rnd_event_space[e].re_val; 274 add_entropy_words(buf, 2); 275 } 276 } 277 278 /* 279 * Grabs a chunk from the entropy_pool[] and slams it through SHA512 when 280 * requested. 281 */ 282 void 283 extract_entropy(u_int8_t *buf) 284 { 285 static u_int32_t extract_pool[POOLWORDS]; 286 u_char digest[SHA512_DIGEST_LENGTH]; 287 SHA2_CTX shactx; 288 289 #if SHA512_DIGEST_LENGTH < EBUFSIZE 290 #error "need more bigger hash output" 291 #endif 292 293 /* 294 * INTENTIONALLY not protected by any lock. Races during 295 * memcpy() result in acceptable input data; races during 296 * SHA512Update() would create nasty data dependencies. We 297 * do not rely on this as a benefit, but if it happens, cool. 298 */ 299 memcpy(extract_pool, entropy_pool, sizeof(extract_pool)); 300 301 /* Hash the pool to get the output */ 302 SHA512Init(&shactx); 303 SHA512Update(&shactx, (u_int8_t *)extract_pool, sizeof(extract_pool)); 304 SHA512Final(digest, &shactx); 305 306 /* Copy data to destination buffer */ 307 memcpy(buf, digest, EBUFSIZE); 308 309 /* 310 * Modify pool so next hash will produce different results. 311 */ 312 add_event_data(extract_pool[0]); 313 dequeue_randomness(NULL); 314 315 /* Wipe data from memory */ 316 explicit_bzero(extract_pool, sizeof(extract_pool)); 317 explicit_bzero(digest, sizeof(digest)); 318 } 319 320 /* random keystream by ChaCha */ 321 322 struct mutex rndlock = MUTEX_INITIALIZER(IPL_HIGH); 323 struct timeout rndreinit_timeout = TIMEOUT_INITIALIZER(rnd_reinit, NULL); 324 struct task rnd_task = TASK_INITIALIZER(rnd_init, NULL); 325 326 static chacha_ctx rs; /* chacha context for random keystream */ 327 /* keystream blocks (also chacha seed from boot) */ 328 static u_char rs_buf[RSBUFSZ]; 329 u_char rs_buf0[RSBUFSZ] __attribute__((section(".openbsd.randomdata"))); 330 static size_t rs_have; /* valid bytes at end of rs_buf */ 331 static size_t rs_count; /* bytes till reseed */ 332 333 void 334 suspend_randomness(void) 335 { 336 struct timespec ts; 337 338 getnanotime(&ts); 339 enqueue_randomness(ts.tv_sec); 340 enqueue_randomness(ts.tv_nsec); 341 342 dequeue_randomness(NULL); 343 rs_count = 0; 344 arc4random_buf(entropy_pool, sizeof(entropy_pool)); 345 } 346 347 void 348 resume_randomness(char *buf, size_t buflen) 349 { 350 struct timespec ts; 351 352 if (buf && buflen) 353 _rs_seed(buf, buflen); 354 getnanotime(&ts); 355 enqueue_randomness(ts.tv_sec); 356 enqueue_randomness(ts.tv_nsec); 357 358 dequeue_randomness(NULL); 359 rs_count = 0; 360 } 361 362 static inline void _rs_rekey(u_char *dat, size_t datlen); 363 364 static inline void 365 _rs_init(u_char *buf, size_t n) 366 { 367 KASSERT(n >= KEYSZ + IVSZ); 368 chacha_keysetup(&rs, buf, KEYSZ * 8); 369 chacha_ivsetup(&rs, buf + KEYSZ, NULL); 370 } 371 372 static void 373 _rs_seed(u_char *buf, size_t n) 374 { 375 _rs_rekey(buf, n); 376 377 /* invalidate rs_buf */ 378 rs_have = 0; 379 memset(rs_buf, 0, sizeof(rs_buf)); 380 381 rs_count = 1600000; 382 } 383 384 static void 385 _rs_stir(int do_lock) 386 { 387 struct timespec ts; 388 u_int8_t buf[EBUFSIZE], *p; 389 int i; 390 391 /* 392 * Use SHA512 PRNG data and a system timespec; early in the boot 393 * process this is the best we can do -- some architectures do 394 * not collect entropy very well during this time, but may have 395 * clock information which is better than nothing. 396 */ 397 extract_entropy(buf); 398 399 nanotime(&ts); 400 for (p = (u_int8_t *)&ts, i = 0; i < sizeof(ts); i++) 401 buf[i] ^= p[i]; 402 403 if (do_lock) 404 mtx_enter(&rndlock); 405 _rs_seed(buf, sizeof(buf)); 406 if (do_lock) 407 mtx_leave(&rndlock); 408 explicit_bzero(buf, sizeof(buf)); 409 410 /* encourage fast-dequeue again */ 411 rnd_slowextract = 1; 412 } 413 414 static inline void 415 _rs_stir_if_needed(size_t len) 416 { 417 static int rs_initialized; 418 419 if (!rs_initialized) { 420 memcpy(entropy_pool, entropy_pool0, sizeof(entropy_pool)); 421 memcpy(rs_buf, rs_buf0, sizeof(rs_buf)); 422 /* seeds cannot be cleaned yet, random_start() will do so */ 423 _rs_init(rs_buf, KEYSZ + IVSZ); 424 rs_count = 1024 * 1024 * 1024; /* until main() runs */ 425 rs_initialized = 1; 426 } else if (rs_count <= len) 427 _rs_stir(0); 428 else 429 rs_count -= len; 430 } 431 432 static void 433 _rs_clearseed(const void *p, size_t s) 434 { 435 struct kmem_dyn_mode kd_avoidalias; 436 vaddr_t va = trunc_page((vaddr_t)p); 437 vsize_t off = (vaddr_t)p - va; 438 vsize_t len; 439 vaddr_t rwva; 440 paddr_t pa; 441 442 while (s > 0) { 443 pmap_extract(pmap_kernel(), va, &pa); 444 445 memset(&kd_avoidalias, 0, sizeof(kd_avoidalias)); 446 kd_avoidalias.kd_prefer = pa; 447 kd_avoidalias.kd_waitok = 1; 448 rwva = (vaddr_t)km_alloc(PAGE_SIZE, &kv_any, &kp_none, 449 &kd_avoidalias); 450 if (!rwva) 451 panic("_rs_clearseed"); 452 453 pmap_kenter_pa(rwva, pa, PROT_READ | PROT_WRITE); 454 pmap_update(pmap_kernel()); 455 456 len = MIN(s, PAGE_SIZE - off); 457 explicit_bzero((void *)(rwva + off), len); 458 459 pmap_kremove(rwva, PAGE_SIZE); 460 km_free((void *)rwva, PAGE_SIZE, &kv_any, &kp_none); 461 462 va += PAGE_SIZE; 463 s -= len; 464 off = 0; 465 } 466 } 467 468 static inline void 469 _rs_rekey(u_char *dat, size_t datlen) 470 { 471 #ifndef KEYSTREAM_ONLY 472 memset(rs_buf, 0, sizeof(rs_buf)); 473 #endif 474 /* fill rs_buf with the keystream */ 475 chacha_encrypt_bytes(&rs, rs_buf, rs_buf, sizeof(rs_buf)); 476 /* mix in optional user provided data */ 477 if (dat) { 478 size_t i, m; 479 480 m = MIN(datlen, KEYSZ + IVSZ); 481 for (i = 0; i < m; i++) 482 rs_buf[i] ^= dat[i]; 483 } 484 /* immediately reinit for backtracking resistance */ 485 _rs_init(rs_buf, KEYSZ + IVSZ); 486 memset(rs_buf, 0, KEYSZ + IVSZ); 487 rs_have = sizeof(rs_buf) - KEYSZ - IVSZ; 488 } 489 490 static inline void 491 _rs_random_buf(void *_buf, size_t n) 492 { 493 u_char *buf = (u_char *)_buf; 494 size_t m; 495 496 _rs_stir_if_needed(n); 497 while (n > 0) { 498 if (rs_have > 0) { 499 m = MIN(n, rs_have); 500 memcpy(buf, rs_buf + sizeof(rs_buf) - rs_have, m); 501 memset(rs_buf + sizeof(rs_buf) - rs_have, 0, m); 502 buf += m; 503 n -= m; 504 rs_have -= m; 505 } 506 if (rs_have == 0) 507 _rs_rekey(NULL, 0); 508 } 509 } 510 511 static inline void 512 _rs_random_u32(u_int32_t *val) 513 { 514 _rs_stir_if_needed(sizeof(*val)); 515 if (rs_have < sizeof(*val)) 516 _rs_rekey(NULL, 0); 517 memcpy(val, rs_buf + sizeof(rs_buf) - rs_have, sizeof(*val)); 518 memset(rs_buf + sizeof(rs_buf) - rs_have, 0, sizeof(*val)); 519 rs_have -= sizeof(*val); 520 } 521 522 /* Return one word of randomness from a ChaCha20 generator */ 523 u_int32_t 524 arc4random(void) 525 { 526 u_int32_t ret; 527 528 mtx_enter(&rndlock); 529 _rs_random_u32(&ret); 530 mtx_leave(&rndlock); 531 return ret; 532 } 533 534 /* 535 * Fill a buffer of arbitrary length with ChaCha20-derived randomness. 536 */ 537 void 538 arc4random_buf(void *buf, size_t n) 539 { 540 mtx_enter(&rndlock); 541 _rs_random_buf(buf, n); 542 mtx_leave(&rndlock); 543 } 544 545 /* 546 * Allocate a new ChaCha20 context for the caller to use. 547 */ 548 struct arc4random_ctx * 549 arc4random_ctx_new(void) 550 { 551 char keybuf[KEYSZ + IVSZ]; 552 553 chacha_ctx *ctx = malloc(sizeof(chacha_ctx), M_TEMP, M_WAITOK); 554 arc4random_buf(keybuf, KEYSZ + IVSZ); 555 chacha_keysetup(ctx, keybuf, KEYSZ * 8); 556 chacha_ivsetup(ctx, keybuf + KEYSZ, NULL); 557 explicit_bzero(keybuf, sizeof(keybuf)); 558 return (struct arc4random_ctx *)ctx; 559 } 560 561 /* 562 * Free a ChaCha20 context created by arc4random_ctx_new() 563 */ 564 void 565 arc4random_ctx_free(struct arc4random_ctx *ctx) 566 { 567 explicit_bzero(ctx, sizeof(chacha_ctx)); 568 free(ctx, M_TEMP, sizeof(chacha_ctx)); 569 } 570 571 /* 572 * Use a given ChaCha20 context to fill a buffer 573 */ 574 void 575 arc4random_ctx_buf(struct arc4random_ctx *ctx, void *buf, size_t n) 576 { 577 #ifndef KEYSTREAM_ONLY 578 memset(buf, 0, n); 579 #endif 580 chacha_encrypt_bytes((chacha_ctx *)ctx, buf, buf, n); 581 } 582 583 /* 584 * Calculate a uniformly distributed random number less than upper_bound 585 * avoiding "modulo bias". 586 * 587 * Uniformity is achieved by generating new random numbers until the one 588 * returned is outside the range [0, 2**32 % upper_bound). This 589 * guarantees the selected random number will be inside 590 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) 591 * after reduction modulo upper_bound. 592 */ 593 u_int32_t 594 arc4random_uniform(u_int32_t upper_bound) 595 { 596 u_int32_t r, min; 597 598 if (upper_bound < 2) 599 return 0; 600 601 /* 2**32 % x == (2**32 - x) % x */ 602 min = -upper_bound % upper_bound; 603 604 /* 605 * This could theoretically loop forever but each retry has 606 * p > 0.5 (worst case, usually far better) of selecting a 607 * number inside the range we need, so it should rarely need 608 * to re-roll. 609 */ 610 for (;;) { 611 r = arc4random(); 612 if (r >= min) 613 break; 614 } 615 616 return r % upper_bound; 617 } 618 619 void 620 rnd_init(void *null) 621 { 622 _rs_stir(1); 623 } 624 625 /* 626 * Called by timeout to mark arc4 for stirring, 627 */ 628 void 629 rnd_reinit(void *v) 630 { 631 task_add(systq, &rnd_task); 632 /* 10 minutes, per dm@'s suggestion */ 633 timeout_add_sec(&rndreinit_timeout, 10 * 60); 634 } 635 636 /* 637 * Start periodic services inside the random subsystem, which pull 638 * entropy forward, hash it, and re-seed the random stream as needed. 639 */ 640 void 641 random_start(int goodseed) 642 { 643 extern char etext[]; 644 645 #if !defined(NO_PROPOLICE) 646 extern long __guard_local; 647 648 if (__guard_local == 0) 649 printf("warning: no entropy supplied by boot loader\n"); 650 #endif 651 652 _rs_clearseed(entropy_pool0, sizeof(entropy_pool0)); 653 _rs_clearseed(rs_buf0, sizeof(rs_buf0)); 654 655 /* Message buffer may contain data from previous boot */ 656 if (msgbufp->msg_magic == MSG_MAGIC) 657 add_entropy_words((u_int32_t *)msgbufp->msg_bufc, 658 msgbufp->msg_bufs / sizeof(u_int32_t)); 659 add_entropy_words((u_int32_t *)etext - 32*1024, 660 8192/sizeof(u_int32_t)); 661 662 dequeue_randomness(NULL); 663 rnd_init(NULL); 664 rnd_reinit(NULL); 665 666 if (goodseed) 667 printf("random: good seed from bootblocks\n"); 668 else { 669 /* XXX kernel should work harder here */ 670 printf("random: boothowto does not indicate good seed\n"); 671 } 672 } 673 674 int 675 randomopen(dev_t dev, int flag, int mode, struct proc *p) 676 { 677 return 0; 678 } 679 680 int 681 randomclose(dev_t dev, int flag, int mode, struct proc *p) 682 { 683 return 0; 684 } 685 686 /* 687 * Maximum number of bytes to serve directly from the main ChaCha 688 * pool. Larger requests are served from a discrete ChaCha instance keyed 689 * from the main pool. 690 */ 691 #define RND_MAIN_MAX_BYTES 2048 692 693 int 694 randomread(dev_t dev, struct uio *uio, int ioflag) 695 { 696 struct arc4random_ctx *lctx = NULL; 697 size_t total = uio->uio_resid; 698 u_char *buf; 699 int ret = 0; 700 701 if (uio->uio_resid == 0) 702 return 0; 703 704 buf = malloc(POOLBYTES, M_TEMP, M_WAITOK); 705 if (total > RND_MAIN_MAX_BYTES) 706 lctx = arc4random_ctx_new(); 707 708 while (ret == 0 && uio->uio_resid > 0) { 709 size_t n = ulmin(POOLBYTES, uio->uio_resid); 710 711 if (lctx != NULL) 712 arc4random_ctx_buf(lctx, buf, n); 713 else 714 arc4random_buf(buf, n); 715 ret = uiomove(buf, n, uio); 716 if (ret == 0 && uio->uio_resid > 0) 717 yield(); 718 } 719 if (lctx != NULL) 720 arc4random_ctx_free(lctx); 721 explicit_bzero(buf, POOLBYTES); 722 free(buf, M_TEMP, POOLBYTES); 723 return ret; 724 } 725 726 int 727 randomwrite(dev_t dev, struct uio *uio, int flags) 728 { 729 int ret = 0, newdata = 0; 730 u_int32_t *buf; 731 732 if (uio->uio_resid == 0) 733 return 0; 734 735 buf = malloc(POOLBYTES, M_TEMP, M_WAITOK); 736 737 while (ret == 0 && uio->uio_resid > 0) { 738 size_t n = ulmin(POOLBYTES, uio->uio_resid); 739 740 ret = uiomove(buf, n, uio); 741 if (ret != 0) 742 break; 743 while (n % sizeof(u_int32_t)) 744 ((u_int8_t *)buf)[n++] = 0; 745 add_entropy_words(buf, n / 4); 746 if (uio->uio_resid > 0) 747 yield(); 748 newdata = 1; 749 } 750 751 if (newdata) 752 rnd_init(NULL); 753 754 explicit_bzero(buf, POOLBYTES); 755 free(buf, M_TEMP, POOLBYTES); 756 return ret; 757 } 758 759 int 760 randomkqfilter(dev_t dev, struct knote *kn) 761 { 762 switch (kn->kn_filter) { 763 case EVFILT_READ: 764 kn->kn_fop = &randomread_filtops; 765 break; 766 case EVFILT_WRITE: 767 kn->kn_fop = &randomwrite_filtops; 768 break; 769 default: 770 return (EINVAL); 771 } 772 773 return (0); 774 } 775 776 void 777 filt_randomdetach(struct knote *kn) 778 { 779 } 780 781 int 782 filt_randomread(struct knote *kn, long hint) 783 { 784 kn->kn_data = RND_MAIN_MAX_BYTES; 785 return (1); 786 } 787 788 int 789 filt_randomwrite(struct knote *kn, long hint) 790 { 791 kn->kn_data = POOLBYTES; 792 return (1); 793 } 794 795 int 796 randomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 797 { 798 switch (cmd) { 799 case FIOASYNC: 800 /* No async flag in softc so this is a no-op. */ 801 break; 802 default: 803 return ENOTTY; 804 } 805 return 0; 806 } 807 808 int 809 sys_getentropy(struct proc *p, void *v, register_t *retval) 810 { 811 struct sys_getentropy_args /* { 812 syscallarg(void *) buf; 813 syscallarg(size_t) nbyte; 814 } */ *uap = v; 815 char buf[GETENTROPY_MAX]; 816 int error; 817 818 if (SCARG(uap, nbyte) > sizeof(buf)) 819 return (EINVAL); 820 arc4random_buf(buf, SCARG(uap, nbyte)); 821 if ((error = copyout(buf, SCARG(uap, buf), SCARG(uap, nbyte))) != 0) 822 return (error); 823 explicit_bzero(buf, sizeof(buf)); 824 *retval = 0; 825 return (0); 826 } 827