Skip to content

Commit

Permalink
Add --with-rand-seed
Browse files Browse the repository at this point in the history
Add a new config param to specify how the CSPRNG should be seeded.
Illegal values or nonsensical combinations (e.g., anything other
than "os" on VMS or HP VOS etc) result in build failures.
Add RDSEED support.
Add RDTSC but leave it disabled for now pending more investigation.

Refactor and reorganization all seeding files (rand_unix/win/vms) so
that they are simpler.

Only require 128 bits of seeding material.

Many document improvements, including why to not use RAND_add() and the
limitations around using load_file/write_file.
Document RAND_poll().

Cleanup Windows RAND_poll and return correct status

More completely initialize the default DRBG.

Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl#3965)
  • Loading branch information
Rich Salz committed Jul 22, 2017
1 parent 0d7903f commit 8389ec4
Show file tree
Hide file tree
Showing 10 changed files with 324 additions and 306 deletions.
23 changes: 23 additions & 0 deletions Configure
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,9 @@ $config{build_type} = "release";

my %unsupported_options = ();
my %deprecated_options = ();
# If you change this, update apps/version.c
my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom);
my @seed_sources = ();
while (@argvcopy)
{
$_ = shift @argvcopy;
Expand Down Expand Up @@ -729,6 +732,15 @@ while (@argvcopy)
{
$withargs{fuzzer_include}=$1;
}
elsif (/^--with-rand-seed=(.*)$/)
{
foreach my $x (split(m|,|, $1))
{
die "Unknown --with-rand-seed choice $x\n"
if ! grep { $x eq $_ } @known_seed_sources;
push @seed_sources, $x;
}
}
elsif (/^--cross-compile-prefix=(.*)$/)
{
$config{cross_compile_prefix}=$1;
Expand Down Expand Up @@ -812,6 +824,17 @@ if ($libs =~ /(^|\s)-Wl,-rpath,/
"***** any of asan, msan or ubsan\n";
}

if (scalar(@seed_sources) == 0) {
print "Using implicit seed configuration\n";
push @seed_sources, 'os';
}
die "Cannot seed with none and anything else"
if scalar(grep { $_ eq 'none' } @seed_sources) > 0
&& scalar(@seed_sources) > 1;
push @{$config{openssl_other_defines}},
map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" }
@seed_sources;

my @tocheckfor = (keys %disabled);
while (@tocheckfor) {
my %new_tocheckfor = ();
Expand Down
38 changes: 35 additions & 3 deletions apps/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_B, OPT_D, OPT_E, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A
OPT_B, OPT_D, OPT_E, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A, OPT_R
} OPTION_CHOICE;

const OPTIONS version_options[] = {
Expand All @@ -44,13 +44,14 @@ const OPTIONS version_options[] = {
{"f", OPT_F, '-', "Show compiler flags used"},
{"o", OPT_O, '-', "Show some internal datatype options"},
{"p", OPT_P, '-', "Show target build platform"},
{"r", OPT_R, '-', "Show random seeding options"},
{"v", OPT_V, '-', "Show library version"},
{NULL}
};

int version_main(int argc, char **argv)
{
int ret = 1, dirty = 0;
int ret = 1, dirty = 0, seed = 0;
int cflags = 0, version = 0, date = 0, options = 0, platform = 0, dir = 0;
int engdir = 0;
char *prog;
Expand Down Expand Up @@ -85,11 +86,14 @@ int version_main(int argc, char **argv)
case OPT_P:
dirty = platform = 1;
break;
case OPT_R:
dirty = seed = 1;
break;
case OPT_V:
dirty = version = 1;
break;
case OPT_A:
cflags = version = date = platform = dir = engdir = 1;
seed = cflags = version = date = platform = dir = engdir = 1;
break;
}
}
Expand Down Expand Up @@ -133,6 +137,34 @@ int version_main(int argc, char **argv)
printf("%s\n", OpenSSL_version(OPENSSL_DIR));
if (engdir)
printf("%s\n", OpenSSL_version(OPENSSL_ENGINES_DIR));
if (seed) {
printf("Seeding source:");
#ifdef OPENSSL_RAND_SEED_RTDSC
printf(" rtdsc");
#endif
#ifdef OPENSSL_RAND_SEED_RDCPU
printf(" rdrand-hardware");
#endif
#ifdef OPENSSL_RAND_SEED_LIBRANDOM
printf(" C-library-random");
#endif
#ifdef OPENSSL_RAND_SEED_GETRANDOM
printf(" getrandom-syscall");
#endif
#ifdef OPENSSL_RAND_SEED_DEVRANDOM
printf(" random-device");
#endif
#ifdef OPENSSL_RAND_SEED_EGD
printf(" EGD");
#endif
#ifdef OPENSSL_RAND_SEED_NONE
printf(" none");
#endif
#ifdef OPENSSL_RAND_SEED_OS
printf(" os-specific");
#endif
printf("\n");
}
ret = 0;
end:
return (ret);
Expand Down
6 changes: 5 additions & 1 deletion crypto/rand/drbg_rand.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ static CRYPTO_ONCE ossl_drbg_init = CRYPTO_ONCE_STATIC_INIT;

DEFINE_RUN_ONCE_STATIC(do_ossl_drbg_init)
{
int st = 1;

ossl_drbg.lock = CRYPTO_THREAD_lock_new();
return ossl_drbg.lock != NULL;
st &= ossl_drbg.lock != NULL;
st &= RAND_DRBG_set(&ossl_drbg, NID_aes_128_ctr, 0) == 1;
return st;
}

void rand_drbg_cleanup(void)
Expand Down
28 changes: 19 additions & 9 deletions crypto/rand/rand_lcl.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,24 @@
# include <openssl/ec.h>
# include "internal/rand.h"

/* we require 256 bits of randomness */
# define RANDOMNESS_NEEDED (256 / 8)
/* Amount of randomness (in bytes) we want for initial seeding. */
# define RANDOMNESS_NEEDED (128 / 8)

/* Maximum count allowed in reseeding */
#define MAX_RESEED (1 << 24)

/* DRBG status values */
#define DRBG_STATUS_UNINITIALISED 0
#define DRBG_STATUS_READY 1
#define DRBG_STATUS_RESEED 2
#define DRBG_STATUS_ERROR 3
# define DRBG_STATUS_UNINITIALISED 0
# define DRBG_STATUS_READY 1
# define DRBG_STATUS_RESEED 2
# define DRBG_STATUS_ERROR 3

/* A default maximum length: larger than any reasonable value used in pratice */
#define DRBG_MAX_LENGTH 0x7ffffff0
# define DRBG_MAX_LENGTH 0x7ffffff0

/*
* The context for DRBG AES-CTR
*/
typedef struct drbg_ctr_ctx_st {
AES_KEY ks;
size_t keylen;
Expand All @@ -46,6 +49,10 @@ typedef struct drbg_ctr_ctx_st {
unsigned char KX[48];
} DRBG_CTR_CTX;


/*
* The context for all DRBG's
*/
struct drbg_ctx_st {
CRYPTO_RWLOCK *lock;
DRBG_CTX *parent;
Expand Down Expand Up @@ -84,9 +91,12 @@ struct drbg_ctx_st {
extern RAND_METHOD openssl_rand_meth;
void rand_drbg_cleanup(void);

/* Hardware-based seeding functions. */
void rand_rdtsc(void);
int rand_rdcpu(void);

/* DRBG functions implementing AES-CTR */
int ctr_init(DRBG_CTX *dctx);
int drbg_hash_init(DRBG_CTX *dctx);
int drbg_hmac_init(DRBG_CTX *dctx);
int ctr_uninstantiate(DRBG_CTX *dctx);
int ctr_instantiate(DRBG_CTX *dctx,
const unsigned char *ent, size_t entlen,
Expand Down
64 changes: 64 additions & 0 deletions crypto/rand/rand_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,70 @@ static CRYPTO_RWLOCK *rand_meth_lock;
static const RAND_METHOD *default_RAND_meth;
static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT;

#ifdef OPENSSL_RAND_SEED_RDTSC
/*
* IMPORTANT NOTE: It is not currently possible to use this code
* because we are not sure about the amount of randomness. Some
* SP900 tests have been run, but there is internal skepticism.
* So for now this code is not used.
*/
# error "RDTSC enabled? Should not be possible!"

/*
* Since we get some randomness from the low-order bits of the
* high-speec clock, it can help. But don't return a status since
* it's not sufficient to indicate whether or not the seeding was
* done.
*/
void rand_rdtsc(void)
{
unsigned char c;
int i;

for (i = 0; i < 10; i++) {
c = (unsigned char)(OPENSSL_rdtsc() & 0xFF);
RAND_add(&c, 1, 0.5);
}
}
#endif

#ifdef OPENSSL_RAND_SEED_RDCPU
size_t OPENSSL_ia32_rdseed(void);
size_t OPENSSL_ia32_rdrand(void);

extern unsigned int OPENSSL_ia32cap_P[];

int rand_rdcpu(void)
{
size_t i, s;

/* If RDSEED is available, use that. */
if ((OPENSSL_ia32cap_P[1] & (1 << 18)) != 0) {
for (i = 0; i < RANDOMNESS_NEEDED; i += sizeof(s)) {
s = OPENSSL_ia32_rdseed();
if (s == 0)
break;
RAND_add(&s, (int)sizeof(s), sizeof(s));
}
if (i >= RANDOMNESS_NEEDED)
return 1;
}

/* Second choice is RDRAND. */
if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) {
for (i = 0; i < RANDOMNESS_NEEDED; i += sizeof(s)) {
s = OPENSSL_ia32_rdrand();
if (s == 0)
break;
RAND_add(&s, (int)sizeof(s), sizeof(s));
}
if (i >= RANDOMNESS_NEEDED)
return 1;
}

return 0;
}
#endif

DEFINE_RUN_ONCE_STATIC(do_rand_init)
{
Expand Down
Loading

0 comments on commit 8389ec4

Please sign in to comment.