]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/random/pseudo_rng.c
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[FreeBSD/stable/10.git] / sys / dev / random / pseudo_rng.c
1 /*-
2  * Copyright (c) 2013 Arthur Mesh <arthurmesh@gmail.com>
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 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/param.h>
31 #include <sys/time.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/selinfo.h>
35 #include <sys/systm.h>
36
37 #include <dev/random/random_adaptors.h>
38 #include <dev/random/randomdev.h>
39
40 static struct mtx       pseudo_random_block_mtx;
41
42 /* Used to fake out unused random calls in random_adaptor */
43 void
44 random_null_func(void)
45 {
46 }
47
48 static int
49 pseudo_random_block_read(void *buf __unused, int c __unused)
50 {
51
52         mtx_lock(&pseudo_random_block_mtx);
53
54         printf("random(4) device is blocking.\n");
55         msleep(pseudo_random_block_read, &pseudo_random_block_mtx, 0,
56             "block", 0);
57
58         mtx_unlock(&pseudo_random_block_mtx);
59
60         return (0);
61 }
62
63 static void
64 pseudo_random_block_init(void)
65 {
66
67         mtx_init(&pseudo_random_block_mtx, "sleep mtx for random_block",
68             NULL, MTX_DEF);
69 }
70
71 static void
72 pseudo_random_block_deinit(void)
73 {
74
75         mtx_destroy(&pseudo_random_block_mtx);
76 }
77
78 struct random_adaptor pseudo_random_block = {
79         .ident = "pseudo-RNG that always blocks",
80         .init = pseudo_random_block_init,
81         .deinit = pseudo_random_block_deinit,
82         .read = pseudo_random_block_read,
83         .write = (random_write_func_t *)random_null_func,
84         .reseed = (random_reseed_func_t *)random_null_func,
85         .seeded = 1,
86 };
87
88 static int
89 pseudo_random_panic_read(void *buf, int c)
90 {
91
92         panic("Insert a witty panic msg in here.");
93
94         return (0);
95 }
96
97 struct random_adaptor pseudo_random_panic = {
98         .ident = "pseudo-RNG that always panics on first read(2)",
99         .init = (random_init_func_t *)random_null_func,
100         .deinit = (random_deinit_func_t *)random_null_func,
101         .read = pseudo_random_panic_read,
102         .write = (random_write_func_t *)random_null_func,
103         .reseed = (random_reseed_func_t *)random_null_func,
104         .seeded = 1,
105 };
106
107 static int
108 pseudo_random_modevent(module_t mod, int type, void *unused)
109 {
110
111         switch (type) {
112         case MOD_LOAD:
113                 random_adaptor_register("block", &pseudo_random_block);
114                 EVENTHANDLER_INVOKE(random_adaptor_attach,
115                     &pseudo_random_block);
116
117                 random_adaptor_register("panic", &pseudo_random_panic);
118
119                 return (0);
120         }
121
122         return (EINVAL);
123 }
124
125 RANDOM_ADAPTOR_MODULE(pseudo, pseudo_random_modevent, 1);