1 /*- 2 * Copyright (c) 2000-2013 Mark R V Murray 3 * Copyright (c) 2013 Arthur Mesh <arthurmesh@gmail.com> 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 * NOTE NOTE NOTE 31 * 32 * This file is compiled into the kernel unconditionally. Any random(4) 33 * infrastructure that needs to be in the kernel by default goes here! 34 * 35 * Except ... 36 * 37 * The adaptor code all goes into random_adaptor.c, which is also compiled 38 * the kernel by default. The module in that file is initialised before 39 * this one. 40 * 41 * Other modules must be initialised after the above two, and are 42 * software random processors which plug into random_adaptor.c. 43 * 44 */ 45 46 #include <sys/cdefs.h> 47 __FBSDID("$FreeBSD$"); 48 49 #include "opt_random.h" 50 51 #include <sys/param.h> 52 #include <sys/systm.h> 53 #include <sys/bus.h> 54 #include <sys/conf.h> 55 #include <sys/fcntl.h> 56 #include <sys/filio.h> 57 #include <sys/kernel.h> 58 #include <sys/kthread.h> 59 #include <sys/lock.h> 60 #include <sys/module.h> 61 #include <sys/malloc.h> 62 #include <sys/proc.h> 63 #include <sys/random.h> 64 #include <sys/sysctl.h> 65 #include <sys/systm.h> 66 #include <sys/uio.h> 67 #include <sys/unistd.h> 68 69 #include <dev/random/randomdev.h> 70 #include <dev/random/random_adaptors.h> 71 #include <dev/random/random_harvestq.h> 72 73 #define RANDOM_MINOR 0 74 75 static d_ioctl_t randomdev_ioctl; 76 77 static struct cdevsw random_cdevsw = { 78 .d_name = "random", 79 .d_version = D_VERSION, 80 .d_read = random_adaptor_read, 81 .d_write = random_adaptor_write, 82 .d_poll = random_adaptor_poll, 83 .d_ioctl = randomdev_ioctl, 84 }; 85 86 /* For use with make_dev(9)/destroy_dev(9). */ 87 static struct cdev *random_dev; 88 89 /* Set up the sysctl root node for the entropy device */ 90 SYSCTL_NODE(_kern, OID_AUTO, random, CTLFLAG_RW, 0, "Random Number Generator"); 91 92 MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers and data structures"); 93 94 /* ARGSUSED */ 95 static int 96 randomdev_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t addr __unused, 97 int flags __unused, struct thread *td __unused) 98 { 99 int error = 0; 100 101 switch (cmd) { 102 /* Really handled in upper layer */ 103 case FIOASYNC: 104 case FIONBIO: 105 break; 106 107 default: 108 error = ENOTTY; 109 110 } 111 112 return (error); 113 } 114 115 /* Helper routine to enable kproc_exit() to work while the module is 116 * being (or has been) unloaded. 117 * This routine is in this file because it is always linked into the kernel, 118 * and will thus never be unloaded. This is critical for unloadable modules 119 * that have threads. 120 */ 121 void 122 randomdev_set_wakeup_exit(void *control) 123 { 124 125 wakeup(control); 126 kproc_exit(0); 127 /* NOTREACHED */ 128 } 129 130 /* ARGSUSED */ 131 static int 132 randomdev_modevent(module_t mod __unused, int type, void *data __unused) 133 { 134 int error = 0; 135 136 switch (type) { 137 case MOD_LOAD: 138 printf("random: entropy device infrastructure driver\n"); 139 random_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &random_cdevsw, 140 RANDOM_MINOR, NULL, UID_ROOT, GID_WHEEL, 0644, "random"); 141 make_dev_alias(random_dev, "urandom"); /* compatibility */ 142 random_adaptors_init(); 143 break; 144 145 case MOD_UNLOAD: 146 random_adaptors_deinit(); 147 destroy_dev(random_dev); 148 break; 149 150 case MOD_SHUTDOWN: 151 break; 152 153 default: 154 error = EOPNOTSUPP; 155 break; 156 157 } 158 159 return (error); 160 } 161 162 DEV_MODULE_ORDERED(randomdev, randomdev_modevent, NULL, SI_ORDER_SECOND); 163 MODULE_VERSION(randomdev, 1); 164 165 /* ================ 166 * Harvesting stubs 167 * ================ 168 */ 169 170 /* Internal stub/fake routine for when no entropy processor is loaded. 171 * If the entropy device is not loaded, don't act on harvesting calls 172 * and just return. 173 */ 174 /* ARGSUSED */ 175 static void 176 random_harvest_phony(const void *entropy __unused, u_int count __unused, 177 u_int bits __unused, enum random_entropy_source origin __unused) 178 { 179 } 180 181 /* Hold the address of the routine which is actually called */ 182 static void (*reap_func)(const void *, u_int, u_int, enum random_entropy_source) = random_harvest_phony; 183 184 /* Initialise the harvester when/if it is loaded */ 185 void 186 randomdev_init_harvester(void (*reaper)(const void *, u_int, u_int, enum random_entropy_source)) 187 { 188 189 reap_func = reaper; 190 } 191 192 /* Deinitialise the harvester when/if it is unloaded */ 193 void 194 randomdev_deinit_harvester(void) 195 { 196 197 reap_func = random_harvest_phony; 198 } 199 200 /* Entropy harvesting routine. 201 * Implemented as in indirect call to allow non-inclusion of 202 * the entropy device. 203 */ 204 void 205 random_harvest(const void *entropy, u_int count, u_int bits, enum random_entropy_source origin) 206 { 207 208 (*reap_func)(entropy, count, bits, origin); 209 } 210 211 /* ================================ 212 * Internal reading stubs and fakes 213 * ================================ 214 */ 215 216 /* Hold the address of the routine which is actually called */ 217 static u_int (*read_func)(uint8_t *, u_int) = dummy_random_read_phony; 218 219 /* Initialise the reader when/if it is loaded */ 220 void 221 randomdev_init_reader(u_int (*reader)(uint8_t *, u_int)) 222 { 223 224 read_func = reader; 225 } 226 227 /* Deinitialise the reader when/if it is unloaded */ 228 void 229 randomdev_deinit_reader(void) 230 { 231 232 read_func = dummy_random_read_phony; 233 } 234 235 /* Kernel API version of read_random(). 236 * Implemented as in indirect call to allow non-inclusion of 237 * the entropy device. 238 */ 239 int 240 read_random(void *buf, int count) 241 { 242 243 return ((int)(*read_func)(buf, (u_int)count)); 244 } 245