Index: head/share/man/man4/random.4 =================================================================== --- head/share/man/man4/random.4 +++ head/share/man/man4/random.4 @@ -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 @@ 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 Index: head/sys/conf/NOTES =================================================================== --- head/sys/conf/NOTES +++ head/sys/conf/NOTES @@ -2985,8 +2985,10 @@ #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 Index: head/sys/conf/options =================================================================== --- head/sys/conf/options +++ head/sys/conf/options @@ -945,17 +945,16 @@ 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 Index: head/sys/dev/random/build.sh =================================================================== --- head/sys/dev/random/build.sh +++ head/sys/dev/random/build.sh @@ -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 @@ ../../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 \ Index: head/sys/dev/random/fortuna.c =================================================================== --- head/sys/dev/random/fortuna.c +++ head/sys/dev/random/fortuna.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -94,6 +95,11 @@ 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 @@ } 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 */ Index: head/sys/dev/random/random_harvestq.c =================================================================== --- head/sys/dev/random/random_harvestq.c +++ head/sys/dev/random/random_harvestq.c @@ -170,7 +170,7 @@ /* 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 @@ "INTERRUPT", "SWI", "FS_ATIME", - "HIGH_PERFORMANCE", /* ENVIRONMENTAL_END */ + "UMA", /* ENVIRONMENTAL_END */ "PURE_OCTEON", "PURE_SAFE", "PURE_GLXSB", Index: head/sys/dev/random/unit_test.c =================================================================== --- head/sys/dev/random/unit_test.c +++ head/sys/dev/random/unit_test.c @@ -29,7 +29,7 @@ /* Build this by going: -cc -g -O0 -pthread -DRANDOM_ -DRANDOM_DEBUG -I../.. -lstdthreads -Wall \ +cc -g -O0 -pthread -DRANDOM_ -I../.. -lstdthreads -Wall \ unit_test.c \ yarrow.c \ fortuna.c \ Index: head/sys/dev/random/yarrow.c =================================================================== --- head/sys/dev/random/yarrow.c +++ head/sys/dev/random/yarrow.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -77,6 +78,11 @@ 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 @@ 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 */ Index: head/sys/sys/random.h =================================================================== --- head/sys/sys/random.h +++ head/sys/sys/random.h @@ -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 @@ 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 @@ #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_ */ Index: head/sys/vm/uma_core.c =================================================================== --- head/sys/vm/uma_core.c +++ head/sys/vm/uma_core.c @@ -2135,8 +2135,8 @@ 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 @@ 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);