]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/random/randomdev_soft.c
Merge from head@274682
[FreeBSD/FreeBSD.git] / sys / dev / random / randomdev_soft.c
1 /*-
2  * Copyright (c) 2000-2014 Mark R V Murray
3  * Copyright (c) 2004 Robert N. M. Watson
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer
11  *    in this position and unchanged.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28
29 /*
30  * This is the loadable infrastructure base file for software CSPRNG
31  * drivers such as Yarrow or Fortuna.
32  *
33  * It is anticipated that one instance of this file will be used
34  * for _each_ invocation of a CSPRNG, but with different #defines
35  * set. See below.
36  *
37  */
38
39 #include "opt_random.h"
40
41 #if !defined(RANDOM_YARROW) && !defined(RANDOM_FORTUNA)
42 #define RANDOM_YARROW
43 #elif defined(RANDOM_YARROW) && defined(RANDOM_FORTUNA)
44 #error "Must define either RANDOM_YARROW or RANDOM_FORTUNA"
45 #endif
46
47 #include <sys/cdefs.h>
48 __FBSDID("$FreeBSD$");
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/conf.h>
53 #include <sys/fcntl.h>
54 #include <sys/kernel.h>
55 #include <sys/lock.h>
56 #include <sys/malloc.h>
57 #include <sys/module.h>
58 #include <sys/mutex.h>
59 #include <sys/poll.h>
60 #include <sys/random.h>
61 #include <sys/sysctl.h>
62 #include <sys/unistd.h>
63
64 #include <dev/random/randomdev.h>
65 #include <dev/random/randomdev_soft.h>
66 #include <dev/random/random_harvestq.h>
67 #include <dev/random/random_adaptors.h>
68 #if defined(RANDOM_YARROW)
69 #include <dev/random/yarrow.h>
70 #endif
71 #if defined(RANDOM_FORTUNA)
72 #include <dev/random/fortuna.h>
73 #endif
74
75 static struct random_adaptor random_soft_processor = {
76 #if defined(RANDOM_YARROW)
77 #define RANDOM_CSPRNG_NAME      "yarrow"
78         .ra_ident = "Yarrow",
79         .ra_priority = 90, /* High priority, so top of the list. Fortuna may still win. */
80         .ra_read = random_yarrow_read,
81         .ra_write = random_yarrow_write,
82         .ra_reseed = random_yarrow_reseed,
83         .ra_seeded = random_yarrow_seeded,
84 #endif
85 #if defined(RANDOM_FORTUNA)
86 #define RANDOM_CSPRNG_NAME      "fortuna"
87         .ra_ident = "Fortuna",
88         .ra_priority = 100, /* High priority, so top of the list. Beat Yarrow. */
89         .ra_read = random_fortuna_read,
90         .ra_write = random_fortuna_write,
91         .ra_reseed = random_fortuna_reseed,
92         .ra_seeded = random_fortuna_seeded,
93 #endif
94         .ra_init = randomdev_init,
95         .ra_deinit = randomdev_deinit,
96 };
97
98 void
99 randomdev_init(void)
100 {
101
102 #if defined(RANDOM_YARROW)
103         random_yarrow_init_alg();
104         random_harvestq_init(random_yarrow_process_event, 2);
105 #endif
106 #if defined(RANDOM_FORTUNA)
107         random_fortuna_init_alg();
108         random_harvestq_init(random_fortuna_process_event, 32);
109 #endif
110
111         /* Register the randomness harvesting routine */
112         randomdev_init_harvester(random_harvestq_internal);
113 }
114
115 void
116 randomdev_deinit(void)
117 {
118         /* Deregister the randomness harvesting routine */
119         randomdev_deinit_harvester();
120
121 #if defined(RANDOM_YARROW)
122         random_yarrow_deinit_alg();
123 #endif
124 #if defined(RANDOM_FORTUNA)
125         random_fortuna_deinit_alg();
126 #endif
127 }
128
129 /* ARGSUSED */
130 static int
131 randomdev_soft_modevent(module_t mod __unused, int type, void *unused __unused)
132 {
133         int error = 0;
134
135         switch (type) {
136         case MOD_LOAD:
137                 printf("random: SOFT: %s init()\n", RANDOM_CSPRNG_NAME);
138                 random_adaptor_register(RANDOM_CSPRNG_NAME, &random_soft_processor);
139                 break;
140
141         case MOD_UNLOAD:
142                 random_adaptor_deregister(RANDOM_CSPRNG_NAME);
143                 break;
144
145         case MOD_SHUTDOWN:
146                 break;
147
148         default:
149                 error = EOPNOTSUPP;
150                 break;
151
152         }
153         return (error);
154 }
155
156 #if defined(RANDOM_YARROW)
157 DEV_MODULE(yarrow, randomdev_soft_modevent, NULL);
158 MODULE_VERSION(yarrow, 1);
159 MODULE_DEPEND(yarrow, randomdev, 1, 1, 1);
160 #endif
161 #if defined(RANDOM_FORTUNA)
162 DEV_MODULE(fortuna, randomdev_soft_modevent, NULL);
163 MODULE_VERSION(fortuna, 1);
164 MODULE_DEPEND(fortuna, randomdev, 1, 1, 1);
165 #endif