Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/random/random_harvestq.c
Show First 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
#define _RANDOM_HARVEST_UMA_OFF (1u << RANDOM_UMA) | #define _RANDOM_HARVEST_UMA_OFF (1u << RANDOM_UMA) | ||||
#endif | #endif | ||||
static void random_kthread(void); | static void random_kthread(void); | ||||
static void random_sources_feed(void); | static void random_sources_feed(void); | ||||
static u_int read_rate; | static u_int read_rate; | ||||
/* List for the dynamic sysctls */ | |||||
static struct sysctl_ctx_list random_clist; | |||||
/* | /* | ||||
* How many events to queue up. We create this many items in | * How many events to queue up. We create this many items in | ||||
* an 'empty' queue, then transfer them to the 'harvest' queue with | * an 'empty' queue, then transfer them to the 'harvest' queue with | ||||
* supplied junk. When used, they are transferred back to the | * supplied junk. When used, they are transferred back to the | ||||
* 'empty' queue. | * 'empty' queue. | ||||
*/ | */ | ||||
#define RANDOM_RING_MAX 1024 | #define RANDOM_RING_MAX 1024 | ||||
#define RANDOM_ACCUM_MAX 8 | #define RANDOM_ACCUM_MAX 8 | ||||
/* 1 to let the kernel thread run, 0 to terminate, -1 to mark completion */ | /* 1 to let the kernel thread run, 0 to terminate, -1 to mark completion */ | ||||
volatile int random_kthread_control; | volatile int random_kthread_control; | ||||
/* Allow the sysadmin to select the broad category of | /* Allow the sysadmin to select the broad category of | ||||
* entropy types to harvest. | * entropy types to harvest. | ||||
*/ | */ | ||||
__read_frequently u_int hc_source_mask; | __read_frequently u_int hc_source_mask; | ||||
SYSCTL_NODE(_kern_random, OID_AUTO, harvest, CTLFLAG_RW, 0, | |||||
"Entropy Device Parameters"); | |||||
/* | /* | ||||
* Put all the harvest queue context stuff in one place. | * Put all the harvest queue context stuff in one place. | ||||
* this make is a bit easier to lock and protect. | * this make is a bit easier to lock and protect. | ||||
*/ | */ | ||||
static struct harvest_context { | static struct harvest_context { | ||||
/* The harvest mutex protects all of harvest_context and | /* The harvest mutex protects all of harvest_context and | ||||
* the related data. | * the related data. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 175 Lines • ▼ Show 20 Lines | random_check_uint_harvestmask(SYSCTL_HANDLER_ARGS) | ||||
/* | /* | ||||
* Disallow userspace modification of pure entropy sources. | * Disallow userspace modification of pure entropy sources. | ||||
*/ | */ | ||||
hc_source_mask = (value & ~user_immutable_mask) | | hc_source_mask = (value & ~user_immutable_mask) | | ||||
(orig_value & user_immutable_mask); | (orig_value & user_immutable_mask); | ||||
return (0); | return (0); | ||||
} | } | ||||
SYSCTL_PROC(_kern_random_harvest, OID_AUTO, mask, CTLTYPE_UINT | CTLFLAG_RW, | |||||
NULL, 0, random_check_uint_harvestmask, "IU", "Entropy harvesting mask"); | |||||
/* ARGSUSED */ | /* ARGSUSED */ | ||||
static int | static int | ||||
random_print_harvestmask(SYSCTL_HANDLER_ARGS) | random_print_harvestmask(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct sbuf sbuf; | struct sbuf sbuf; | ||||
int error, i; | int error, i; | ||||
error = sysctl_wire_old_buffer(req, 0); | error = sysctl_wire_old_buffer(req, 0); | ||||
if (error == 0) { | if (error == 0) { | ||||
sbuf_new_for_sysctl(&sbuf, NULL, 128, req); | sbuf_new_for_sysctl(&sbuf, NULL, 128, req); | ||||
for (i = ENTROPYSOURCE - 1; i >= 0; i--) | for (i = ENTROPYSOURCE - 1; i >= 0; i--) | ||||
sbuf_cat(&sbuf, (hc_source_mask & (1 << i)) ? "1" : "0"); | sbuf_cat(&sbuf, (hc_source_mask & (1 << i)) ? "1" : "0"); | ||||
error = sbuf_finish(&sbuf); | error = sbuf_finish(&sbuf); | ||||
sbuf_delete(&sbuf); | sbuf_delete(&sbuf); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_kern_random_harvest, OID_AUTO, mask_bin, | |||||
CTLTYPE_STRING | CTLFLAG_RD, NULL, 0, random_print_harvestmask, "A", | |||||
"Entropy harvesting mask (printable)"); | |||||
static const char *random_source_descr[ENTROPYSOURCE] = { | static const char *random_source_descr[ENTROPYSOURCE] = { | ||||
[RANDOM_CACHED] = "CACHED", | [RANDOM_CACHED] = "CACHED", | ||||
[RANDOM_ATTACH] = "ATTACH", | [RANDOM_ATTACH] = "ATTACH", | ||||
[RANDOM_KEYBOARD] = "KEYBOARD", | [RANDOM_KEYBOARD] = "KEYBOARD", | ||||
[RANDOM_MOUSE] = "MOUSE", | [RANDOM_MOUSE] = "MOUSE", | ||||
[RANDOM_NET_TUN] = "NET_TUN", | [RANDOM_NET_TUN] = "NET_TUN", | ||||
[RANDOM_NET_ETHER] = "NET_ETHER", | [RANDOM_NET_ETHER] = "NET_ETHER", | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | for (i = ENTROPYSOURCE - 1; i >= 0; i--) { | ||||
sbuf_cat(&sbuf, !(hc_source_mask & (1 << i)) ? "]" : ""); | sbuf_cat(&sbuf, !(hc_source_mask & (1 << i)) ? "]" : ""); | ||||
first = false; | first = false; | ||||
} | } | ||||
error = sbuf_finish(&sbuf); | error = sbuf_finish(&sbuf); | ||||
sbuf_delete(&sbuf); | sbuf_delete(&sbuf); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_kern_random_harvest, OID_AUTO, mask_symbolic, | |||||
CTLTYPE_STRING | CTLFLAG_RD, NULL, 0, random_print_harvestmask_symbolic, | |||||
"A", "Entropy harvesting mask (symbolic)"); | |||||
/* ARGSUSED */ | /* ARGSUSED */ | ||||
static void | static void | ||||
random_harvestq_init(void *unused __unused) | random_harvestq_init(void *unused __unused) | ||||
{ | { | ||||
static const u_int almost_everything_mask = | static const u_int almost_everything_mask = | ||||
(((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1) & | (((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1) & | ||||
~_RANDOM_HARVEST_ETHER_OFF & ~_RANDOM_HARVEST_UMA_OFF); | ~_RANDOM_HARVEST_ETHER_OFF & ~_RANDOM_HARVEST_UMA_OFF); | ||||
struct sysctl_oid *random_sys_o; | |||||
random_sys_o = SYSCTL_ADD_NODE(&random_clist, | |||||
SYSCTL_STATIC_CHILDREN(_kern_random), | |||||
OID_AUTO, "harvest", CTLFLAG_RW, 0, | |||||
"Entropy Device Parameters"); | |||||
hc_source_mask = almost_everything_mask; | hc_source_mask = almost_everything_mask; | ||||
SYSCTL_ADD_PROC(&random_clist, | |||||
SYSCTL_CHILDREN(random_sys_o), | |||||
OID_AUTO, "mask", CTLTYPE_UINT | CTLFLAG_RW, | |||||
NULL, 0, random_check_uint_harvestmask, "IU", | |||||
"Entropy harvesting mask"); | |||||
SYSCTL_ADD_PROC(&random_clist, | |||||
SYSCTL_CHILDREN(random_sys_o), | |||||
OID_AUTO, "mask_bin", CTLTYPE_STRING | CTLFLAG_RD, | |||||
NULL, 0, random_print_harvestmask, "A", "Entropy harvesting mask (printable)"); | |||||
SYSCTL_ADD_PROC(&random_clist, | |||||
SYSCTL_CHILDREN(random_sys_o), | |||||
OID_AUTO, "mask_symbolic", CTLTYPE_STRING | CTLFLAG_RD, | |||||
NULL, 0, random_print_harvestmask_symbolic, "A", "Entropy harvesting mask (symbolic)"); | |||||
RANDOM_HARVEST_INIT_LOCK(); | RANDOM_HARVEST_INIT_LOCK(); | ||||
harvest_context.hc_entropy_ring.in = harvest_context.hc_entropy_ring.out = 0; | harvest_context.hc_entropy_ring.in = harvest_context.hc_entropy_ring.out = 0; | ||||
} | } | ||||
SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_SECOND, random_harvestq_init, NULL); | SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_SECOND, random_harvestq_init, NULL); | ||||
/* | /* | ||||
* Subroutine to slice up a contiguous chunk of 'entropy' and feed it into the | * Subroutine to slice up a contiguous chunk of 'entropy' and feed it into the | ||||
* underlying algorithm. Returns number of bytes actually fed into underlying | * underlying algorithm. Returns number of bytes actually fed into underlying | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
random_harvestq_deinit(void *unused __unused) | random_harvestq_deinit(void *unused __unused) | ||||
{ | { | ||||
/* Command the hash/reseed thread to end and wait for it to finish */ | /* Command the hash/reseed thread to end and wait for it to finish */ | ||||
random_kthread_control = 0; | random_kthread_control = 0; | ||||
while (random_kthread_control >= 0) | while (random_kthread_control >= 0) | ||||
tsleep(&harvest_context.hc_kthread_proc, 0, "harvqterm", hz/5); | tsleep(&harvest_context.hc_kthread_proc, 0, "harvqterm", hz/5); | ||||
sysctl_ctx_free(&random_clist); | |||||
} | } | ||||
SYSUNINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_SECOND, random_harvestq_deinit, NULL); | SYSUNINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_SECOND, random_harvestq_deinit, NULL); | ||||
/*- | /*- | ||||
* Entropy harvesting queue routine. | * Entropy harvesting queue routine. | ||||
* | * | ||||
* This is supposed to be fast; do not do anything slow in here! | * This is supposed to be fast; do not do anything slow in here! | ||||
* It is also illegal (and morally reprehensible) to insert any | * It is also illegal (and morally reprehensible) to insert any | ||||
▲ Show 20 Lines • Show All 146 Lines • Show Last 20 Lines |