Make the UMA harvesting go away completely if not wanted. Default to "not wanted".

Provide and document the RANDOM_ENABLE_UMA option.

Change RANDOM_FAST to RANDOM_UMA to clarify the harvesting.

Remove RANDOM_DEBUG option, replace with SDT probes. These will be of
use to folks measuring the harvesting effect when deciding whether to
use RANDOM_ENABLE_UMA.

Requested by:	scottl and others.
Approved by:	so (/dev/random blanket)
Differential Revision:    https://reviews.freebsd.org/D3197
This commit is contained in:
markm 2015-08-22 12:59:05 +00:00
parent 47e7b3851f
commit 8982309189
10 changed files with 61 additions and 43 deletions

View File

@ -32,6 +32,7 @@
.Sh SYNOPSIS
.Cd "device random"
.Cd "options RANDOM_LOADABLE"
.Cd "options RANDOM_ENABLE_UMA"
.Sh DESCRIPTION
The
.Nm
@ -177,6 +178,24 @@ must be locked against
load and unload events,
and also must be indirect calls
to allow for removal.
.Pp
When
.Cd "options RANDOM_ENABLE_UMA"
is used,
the
.Pa /dev/random
device will obtain entropy
from the zone allocator.
This is potentially very high rate,
and if so will be of questionable use.
If this is the case,
use of this option
is not recommended.
Determining this is not trivial,
so experimenting and measurement
using tools such as
.Xr dtrace 1
will be required.
.Sh RANDOMNESS
The use of randomness in the field of computing
is a rather subtle issue because randomness means

View File

@ -2985,8 +2985,10 @@ options MAXFILES=999
#options RANDOM_YARROW # Yarrow CSPRNG (old default)
#options RANDOM_LOADABLE # Allow the algorithm to be loaded as
# a module.
# For developers.
options RANDOM_DEBUG # Extra debugging messages
# Select this to allow high-rate but potentially expensive
# harvesting of Slab-Allocator entropy. In very high-rate
# situations the value of doing this is dubious at best.
options RANDOM_ENABLE_UMA # slab allocator
# Module to enable execution of application via emulators like QEMU
options IMAGACT_BINMISC

View File

@ -945,17 +945,16 @@ RACCT_DEFAULT_TO_DISABLED opt_global.h
RCTL opt_global.h
# Random number generator(s)
# The DEBUG option is in global.h as the random harvesting
# puts probes all over the place, and it makes little sense
# to pollute these headers with an extra include.
RANDOM_DEBUG opt_random.h
# Which CSPRNG hashes we get.
# Which CSPRNG hash we get.
# If Yarrow is not chosen, Fortuna is selected.
RANDOM_YARROW opt_random.h
# With this, no entropy processor is loaded, but the entropy
# harvesting infrastructure is present. This means an entropy
# processor may be loaded as a module.
RANDOM_LOADABLE opt_random.h
# This turns on high-rate and potentially expensive harvesting in
# the uma slab allocator.
RANDOM_ENABLE_UMA opt_global.h
# Intel em(4) driver
EM_MULTIQUEUE opt_em.h

View File

@ -35,7 +35,7 @@
# <(sed -e 's/fortuna/wombat/g' \
# -e 's/FORTUNA/WOMBAT/g' fortuna.c) | less
#
cc -g -O0 -pthread -DRANDOM_DEBUG \
cc -g -O0 -pthread \
-I../.. -lstdthreads -Wall \
unit_test.c \
yarrow.c \
@ -46,7 +46,7 @@ cc -g -O0 -pthread -DRANDOM_DEBUG \
../../crypto/sha2/sha256c.c \
-lz \
-o yunit_test
cc -g -O0 -pthread -DRANDOM_DEBUG \
cc -g -O0 -pthread \
-I../.. -lstdthreads -Wall \
unit_test.c \
fortuna.c \

View File

@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/random.h>
#include <sys/sdt.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
@ -94,6 +95,11 @@ CTASSERT(RANDOM_FORTUNA_DEFPOOLSIZE <= RANDOM_FORTUNA_MAXPOOLSIZE);
CTASSERT(RANDOM_BLOCKSIZE == sizeof(uint128_t));
CTASSERT(RANDOM_KEYSIZE == 2*RANDOM_BLOCKSIZE);
/* Probes for dtrace(1) */
SDT_PROVIDER_DECLARE(random);
SDT_PROVIDER_DEFINE(random);
SDT_PROBE_DEFINE2(random, fortuna, event_processor, debug, "u_int", "struct fs_pool *");
/*
* This is the beastie that needs protecting. It contains all of the
* state that we are excited about. Exactly one is instantiated.
@ -379,16 +385,7 @@ random_fortuna_pre_read(void)
} else
break;
}
#ifdef RANDOM_DEBUG
{
u_int j;
printf("random: reseedcount [%d]", fortuna_state.fs_reseedcount);
for (j = 0; j < RANDOM_FORTUNA_NPOOLS; j++)
printf(" %X", fortuna_state.fs_pool[j].fsp_length);
printf("\n");
}
#endif
SDT_PROBE2(random, fortuna, event_processor, debug, fortuna_state.fs_reseedcount, fortuna_state.fs_pool);
/* FS&K */
random_fortuna_reseed_internal(s, i < RANDOM_FORTUNA_NPOOLS ? i + 1 : RANDOM_FORTUNA_NPOOLS);
/* Clean up and secure */

View File

@ -170,7 +170,7 @@ random_kthread(void)
/* XXX: FIX!! Increase the high-performance data rate? Need some measurements first. */
for (i = 0; i < RANDOM_ACCUM_MAX; i++) {
if (harvest_context.hc_entropy_fast_accumulator.buf[i]) {
random_harvest_direct(harvest_context.hc_entropy_fast_accumulator.buf + i, sizeof(harvest_context.hc_entropy_fast_accumulator.buf[0]), 4, RANDOM_FAST);
random_harvest_direct(harvest_context.hc_entropy_fast_accumulator.buf + i, sizeof(harvest_context.hc_entropy_fast_accumulator.buf[0]), 4, RANDOM_UMA);
harvest_context.hc_entropy_fast_accumulator.buf[i] = 0;
}
}
@ -261,7 +261,7 @@ static const char *(random_source_descr[]) = {
"INTERRUPT",
"SWI",
"FS_ATIME",
"HIGH_PERFORMANCE", /* ENVIRONMENTAL_END */
"UMA", /* ENVIRONMENTAL_END */
"PURE_OCTEON",
"PURE_SAFE",
"PURE_GLXSB",

View File

@ -29,7 +29,7 @@
/*
Build this by going:
cc -g -O0 -pthread -DRANDOM_<alg> -DRANDOM_DEBUG -I../.. -lstdthreads -Wall \
cc -g -O0 -pthread -DRANDOM_<alg> -I../.. -lstdthreads -Wall \
unit_test.c \
yarrow.c \
fortuna.c \

View File

@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/random.h>
#include <sys/sdt.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
@ -77,6 +78,11 @@ __FBSDID("$FreeBSD$");
CTASSERT(RANDOM_BLOCKSIZE == sizeof(uint128_t));
CTASSERT(RANDOM_KEYSIZE == 2*RANDOM_BLOCKSIZE);
/* Probes for dtrace(1) */
SDT_PROVIDER_DECLARE(random);
SDT_PROVIDER_DEFINE(random);
SDT_PROBE_DEFINE3(random, yarrow, event_processor, debug, "boolean", "u_int", "struct ys_pool *");
/*
* This is the beastie that needs protecting. It contains all of the
* state that we are excited about. Exactly one is instantiated.
@ -261,20 +267,7 @@ random_yarrow_reseed_internal(u_int fastslow)
KASSERT(yarrow_state.ys_pool[RANDOM_YARROW_FAST].ysp_thresh > 0, ("random: Yarrow fast threshold = 0"));
KASSERT(yarrow_state.ys_pool[RANDOM_YARROW_SLOW].ysp_thresh > 0, ("random: Yarrow slow threshold = 0"));
RANDOM_RESEED_ASSERT_LOCK_OWNED();
#ifdef RANDOM_DEBUG
/* WARNING! This is dangerously tedious to do with mutexes held! */
printf("random: %s ", __func__);
printf("type/pool = %s ", fastslow == RANDOM_YARROW_FAST ? "RANDOM_YARROW_FAST" : "RANDOM_YARROW_SLOW");
printf("seeded = %s\n", yarrow_state.ys_seeded ? "true" : "false");
printf("random: fast - thresh %d,1 - ", yarrow_state.ys_pool[RANDOM_YARROW_FAST].ysp_thresh);
for (i = RANDOM_START; i < ENTROPYSOURCE; i++)
printf(" %d", yarrow_state.ys_pool[RANDOM_YARROW_FAST].ysp_source_bits[i]);
printf("\n");
printf("random: slow - thresh %d,%d - ", yarrow_state.ys_pool[RANDOM_YARROW_SLOW].ysp_thresh, yarrow_state.ys_slowoverthresh);
for (i = RANDOM_START; i < ENTROPYSOURCE; i++)
printf(" %d", yarrow_state.ys_pool[RANDOM_YARROW_SLOW].ysp_source_bits[i]);
printf("\n");
#endif
SDT_PROBE3(random, yarrow, event_processor, debug, yarrow_state.ys_seeded, yarrow_state.ys_slowoverthresh, yarrow_state.ys_pool);
/* 1. Hash the accumulated entropy into v[0] */
randomdev_hash_init(&context);
/* Feed the slow pool hash in if slow */

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2000-2013 Mark R. V. Murray
* Copyright (c) 2000-2015 Mark R. V. Murray
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -35,9 +35,11 @@
#include "opt_random.h"
#if !defined(KLD_MODULE)
#if defined(RANDOM_LOADABLE) && defined(RANDOM_YARROW)
#error "Cannot define both RANDOM_LOADABLE and RANDOM_YARROW"
#endif
#endif
struct uio;
@ -78,8 +80,8 @@ enum random_entropy_source {
RANDOM_INTERRUPT,
RANDOM_SWI,
RANDOM_FS_ATIME,
RANDOM_FAST, /* Special!! Miscellaneous high performance stuff, like UMA/SLAB Allocator */
RANDOM_ENVIRONMENTAL_END = RANDOM_FAST,
RANDOM_UMA, /* Special!! UMA/SLAB Allocator */
RANDOM_ENVIRONMENTAL_END = RANDOM_UMA,
/* Fast hardware random-number sources from here on. */
RANDOM_PURE_OCTEON,
RANDOM_PURE_SAFE,
@ -105,6 +107,12 @@ void random_harvest_direct(const void *, u_int, u_int, enum random_entropy_sourc
#define random_harvest_direct(a, b, c, d) do {} while (0)
#endif
#if defined(RANDOM_ENABLE_UMA)
#define random_harvest_fast_uma(a, b, c, d) random_harvest_fast(a, b, c, d)
#else /* !defined(RANDOM_ENABLE_UMA) */
#define random_harvest_fast_uma(a, b, c, d) do {} while (0)
#endif /* defined(RANDOM_ENABLE_UMA) */
#endif /* _KERNEL */
#endif /* _SYS_RANDOM_H_ */

View File

@ -2135,8 +2135,8 @@ uma_zalloc_arg(uma_zone_t zone, void *udata, int flags)
int lockfail;
int cpu;
/* XXX: FIX? The entropy here is desirable, but the harvesting may be expensive */
random_harvest_fast(&zone, sizeof(zone), 1, RANDOM_FAST);
/* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */
random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA);
/* This is the fast path allocation */
#ifdef UMA_DEBUG_ALLOC_1
@ -2677,8 +2677,8 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata)
int lockfail;
int cpu;
/* XXX: FIX? The entropy here is desirable, but the harvesting may be expensive */
random_harvest_fast(&zone, sizeof(zone), 1, RANDOM_FAST);
/* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */
random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA);
#ifdef UMA_DEBUG_ALLOC_1
printf("Freeing item %p to %s(%p)\n", item, zone->uz_name, zone);