This source file includes following definitions.
- roll
- rnd_get
- rnd_put
- rnd_qlen
- arc4_getbyte
- arc4_stir
- arc4maybeinit
- arc4_reinit
- arc4random
- arc4random_bytes
- randomattach
- randomopen
- randomclose
- add_entropy_words
- enqueue_randomness
- dequeue_randomness
- extract_entropy
- get_random_bytes
- randomread
- randompoll
- randomkqfilter
- filt_rndrdetach
- filt_rndread
- filt_rndwdetach
- filt_rndwrite
- randomwrite
- randomioctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237 #undef RNDEBUG
238
239 #include <sys/param.h>
240 #include <sys/systm.h>
241 #include <sys/conf.h>
242 #include <sys/disk.h>
243 #include <sys/ioctl.h>
244 #include <sys/malloc.h>
245 #include <sys/fcntl.h>
246 #include <sys/vnode.h>
247 #include <sys/sysctl.h>
248 #include <sys/timeout.h>
249 #include <sys/poll.h>
250
251 #include <crypto/md5.h>
252
253 #include <dev/rndvar.h>
254 #include <dev/rndioctl.h>
255
256 #ifdef RNDEBUG
257 int rnd_debug = 0x0000;
258 #define RD_INPUT 0x000f
259 #define RD_OUTPUT 0x00f0
260 #define RD_WAIT 0x0100
261 #endif
262
263
264
265
266
267
268 #define POOLBITS (POOLWORDS*32)
269 #define POOLBYTES (POOLWORDS*4)
270 #if POOLWORDS == 2048
271 #define TAP1 1638
272 #define TAP2 1231
273 #define TAP3 819
274 #define TAP4 411
275 #define TAP5 1
276 #elif POOLWORDS == 1024
277 #define TAP1 817
278 #define TAP2 615
279 #define TAP3 412
280 #define TAP4 204
281 #define TAP5 1
282 #elif POOLWORDS == 512
283 #define TAP1 411
284 #define TAP2 308
285 #define TAP3 208
286 #define TAP4 104
287 #define TAP5 1
288 #elif POOLWORDS == 256
289 #define TAP1 205
290 #define TAP2 155
291 #define TAP3 101
292 #define TAP4 52
293 #define TAP5 1
294 #elif POOLWORDS == 128
295 #define TAP1 103
296 #define TAP2 76
297 #define TAP3 51
298 #define TAP4 25
299 #define TAP5 1
300 #elif POOLWORDS == 64
301 #define TAP1 52
302 #define TAP2 39
303 #define TAP3 26
304 #define TAP4 14
305 #define TAP5 1
306 #elif POOLWORDS == 32
307 #define TAP1 26
308 #define TAP2 20
309 #define TAP3 14
310 #define TAP4 7
311 #define TAP5 1
312 #else
313 #error No primitive polynomial available for chosen POOLWORDS
314 #endif
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360 #define QEVLEN (1024 / sizeof(struct rand_event))
361 #define QEVSLOW (QEVLEN * 3 / 4)
362 #define QEVSBITS 10
363
364
365 struct random_bucket {
366 u_int add_ptr;
367 u_int entropy_count;
368 u_char input_rotate;
369 u_int32_t pool[POOLWORDS];
370 u_int asleep;
371 u_int tmo;
372 };
373
374
375 struct timer_rand_state {
376 u_int last_time;
377 u_int last_delta;
378 u_int last_delta2;
379 u_int dont_count_entropy : 1;
380 u_int max_entropy : 1;
381 };
382
383 struct arc4_stream {
384 u_int8_t s[256];
385 u_int cnt;
386 u_int8_t i;
387 u_int8_t j;
388 };
389
390 struct rand_event {
391 struct timer_rand_state *re_state;
392 u_int re_nbits;
393 u_int re_time;
394 u_int re_val;
395 };
396
397 struct timeout rnd_timeout, arc4_timeout;
398 struct random_bucket random_state;
399 struct arc4_stream arc4random_state;
400 struct timer_rand_state rnd_states[RND_SRC_NUM];
401 struct rand_event rnd_event_space[QEVLEN];
402 struct rand_event *rnd_event_head = rnd_event_space;
403 struct rand_event *rnd_event_tail = rnd_event_space;
404 struct selinfo rnd_rsel, rnd_wsel;
405
406 void filt_rndrdetach(struct knote *kn);
407 int filt_rndread(struct knote *kn, long hint);
408
409 struct filterops rndread_filtops =
410 { 1, NULL, filt_rndrdetach, filt_rndread};
411
412 void filt_rndwdetach(struct knote *kn);
413 int filt_rndwrite(struct knote *kn, long hint);
414
415 struct filterops rndwrite_filtops =
416 { 1, NULL, filt_rndwdetach, filt_rndwrite};
417
418 int rnd_attached;
419 int arc4random_initialized;
420 struct rndstats rndstats;
421
422 static __inline u_int32_t roll(u_int32_t w, int i)
423 {
424 #ifdef i386
425 __asm ("roll %%cl, %0" : "+r" (w) : "c" (i));
426 #else
427 w = (w << i) | (w >> (32 - i));
428 #endif
429 return w;
430 }
431
432
433 static __inline struct rand_event *
434 rnd_get(void)
435 {
436 struct rand_event *p = rnd_event_tail;
437
438 if (p == rnd_event_head)
439 return NULL;
440
441 if (p + 1 >= &rnd_event_space[QEVLEN])
442 rnd_event_tail = rnd_event_space;
443 else
444 rnd_event_tail++;
445
446 return p;
447 }
448
449
450 static __inline struct rand_event *
451 rnd_put(void)
452 {
453 struct rand_event *p = rnd_event_head + 1;
454
455 if (p >= &rnd_event_space[QEVLEN])
456 p = rnd_event_space;
457
458 if (p == rnd_event_tail)
459 return NULL;
460
461 return rnd_event_head = p;
462 }
463
464
465 static __inline int
466 rnd_qlen(void)
467 {
468 int len = rnd_event_head - rnd_event_tail;
469 return (len < 0)? -len : len;
470 }
471
472 void dequeue_randomness(void *);
473
474 static void add_entropy_words(const u_int32_t *, u_int n);
475 void extract_entropy(u_int8_t *, int);
476
477 static u_int8_t arc4_getbyte(void);
478 void arc4_stir(void);
479 void arc4_reinit(void *v);
480 void arc4maybeinit(void);
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500 static u_int8_t
501 arc4_getbyte(void)
502 {
503 u_int8_t si, sj, ret;
504 int s;
505
506 s = splhigh();
507 rndstats.arc4_reads++;
508 arc4random_state.cnt++;
509 arc4random_state.i++;
510 si = arc4random_state.s[arc4random_state.i];
511 arc4random_state.j += si;
512 sj = arc4random_state.s[arc4random_state.j];
513 arc4random_state.s[arc4random_state.i] = sj;
514 arc4random_state.s[arc4random_state.j] = si;
515 ret = arc4random_state.s[(si + sj) & 0xff];
516 splx(s);
517 return (ret);
518 }
519
520 void
521 arc4_stir(void)
522 {
523 u_int8_t buf[256];
524 u_int8_t si;
525 int n, s;
526 int len;
527
528 nanotime((struct timespec *) buf);
529 len = random_state.entropy_count / 8;
530 if (len > sizeof(buf) - sizeof(struct timeval))
531 len = sizeof(buf) - sizeof(struct timeval);
532 get_random_bytes(buf + sizeof (struct timeval), len);
533 len += sizeof(struct timeval);
534
535 s = splhigh();
536 arc4random_state.i--;
537 for (n = 0; n < 256; n++) {
538 arc4random_state.i++;
539 si = arc4random_state.s[arc4random_state.i];
540 arc4random_state.j += si + buf[n % len];
541 arc4random_state.s[arc4random_state.i] =
542 arc4random_state.s[arc4random_state.j];
543 arc4random_state.s[arc4random_state.j] = si;
544 }
545 arc4random_state.j = arc4random_state.i;
546 arc4random_state.cnt = 0;
547 rndstats.arc4_stirs += len;
548 rndstats.arc4_nstirs++;
549 splx(s);
550
551
552
553
554
555
556 for (n = 0; n < 256 * 4; n++)
557 arc4_getbyte();
558 }
559
560 void
561 arc4maybeinit(void)
562 {
563 extern int hz;
564
565 if (!arc4random_initialized) {
566 #ifdef DIAGNOSTIC
567 if (!rnd_attached)
568 panic("arc4maybeinit: premature");
569 #endif
570 arc4random_initialized++;
571 arc4_stir();
572
573 timeout_add(&arc4_timeout, 10 * 60 * hz);
574 }
575 }
576
577
578
579
580
581 void
582 arc4_reinit(void *v)
583 {
584 arc4random_initialized = 0;
585 }
586
587 u_int32_t
588 arc4random(void)
589 {
590 arc4maybeinit();
591 return ((arc4_getbyte() << 24) | (arc4_getbyte() << 16)
592 | (arc4_getbyte() << 8) | arc4_getbyte());
593 }
594
595 void
596 arc4random_bytes(void *buf, size_t n)
597 {
598 u_int8_t *cp = buf;
599 u_int8_t *end = cp + n;
600
601 arc4maybeinit();
602 while (cp < end)
603 *cp++ = arc4_getbyte();
604 }
605
606 void
607 randomattach(void)
608 {
609 int i;
610
611 if (rnd_attached) {
612 #ifdef RNDEBUG
613 printf("random: second attach\n");
614 #endif
615 return;
616 }
617
618 timeout_set(&rnd_timeout, dequeue_randomness, &random_state);
619 timeout_set(&arc4_timeout, arc4_reinit, NULL);
620
621 random_state.add_ptr = 0;
622 random_state.entropy_count = 0;
623 rnd_states[RND_SRC_TIMER].dont_count_entropy = 1;
624 rnd_states[RND_SRC_TRUE].dont_count_entropy = 1;
625 rnd_states[RND_SRC_TRUE].max_entropy = 1;
626
627 bzero(&rndstats, sizeof(rndstats));
628 bzero(&rnd_event_space, sizeof(rnd_event_space));
629
630 for (i = 0; i < 256; i++)
631 arc4random_state.s[i] = i;
632 arc4_reinit(NULL);
633
634 rnd_attached = 1;
635 }
636
637 int
638 randomopen(dev_t dev, int flag, int mode, struct proc *p)
639 {
640 return (minor (dev) < RND_NODEV) ? 0 : ENXIO;
641 }
642
643 int
644 randomclose(dev_t dev, int flag, int mode, struct proc *p)
645 {
646 return 0;
647 }
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663 static void
664 add_entropy_words(const u_int32_t *buf, u_int n)
665 {
666 static const u_int32_t twist_table[8] = {
667 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
668 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278
669 };
670
671 for (; n--; buf++) {
672 u_int32_t w = roll(*buf, random_state.input_rotate);
673 u_int i = random_state.add_ptr =
674 (random_state.add_ptr - 1) & (POOLWORDS - 1);
675
676
677
678
679
680
681 random_state.input_rotate =
682 (random_state.input_rotate + (i? 7 : 14)) & 31;
683
684
685 w ^= random_state.pool[(i+TAP1) & (POOLWORDS-1)] ^
686 random_state.pool[(i+TAP2) & (POOLWORDS-1)] ^
687 random_state.pool[(i+TAP3) & (POOLWORDS-1)] ^
688 random_state.pool[(i+TAP4) & (POOLWORDS-1)] ^
689 random_state.pool[(i+TAP5) & (POOLWORDS-1)] ^
690 random_state.pool[i];
691 random_state.pool[i] = (w >> 3) ^ twist_table[w & 7];
692 }
693 }
694
695
696
697
698
699
700
701
702
703
704
705
706
707 void
708 enqueue_randomness(int state, int val)
709 {
710 struct timer_rand_state *p;
711 struct rand_event *rep;
712 struct timespec tv;
713 u_int time, nbits;
714 int s;
715
716
717 if (!rnd_attached)
718 return;
719
720 #ifdef DIAGNOSTIC
721 if (state < 0 || state >= RND_SRC_NUM)
722 return;
723 #endif
724
725 p = &rnd_states[state];
726 val += state << 13;
727
728 nanotime(&tv);
729 time = (tv.tv_nsec >> 10) + (tv.tv_sec << 20);
730 nbits = 0;
731
732
733
734
735
736
737 if (!p->dont_count_entropy) {
738 int delta, delta2, delta3;
739 delta = time - p->last_time;
740 delta2 = delta - p->last_delta;
741 delta3 = delta2 - p->last_delta2;
742
743 if (delta < 0) delta = -delta;
744 if (delta2 < 0) delta2 = -delta2;
745 if (delta3 < 0) delta3 = -delta3;
746 if (delta > delta2) delta = delta2;
747 if (delta > delta3) delta = delta3;
748 delta3 = delta >>= 1;
749
750
751
752
753
754 if (delta & 0xffff0000) {
755 nbits = 16;
756 delta >>= 16;
757 }
758 if (delta & 0xff00) {
759 nbits += 8;
760 delta >>= 8;
761 }
762 if (delta & 0xf0) {
763 nbits += 4;
764 delta >>= 4;
765 }
766 if (delta & 0xc) {
767 nbits += 2;
768 delta >>= 2;
769 }
770 if (delta & 2) {
771 nbits += 1;
772 delta >>= 1;
773 }
774 if (delta & 1)
775 nbits++;
776
777
778
779
780
781 if (rnd_qlen() > QEVSLOW && nbits < QEVSBITS) {
782 rndstats.rnd_drople++;
783 return;
784 }
785 p->last_time = time;
786 p->last_delta = delta3;
787 p->last_delta2 = delta2;
788 } else if (p->max_entropy)
789 nbits = 8 * sizeof(val) - 1;
790
791 s = splhigh();
792 if ((rep = rnd_put()) == NULL) {
793 rndstats.rnd_drops++;
794 splx(s);
795 return;
796 }
797
798 rep->re_state = p;
799 rep->re_nbits = nbits;
800 rep->re_time = tv.tv_nsec ^ (tv.tv_sec << 20);
801 rep->re_val = val;
802
803 rndstats.rnd_enqs++;
804 rndstats.rnd_ed[nbits]++;
805 rndstats.rnd_sc[state]++;
806 rndstats.rnd_sb[state] += nbits;
807
808 if (rnd_qlen() > QEVSLOW/2 && !random_state.tmo) {
809 random_state.tmo++;
810 timeout_add(&rnd_timeout, 1);
811 }
812 splx(s);
813 }
814
815 void
816 dequeue_randomness(void *v)
817 {
818 struct random_bucket *rs = v;
819 struct rand_event *rep;
820 u_int32_t buf[2];
821 u_int nbits;
822 int s;
823
824 timeout_del(&rnd_timeout);
825 rndstats.rnd_deqs++;
826
827 s = splhigh();
828 while ((rep = rnd_get())) {
829
830 buf[0] = rep->re_time;
831 buf[1] = rep->re_val;
832 nbits = rep->re_nbits;
833 splx(s);
834
835 add_entropy_words(buf, 2);
836
837 rndstats.rnd_total += nbits;
838 rs->entropy_count += nbits;
839 if (rs->entropy_count > POOLBITS)
840 rs->entropy_count = POOLBITS;
841
842 if (rs->asleep && rs->entropy_count > 8) {
843 #ifdef RNDEBUG
844 if (rnd_debug & RD_WAIT)
845 printf("rnd: wakeup[%u]{%u}\n",
846 rs->asleep,
847 rs->entropy_count);
848 #endif
849 rs->asleep--;
850 wakeup((void *)&rs->asleep);
851 selwakeup(&rnd_rsel);
852 KNOTE(&rnd_rsel.si_note, 0);
853 }
854
855 s = splhigh();
856 }
857
858 rs->tmo = 0;
859 splx(s);
860 }
861
862 #if POOLWORDS % 16
863 #error extract_entropy() assumes that POOLWORDS is a multiple of 16 words.
864 #endif
865
866
867
868
869
870
871
872 void
873 extract_entropy(u_int8_t *buf, int nbytes)
874 {
875 struct random_bucket *rs = &random_state;
876 u_char buffer[16];
877 MD5_CTX tmp;
878 u_int i;
879 int s;
880
881 add_timer_randomness(nbytes);
882
883 while (nbytes) {
884 if (nbytes < sizeof(buffer) / 2)
885 i = nbytes;
886 else
887 i = sizeof(buffer) / 2;
888
889
890 MD5Init(&tmp);
891 s = splhigh();
892 MD5Update(&tmp, (u_int8_t*)rs->pool, sizeof(rs->pool));
893 if (rs->entropy_count / 8 > i)
894 rs->entropy_count -= i * 8;
895 else
896 rs->entropy_count = 0;
897 splx(s);
898 MD5Final(buffer, &tmp);
899
900
901
902
903
904 buffer[0] ^= buffer[15];
905 buffer[1] ^= buffer[14];
906 buffer[2] ^= buffer[13];
907 buffer[3] ^= buffer[12];
908 buffer[4] ^= buffer[11];
909 buffer[5] ^= buffer[10];
910 buffer[6] ^= buffer[ 9];
911 buffer[7] ^= buffer[ 8];
912
913
914 bcopy(buffer, buf, i);
915 nbytes -= i;
916 buf += i;
917
918
919 add_timer_randomness(nbytes);
920 dequeue_randomness(&random_state);
921 }
922
923
924 bzero(&tmp, sizeof(tmp));
925 bzero(&buffer, sizeof(buffer));
926 }
927
928
929
930
931
932
933 void
934 get_random_bytes(void *buf, size_t nbytes)
935 {
936 extract_entropy((u_int8_t *) buf, nbytes);
937 rndstats.rnd_used += nbytes * 8;
938 }
939
940 int
941 randomread(dev_t dev, struct uio *uio, int ioflag)
942 {
943 int ret = 0;
944 int i;
945 u_int32_t *buf;
946
947 if (uio->uio_resid == 0)
948 return 0;
949
950 MALLOC(buf, u_int32_t *, POOLBYTES, M_TEMP, M_WAITOK);
951
952 while (!ret && uio->uio_resid > 0) {
953 int n = min(POOLBYTES, uio->uio_resid);
954
955 switch(minor(dev)) {
956 case RND_RND:
957 ret = EIO;
958 break;
959 case RND_SRND:
960 if (random_state.entropy_count < 16 * 8) {
961 if (ioflag & IO_NDELAY) {
962 ret = EWOULDBLOCK;
963 break;
964 }
965 #ifdef RNDEBUG
966 if (rnd_debug & RD_WAIT)
967 printf("rnd: sleep[%u]\n",
968 random_state.asleep);
969 #endif
970 random_state.asleep++;
971 rndstats.rnd_waits++;
972 ret = tsleep(&random_state.asleep,
973 PWAIT | PCATCH, "rndrd", 0);
974 #ifdef RNDEBUG
975 if (rnd_debug & RD_WAIT)
976 printf("rnd: awakened(%d)\n", ret);
977 #endif
978 if (ret)
979 break;
980 }
981 if (n > random_state.entropy_count / 8)
982 n = random_state.entropy_count / 8;
983 rndstats.rnd_reads++;
984 #ifdef RNDEBUG
985 if (rnd_debug & RD_OUTPUT)
986 printf("rnd: %u possible output\n", n);
987 #endif
988 case RND_URND:
989 get_random_bytes((char *)buf, n);
990 #ifdef RNDEBUG
991 if (rnd_debug & RD_OUTPUT)
992 printf("rnd: %u bytes for output\n", n);
993 #endif
994 break;
995 case RND_PRND:
996 i = (n + 3) / 4;
997 while (i--)
998 buf[i] = random() << 16 | (random() & 0xFFFF);
999 break;
1000 case RND_ARND:
1001 {
1002 u_int8_t *cp = (u_int8_t *) buf;
1003 u_int8_t *end = cp + n;
1004 arc4maybeinit();
1005 while (cp < end)
1006 *cp++ = arc4_getbyte();
1007 break;
1008 }
1009 default:
1010 ret = ENXIO;
1011 }
1012 if (n != 0 && ret == 0)
1013 ret = uiomove((caddr_t)buf, n, uio);
1014 }
1015
1016 FREE(buf, M_TEMP);
1017 return ret;
1018 }
1019
1020 int
1021 randompoll(dev_t dev, int events, struct proc *p)
1022 {
1023 int revents;
1024
1025 revents = events & (POLLOUT | POLLWRNORM);
1026 if (events & (POLLIN | POLLRDNORM)) {
1027 if (minor(dev) == RND_SRND && random_state.entropy_count <= 0)
1028 selrecord(p, &rnd_rsel);
1029 else
1030 revents |= events & (POLLIN | POLLRDNORM);
1031 }
1032
1033 return (revents);
1034 }
1035
1036 int
1037 randomkqfilter(dev_t dev, struct knote *kn)
1038 {
1039 struct klist *klist;
1040 int s;
1041
1042 switch (kn->kn_filter) {
1043 case EVFILT_READ:
1044 klist = &rnd_rsel.si_note;
1045 kn->kn_fop = &rndread_filtops;
1046 break;
1047 case EVFILT_WRITE:
1048 klist = &rnd_wsel.si_note;
1049 kn->kn_fop = &rndwrite_filtops;
1050 break;
1051 default:
1052 return (1);
1053 }
1054 kn->kn_hook = (void *)&random_state;
1055
1056 s = splhigh();
1057 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1058 splx(s);
1059
1060 return (0);
1061 }
1062
1063 void
1064 filt_rndrdetach(struct knote *kn)
1065 {
1066 int s = splhigh();
1067
1068 SLIST_REMOVE(&rnd_rsel.si_note, kn, knote, kn_selnext);
1069 splx(s);
1070 }
1071
1072 int
1073 filt_rndread(struct knote *kn, long hint)
1074 {
1075 struct random_bucket *rs = (struct random_bucket *)kn->kn_hook;
1076
1077 kn->kn_data = (int)rs->entropy_count;
1078 return rs->entropy_count > 0;
1079 }
1080
1081 void
1082 filt_rndwdetach(struct knote *kn)
1083 {
1084 int s = splhigh();
1085
1086 SLIST_REMOVE(&rnd_wsel.si_note, kn, knote, kn_selnext);
1087 splx(s);
1088 }
1089
1090 int
1091 filt_rndwrite(struct knote *kn, long hint)
1092 {
1093 return (1);
1094 }
1095
1096 int
1097 randomwrite(dev_t dev, struct uio *uio, int flags)
1098 {
1099 int ret = 0;
1100 u_int32_t *buf;
1101
1102 if (minor(dev) == RND_RND || minor(dev) == RND_PRND)
1103 return ENXIO;
1104
1105 if (uio->uio_resid == 0)
1106 return 0;
1107
1108 MALLOC(buf, u_int32_t *, POOLBYTES, M_TEMP, M_WAITOK);
1109
1110 while (!ret && uio->uio_resid > 0) {
1111 u_short n = min(POOLBYTES, uio->uio_resid);
1112
1113 ret = uiomove((caddr_t)buf, n, uio);
1114 if (!ret) {
1115 while (n % sizeof(u_int32_t))
1116 ((u_int8_t *) buf)[n++] = 0;
1117 add_entropy_words(buf, n / 4);
1118 }
1119 }
1120
1121 if (minor(dev) == RND_ARND && !ret)
1122 arc4random_initialized = 0;
1123
1124 FREE(buf, M_TEMP);
1125 return ret;
1126 }
1127
1128 int
1129 randomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
1130 {
1131 int s, ret = 0;
1132 u_int cnt;
1133
1134 add_timer_randomness((u_long)p ^ (u_long)data ^ cmd);
1135
1136 switch (cmd) {
1137 case FIOASYNC:
1138
1139 break;
1140
1141 case FIONBIO:
1142
1143 break;
1144
1145 case RNDGETENTCNT:
1146 s = splhigh();
1147 *(u_int *)data = random_state.entropy_count;
1148 splx(s);
1149 break;
1150 case RNDADDTOENTCNT:
1151 if (suser(p, 0) != 0)
1152 ret = EPERM;
1153 else {
1154 cnt = *(u_int *)data;
1155 s = splhigh();
1156 random_state.entropy_count += cnt;
1157 if (random_state.entropy_count > POOLBITS)
1158 random_state.entropy_count = POOLBITS;
1159 splx(s);
1160 }
1161 break;
1162 case RNDZAPENTCNT:
1163 if (suser(p, 0) != 0)
1164 ret = EPERM;
1165 else {
1166 s = splhigh();
1167 random_state.entropy_count = 0;
1168 splx(s);
1169 }
1170 break;
1171 case RNDSTIRARC4:
1172 if (suser(p, 0) != 0)
1173 ret = EPERM;
1174 else if (random_state.entropy_count < 64)
1175 ret = EAGAIN;
1176 else {
1177 s = splhigh();
1178 arc4random_initialized = 0;
1179 splx(s);
1180 }
1181 break;
1182 case RNDCLRSTATS:
1183 if (suser(p, 0) != 0)
1184 ret = EPERM;
1185 else {
1186 s = splhigh();
1187 bzero(&rndstats, sizeof(rndstats));
1188 splx(s);
1189 }
1190 break;
1191 default:
1192 ret = ENOTTY;
1193 }
1194
1195 add_timer_randomness((u_long)p ^ (u_long)data ^ cmd);
1196 return ret;
1197 }