randomdev.c (253845) | randomdev.c (254147) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2013 Arthur Mesh <arthurmesh@gmail.com> |
|
2 * Copyright (c) 2000-2004 Mark R V Murray 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 --- 11 unchanged lines hidden (view full) --- 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 28#include <sys/cdefs.h> | 3 * Copyright (c) 2000-2004 Mark R V Murray 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 unchanged lines hidden (view full) --- 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#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/dev/random/randomdev.c 253845 2013-07-31 17:21:18Z obrien $"); | 30__FBSDID("$FreeBSD: head/sys/dev/random/randomdev.c 254147 2013-08-09 15:31:50Z obrien $"); |
30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/bus.h> 34#include <sys/conf.h> 35#include <sys/fcntl.h> 36#include <sys/filio.h> 37#include <sys/kernel.h> --- 27 unchanged lines hidden (view full) --- 65 .d_close = random_close, 66 .d_read = random_read, 67 .d_write = random_write, 68 .d_ioctl = random_ioctl, 69 .d_poll = random_poll, 70 .d_name = "random", 71}; 72 | 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/bus.h> 35#include <sys/conf.h> 36#include <sys/fcntl.h> 37#include <sys/filio.h> 38#include <sys/kernel.h> --- 27 unchanged lines hidden (view full) --- 66 .d_close = random_close, 67 .d_read = random_read, 68 .d_write = random_write, 69 .d_ioctl = random_ioctl, 70 .d_poll = random_poll, 71 .d_name = "random", 72}; 73 |
73struct random_systat *random_systat; | 74static struct random_adaptor *random_adaptor; 75static eventhandler_tag attach_tag; 76static int random_inited; |
74 | 77 |
78 |
|
75/* For use with make_dev(9)/destroy_dev(9). */ 76static struct cdev *random_dev; 77 | 79/* For use with make_dev(9)/destroy_dev(9). */ 80static struct cdev *random_dev; 81 |
78/* Used to fake out unused random calls in random_systat */ | 82/* Used to fake out unused random calls in random_adaptor */ |
79void 80random_null_func(void) 81{ 82} 83 84/* ARGSUSED */ 85static int 86random_close(struct cdev *dev __unused, int flags, int fmt __unused, 87 struct thread *td) 88{ 89 if ((flags & FWRITE) && (priv_check(td, PRIV_RANDOM_RESEED) == 0) 90 && (securelevel_gt(td->td_ucred, 0) == 0)) { | 83void 84random_null_func(void) 85{ 86} 87 88/* ARGSUSED */ 89static int 90random_close(struct cdev *dev __unused, int flags, int fmt __unused, 91 struct thread *td) 92{ 93 if ((flags & FWRITE) && (priv_check(td, PRIV_RANDOM_RESEED) == 0) 94 && (securelevel_gt(td->td_ucred, 0) == 0)) { |
91 (*random_systat->reseed)(); 92 random_systat->seeded = 1; | 95 (*random_adaptor->reseed)(); 96 random_adaptor->seeded = 1; |
93 arc4rand(NULL, 0, 1); /* Reseed arc4random as well. */ 94 } 95 96 return (0); 97} 98 99/* ARGSUSED */ 100static int 101random_read(struct cdev *dev __unused, struct uio *uio, int flag) 102{ 103 int c, error = 0; 104 void *random_buf; 105 106 /* Blocking logic */ | 97 arc4rand(NULL, 0, 1); /* Reseed arc4random as well. */ 98 } 99 100 return (0); 101} 102 103/* ARGSUSED */ 104static int 105random_read(struct cdev *dev __unused, struct uio *uio, int flag) 106{ 107 int c, error = 0; 108 void *random_buf; 109 110 /* Blocking logic */ |
107 if (!random_systat->seeded) 108 error = (*random_systat->block)(flag); | 111 if (!random_adaptor->seeded) 112 error = (*random_adaptor->block)(flag); |
109 110 /* The actual read */ 111 if (!error) { 112 113 random_buf = (void *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 114 115 while (uio->uio_resid > 0 && !error) { 116 c = MIN(uio->uio_resid, PAGE_SIZE); | 113 114 /* The actual read */ 115 if (!error) { 116 117 random_buf = (void *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 118 119 while (uio->uio_resid > 0 && !error) { 120 c = MIN(uio->uio_resid, PAGE_SIZE); |
117 c = (*random_systat->read)(random_buf, c); | 121 c = (*random_adaptor->read)(random_buf, c); |
118 error = uiomove(random_buf, c, uio); 119 } 120 121 free(random_buf, M_TEMP); 122 123 } 124 125 return (error); --- 8 unchanged lines hidden (view full) --- 134 135 random_buf = (void *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 136 137 while (uio->uio_resid > 0) { 138 c = MIN((int)uio->uio_resid, PAGE_SIZE); 139 error = uiomove(random_buf, c, uio); 140 if (error) 141 break; | 122 error = uiomove(random_buf, c, uio); 123 } 124 125 free(random_buf, M_TEMP); 126 127 } 128 129 return (error); --- 8 unchanged lines hidden (view full) --- 138 139 random_buf = (void *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK); 140 141 while (uio->uio_resid > 0) { 142 c = MIN((int)uio->uio_resid, PAGE_SIZE); 143 error = uiomove(random_buf, c, uio); 144 if (error) 145 break; |
142 (*random_systat->write)(random_buf, c); | 146 (*random_adaptor->write)(random_buf, c); |
143 } 144 145 free(random_buf, M_TEMP); 146 147 return (error); 148} 149 150/* ARGSUSED */ --- 16 unchanged lines hidden (view full) --- 167 168/* ARGSUSED */ 169static int 170random_poll(struct cdev *dev __unused, int events, struct thread *td) 171{ 172 int revents = 0; 173 174 if (events & (POLLIN | POLLRDNORM)) { | 147 } 148 149 free(random_buf, M_TEMP); 150 151 return (error); 152} 153 154/* ARGSUSED */ --- 16 unchanged lines hidden (view full) --- 171 172/* ARGSUSED */ 173static int 174random_poll(struct cdev *dev __unused, int events, struct thread *td) 175{ 176 int revents = 0; 177 178 if (events & (POLLIN | POLLRDNORM)) { |
175 if (random_systat->seeded) | 179 if (random_adaptor->seeded) |
176 revents = events & (POLLIN | POLLRDNORM); 177 else | 180 revents = events & (POLLIN | POLLRDNORM); 181 else |
178 revents = (*random_systat->poll) (events,td); | 182 revents = (*random_adaptor->poll) (events,td); |
179 } 180 return (revents); 181} 182 | 183 } 184 return (revents); 185} 186 |
187static void 188random_initialize(void *p, struct random_adaptor *s) 189{ 190 if (random_inited) { 191 printf("random: <%s> already initialized\n", 192 random_adaptor->ident); 193 return; 194 } 195 196 random_adaptor = s; 197 198 (s->init)(); 199 200 printf("random: <%s> initialized\n", s->ident); 201 202 random_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &random_cdevsw, 203 RANDOM_MINOR, NULL, UID_ROOT, GID_WHEEL, 0666, "random"); 204 make_dev_alias(random_dev, "urandom"); /* XXX Deprecated */ 205 206 /* mark random(4) as initialized, to avoid being called again */ 207 random_inited = 1; 208} 209 |
|
183/* ARGSUSED */ 184static int 185random_modevent(module_t mod __unused, int type, void *data __unused) 186{ 187 int error = 0; 188 189 switch (type) { 190 case MOD_LOAD: | 210/* ARGSUSED */ 211static int 212random_modevent(module_t mod __unused, int type, void *data __unused) 213{ 214 int error = 0; 215 216 switch (type) { 217 case MOD_LOAD: |
191 random_ident_hardware(&random_systat); 192 (*random_systat->init)(); | 218 random_ident_hardware(&random_adaptor); |
193 | 219 |
194 if (bootverbose) 195 printf("random: <entropy source, %s>\n", 196 random_systat->ident); | 220 if (random_adaptor == NULL) { 221 printf( 222 "random: No random adaptor attached, postponing initialization\n"); 223 attach_tag = EVENTHANDLER_REGISTER(random_adaptor_attach, 224 random_initialize, NULL, EVENTHANDLER_PRI_ANY); 225 } else { 226 random_initialize(NULL, random_adaptor); 227 } |
197 | 228 |
198 random_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &random_cdevsw, 199 RANDOM_MINOR, NULL, UID_ROOT, GID_WHEEL, 0666, "random"); 200 make_dev_alias(random_dev, "urandom"); /* XXX Deprecated */ 201 | |
202 break; 203 204 case MOD_UNLOAD: | 229 break; 230 231 case MOD_UNLOAD: |
205 (*random_systat->deinit)(); | 232 if (random_adaptor != NULL) { 233 (*random_adaptor->deinit)(); 234 destroy_dev(random_dev); 235 } 236 /* Unregister the event handler */ 237 if (attach_tag != NULL) { 238 EVENTHANDLER_DEREGISTER(random_adaptor_attach, 239 attach_tag); 240 } |
206 | 241 |
207 destroy_dev(random_dev); 208 | |
209 break; 210 211 case MOD_SHUTDOWN: 212 break; 213 214 default: 215 error = EOPNOTSUPP; 216 break; 217 218 } 219 return (error); 220} 221 222DEV_MODULE(random, random_modevent, NULL); 223MODULE_VERSION(random, 1); | 242 break; 243 244 case MOD_SHUTDOWN: 245 break; 246 247 default: 248 error = EOPNOTSUPP; 249 break; 250 251 } 252 return (error); 253} 254 255DEV_MODULE(random, random_modevent, NULL); 256MODULE_VERSION(random, 1); |