random(4): Gather entropy from Pure sources
At initialization, hc_source_mask only includes non-Pure sources. The patch changes source registration to enable the registered source in the hc_source_mask bitmask. This mask governs which sources are harvested. This patch also disallows userspace from disabling such sources. PR: 222807 Submitted by: W. Dean Freeman <badfilemagic AT gmail.com> Reviewed by: jmg (earlier version), delphij Approved by: secteam (delphij) Obtained from: HBSD 0054e3e170e083811acc9f3b637f8be8a86c03e7 Security: yes Differential Revision: https://reviews.freebsd.org/D12611
This commit is contained in:
parent
f04c11c32b
commit
095db7e6e7
@ -1,4 +1,6 @@
|
|||||||
/*-
|
/*-
|
||||||
|
* Copyright (c) 2017 Oliver Pinter
|
||||||
|
* Copyright (c) 2017 W. Dean Freeman
|
||||||
* Copyright (c) 2000-2015 Mark R V Murray
|
* Copyright (c) 2000-2015 Mark R V Murray
|
||||||
* Copyright (c) 2013 Arthur Mesh
|
* Copyright (c) 2013 Arthur Mesh
|
||||||
* Copyright (c) 2004 Robert N. M. Watson
|
* Copyright (c) 2004 Robert N. M. Watson
|
||||||
@ -240,7 +242,27 @@ read_rate_increment(u_int chunk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
RANDOM_CHECK_UINT(harvestmask, 0, RANDOM_HARVEST_EVERYTHING_MASK);
|
static int
|
||||||
|
random_check_uint_harvestmask(SYSCTL_HANDLER_ARGS)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
u_int value, orig_value;
|
||||||
|
|
||||||
|
orig_value = value = harvest_context.hc_source_mask;
|
||||||
|
error = sysctl_handle_int(oidp, &value, 0, req);
|
||||||
|
if (error != 0 || req->newptr == NULL)
|
||||||
|
return (error);
|
||||||
|
|
||||||
|
if (flsl(value) > ENTROPYSOURCE)
|
||||||
|
return (EINVAL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disallow userspace modification of pure entropy sources.
|
||||||
|
*/
|
||||||
|
harvest_context.hc_source_mask = (value & ~RANDOM_HARVEST_PURE_MASK) |
|
||||||
|
(orig_value & RANDOM_HARVEST_PURE_MASK);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
@ -252,7 +274,7 @@ random_print_harvestmask(SYSCTL_HANDLER_ARGS)
|
|||||||
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 = RANDOM_ENVIRONMENTAL_END; i >= 0; i--)
|
for (i = ENTROPYSOURCE - 1; i >= 0; i--)
|
||||||
sbuf_cat(&sbuf, (harvest_context.hc_source_mask & (1 << i)) ? "1" : "0");
|
sbuf_cat(&sbuf, (harvest_context.hc_source_mask & (1 << i)) ? "1" : "0");
|
||||||
error = sbuf_finish(&sbuf);
|
error = sbuf_finish(&sbuf);
|
||||||
sbuf_delete(&sbuf);
|
sbuf_delete(&sbuf);
|
||||||
@ -272,7 +294,7 @@ static const char *random_source_descr[ENTROPYSOURCE] = {
|
|||||||
[RANDOM_SWI] = "SWI",
|
[RANDOM_SWI] = "SWI",
|
||||||
[RANDOM_FS_ATIME] = "FS_ATIME",
|
[RANDOM_FS_ATIME] = "FS_ATIME",
|
||||||
[RANDOM_UMA] = "UMA", /* ENVIRONMENTAL_END */
|
[RANDOM_UMA] = "UMA", /* ENVIRONMENTAL_END */
|
||||||
[RANDOM_PURE_OCTEON] = "PURE_OCTEON",
|
[RANDOM_PURE_OCTEON] = "PURE_OCTEON", /* PURE_START */
|
||||||
[RANDOM_PURE_SAFE] = "PURE_SAFE",
|
[RANDOM_PURE_SAFE] = "PURE_SAFE",
|
||||||
[RANDOM_PURE_GLXSB] = "PURE_GLXSB",
|
[RANDOM_PURE_GLXSB] = "PURE_GLXSB",
|
||||||
[RANDOM_PURE_UBSEC] = "PURE_UBSEC",
|
[RANDOM_PURE_UBSEC] = "PURE_UBSEC",
|
||||||
@ -291,15 +313,22 @@ random_print_harvestmask_symbolic(SYSCTL_HANDLER_ARGS)
|
|||||||
{
|
{
|
||||||
struct sbuf sbuf;
|
struct sbuf sbuf;
|
||||||
int error, i;
|
int error, i;
|
||||||
|
bool first;
|
||||||
|
|
||||||
|
first = true;
|
||||||
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 = RANDOM_ENVIRONMENTAL_END; i >= 0; i--) {
|
for (i = ENTROPYSOURCE - 1; i >= 0; i--) {
|
||||||
sbuf_cat(&sbuf, (i == RANDOM_ENVIRONMENTAL_END) ? "" : ",");
|
if (i >= RANDOM_PURE_START &&
|
||||||
|
(harvest_context.hc_source_mask & (1 << i)) == 0)
|
||||||
|
continue;
|
||||||
|
if (!first)
|
||||||
|
sbuf_cat(&sbuf, ",");
|
||||||
sbuf_cat(&sbuf, !(harvest_context.hc_source_mask & (1 << i)) ? "[" : "");
|
sbuf_cat(&sbuf, !(harvest_context.hc_source_mask & (1 << i)) ? "[" : "");
|
||||||
sbuf_cat(&sbuf, random_source_descr[i]);
|
sbuf_cat(&sbuf, random_source_descr[i]);
|
||||||
sbuf_cat(&sbuf, !(harvest_context.hc_source_mask & (1 << i)) ? "]" : "");
|
sbuf_cat(&sbuf, !(harvest_context.hc_source_mask & (1 << i)) ? "]" : "");
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
error = sbuf_finish(&sbuf);
|
error = sbuf_finish(&sbuf);
|
||||||
sbuf_delete(&sbuf);
|
sbuf_delete(&sbuf);
|
||||||
@ -321,8 +350,7 @@ random_harvestq_init(void *unused __unused)
|
|||||||
SYSCTL_ADD_PROC(&random_clist,
|
SYSCTL_ADD_PROC(&random_clist,
|
||||||
SYSCTL_CHILDREN(random_sys_o),
|
SYSCTL_CHILDREN(random_sys_o),
|
||||||
OID_AUTO, "mask", CTLTYPE_UINT | CTLFLAG_RW,
|
OID_AUTO, "mask", CTLTYPE_UINT | CTLFLAG_RW,
|
||||||
&harvest_context.hc_source_mask, 0,
|
NULL, 0, random_check_uint_harvestmask, "IU",
|
||||||
random_check_uint_harvestmask, "IU",
|
|
||||||
"Entropy harvesting mask");
|
"Entropy harvesting mask");
|
||||||
SYSCTL_ADD_PROC(&random_clist,
|
SYSCTL_ADD_PROC(&random_clist,
|
||||||
SYSCTL_CHILDREN(random_sys_o),
|
SYSCTL_CHILDREN(random_sys_o),
|
||||||
@ -495,4 +523,18 @@ random_harvest_direct(const void *entropy, u_int size, u_int bits, enum random_e
|
|||||||
explicit_bzero(&event, sizeof(event));
|
explicit_bzero(&event, sizeof(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
random_harvest_register_source(enum random_entropy_source source)
|
||||||
|
{
|
||||||
|
|
||||||
|
harvest_context.hc_source_mask |= (1 << source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
random_harvest_deregister_source(enum random_entropy_source source)
|
||||||
|
{
|
||||||
|
|
||||||
|
harvest_context.hc_source_mask &= ~(1 << source);
|
||||||
|
}
|
||||||
|
|
||||||
MODULE_VERSION(random_harvestq, 1);
|
MODULE_VERSION(random_harvestq, 1);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
|
* Copyright (c) 2017 Oliver Pinter
|
||||||
* Copyright (c) 2000-2015 Mark R V Murray
|
* Copyright (c) 2000-2015 Mark R V Murray
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@ -321,6 +322,8 @@ random_source_register(struct random_source *rsource)
|
|||||||
rrs = malloc(sizeof(*rrs), M_ENTROPY, M_WAITOK);
|
rrs = malloc(sizeof(*rrs), M_ENTROPY, M_WAITOK);
|
||||||
rrs->rrs_source = rsource;
|
rrs->rrs_source = rsource;
|
||||||
|
|
||||||
|
random_harvest_register_source(rsource->rs_source);
|
||||||
|
|
||||||
printf("random: registering fast source %s\n", rsource->rs_ident);
|
printf("random: registering fast source %s\n", rsource->rs_ident);
|
||||||
LIST_INSERT_HEAD(&source_list, rrs, rrs_entries);
|
LIST_INSERT_HEAD(&source_list, rrs, rrs_entries);
|
||||||
}
|
}
|
||||||
@ -331,6 +334,9 @@ random_source_deregister(struct random_source *rsource)
|
|||||||
struct random_sources *rrs = NULL;
|
struct random_sources *rrs = NULL;
|
||||||
|
|
||||||
KASSERT(rsource != NULL, ("invalid input to %s", __func__));
|
KASSERT(rsource != NULL, ("invalid input to %s", __func__));
|
||||||
|
|
||||||
|
random_harvest_deregister_source(rsource->rs_source);
|
||||||
|
|
||||||
LIST_FOREACH(rrs, &source_list, rrs_entries)
|
LIST_FOREACH(rrs, &source_list, rrs_entries)
|
||||||
if (rrs->rrs_source == rsource) {
|
if (rrs->rrs_source == rsource) {
|
||||||
LIST_REMOVE(rrs, rrs_entries);
|
LIST_REMOVE(rrs, rrs_entries);
|
||||||
|
@ -81,7 +81,8 @@ enum random_entropy_source {
|
|||||||
RANDOM_UMA, /* Special!! UMA/SLAB Allocator */
|
RANDOM_UMA, /* Special!! UMA/SLAB Allocator */
|
||||||
RANDOM_ENVIRONMENTAL_END = RANDOM_UMA,
|
RANDOM_ENVIRONMENTAL_END = RANDOM_UMA,
|
||||||
/* Fast hardware random-number sources from here on. */
|
/* Fast hardware random-number sources from here on. */
|
||||||
RANDOM_PURE_OCTEON,
|
RANDOM_PURE_START,
|
||||||
|
RANDOM_PURE_OCTEON = RANDOM_PURE_START,
|
||||||
RANDOM_PURE_SAFE,
|
RANDOM_PURE_SAFE,
|
||||||
RANDOM_PURE_GLXSB,
|
RANDOM_PURE_GLXSB,
|
||||||
RANDOM_PURE_UBSEC,
|
RANDOM_PURE_UBSEC,
|
||||||
@ -95,6 +96,7 @@ enum random_entropy_source {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define RANDOM_HARVEST_EVERYTHING_MASK ((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1)
|
#define RANDOM_HARVEST_EVERYTHING_MASK ((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1)
|
||||||
|
#define RANDOM_HARVEST_PURE_MASK (((1 << ENTROPYSOURCE) - 1) & (-1UL << RANDOM_PURE_START))
|
||||||
|
|
||||||
#define RANDOM_LEGACY_BOOT_ENTROPY_MODULE "/boot/entropy"
|
#define RANDOM_LEGACY_BOOT_ENTROPY_MODULE "/boot/entropy"
|
||||||
#define RANDOM_CACHED_BOOT_ENTROPY_MODULE "boot_entropy_cache"
|
#define RANDOM_CACHED_BOOT_ENTROPY_MODULE "boot_entropy_cache"
|
||||||
@ -104,10 +106,14 @@ enum random_entropy_source {
|
|||||||
void random_harvest_queue(const void *, u_int, u_int, enum random_entropy_source);
|
void random_harvest_queue(const void *, u_int, u_int, enum random_entropy_source);
|
||||||
void random_harvest_fast(const void *, u_int, u_int, enum random_entropy_source);
|
void random_harvest_fast(const void *, u_int, u_int, enum random_entropy_source);
|
||||||
void random_harvest_direct(const void *, u_int, u_int, enum random_entropy_source);
|
void random_harvest_direct(const void *, u_int, u_int, enum random_entropy_source);
|
||||||
|
void random_harvest_register_source(enum random_entropy_source);
|
||||||
|
void random_harvest_deregister_source(enum random_entropy_source);
|
||||||
#else
|
#else
|
||||||
#define random_harvest_queue(a, b, c, d) do {} while (0)
|
#define random_harvest_queue(a, b, c, d) do {} while (0)
|
||||||
#define random_harvest_fast(a, b, c, d) do {} while (0)
|
#define random_harvest_fast(a, b, c, d) do {} while (0)
|
||||||
#define random_harvest_direct(a, b, c, d) do {} while (0)
|
#define random_harvest_direct(a, b, c, d) do {} while (0)
|
||||||
|
#define random_harvest_register_source(a) do {} while (0)
|
||||||
|
#define random_harvest_deregister_source(a) do {} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(RANDOM_ENABLE_UMA)
|
#if defined(RANDOM_ENABLE_UMA)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user