DRBG: rename the DRBG taxonomy.

The existing wording didn't capture the reality of the default setup, this new
nomenclature attempts to improve the situation.

Reviewed-by: Mark J. Cox <mark@awe.com>
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12366)
This commit is contained in:
Pauli 2020-07-04 10:48:19 +10:00
parent d35bab46c9
commit ce3080e931
8 changed files with 230 additions and 212 deletions

View File

@ -41,29 +41,32 @@ typedef struct drbg_global_st {
/*
* The three shared DRBG instances
*
* There are three shared DRBG instances: <master>, <public>, and <private>.
* There are three shared DRBG instances: <primary>, <public>, and
* <private>. The <public> and <private> DRBGs are secondary ones.
* These are used for non-secret (e.g. nonces) and secret
* (e.g. private keys) data respectively.
*/
CRYPTO_RWLOCK *lock;
/*
* The <master> DRBG
* The <primary> DRBG
*
* Not used directly by the application, only for reseeding the two other
* DRBGs. It reseeds itself by pulling either randomness from os entropy
* sources or by consuming randomness which was added by RAND_add().
*
* The <master> DRBG is a global instance which is accessed concurrently by
* The <primary> DRBG is a global instance which is accessed concurrently by
* all threads. The necessary locking is managed automatically by its child
* DRBG instances during reseeding.
*/
RAND_DRBG *master_drbg;
RAND_DRBG *primary_drbg;
/*
* The <public> DRBG
*
* Used by default for generating random bytes using RAND_bytes().
*
* The <public> DRBG is thread-local, i.e., there is one instance per
* thread.
* The <public> secondary DRBG is thread-local, i.e., there is one instance
* per thread.
*/
CRYPTO_THREAD_LOCAL public_drbg;
/*
@ -71,43 +74,44 @@ typedef struct drbg_global_st {
*
* Used by default for generating private keys using RAND_priv_bytes()
*
* The <private> DRBG is thread-local, i.e., there is one instance per
* thread.
* The <private> secondary DRBG is thread-local, i.e., there is one
* instance per thread.
*/
CRYPTO_THREAD_LOCAL private_drbg;
} DRBG_GLOBAL;
#define RAND_DRBG_TYPE_FLAGS ( \
RAND_DRBG_FLAG_MASTER | RAND_DRBG_FLAG_PUBLIC | RAND_DRBG_FLAG_PRIVATE )
RAND_DRBG_FLAG_PRIMARY | RAND_DRBG_FLAG_PUBLIC | RAND_DRBG_FLAG_PRIVATE )
#define RAND_DRBG_TYPE_MASTER 0
#define RAND_DRBG_TYPE_PRIMARY 0
#define RAND_DRBG_TYPE_PUBLIC 1
#define RAND_DRBG_TYPE_PRIVATE 2
/* Defaults */
static int rand_drbg_type[3] = {
RAND_DRBG_TYPE, /* Master */
RAND_DRBG_TYPE, /* Primary */
RAND_DRBG_TYPE, /* Public */
RAND_DRBG_TYPE /* Private */
};
static unsigned int rand_drbg_flags[3] = {
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_MASTER, /* Master */
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC, /* Public */
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIVATE /* Private */
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIMARY, /* Primary */
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC, /* Public */
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIVATE /* Private */
};
static unsigned int master_reseed_interval = MASTER_RESEED_INTERVAL;
static unsigned int slave_reseed_interval = SLAVE_RESEED_INTERVAL;
static unsigned int primary_reseed_interval = PRIMARY_RESEED_INTERVAL;
static unsigned int secondary_reseed_interval = SECONDARY_RESEED_INTERVAL;
static time_t master_reseed_time_interval = MASTER_RESEED_TIME_INTERVAL;
static time_t slave_reseed_time_interval = SLAVE_RESEED_TIME_INTERVAL;
static time_t primary_reseed_time_interval = PRIMARY_RESEED_TIME_INTERVAL;
static time_t secondary_reseed_time_interval = SECONDARY_RESEED_TIME_INTERVAL;
/* A logical OR of all used DRBG flag bits (currently there is only one) */
static const unsigned int rand_drbg_used_flags =
RAND_DRBG_FLAG_CTR_NO_DF | RAND_DRBG_FLAG_HMAC | RAND_DRBG_TYPE_FLAGS;
static RAND_DRBG *drbg_setup(OPENSSL_CTX *ctx, RAND_DRBG *parent, int drbg_type);
static RAND_DRBG *drbg_setup(OPENSSL_CTX *ctx, RAND_DRBG *parent,
int drbg_type);
static int get_drbg_params(int type, unsigned int flags, const char **name,
OSSL_PARAM params[3])
@ -229,7 +233,7 @@ static void drbg_ossl_ctx_free(void *vdgbl)
return;
CRYPTO_THREAD_lock_free(dgbl->lock);
RAND_DRBG_free(dgbl->master_drbg);
RAND_DRBG_free(dgbl->primary_drbg);
CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg);
CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg);
@ -293,16 +297,16 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
int use_df;
if (type == 0 && flags == 0) {
type = rand_drbg_type[RAND_DRBG_TYPE_MASTER];
flags = rand_drbg_flags[RAND_DRBG_TYPE_MASTER];
type = rand_drbg_type[RAND_DRBG_TYPE_PRIMARY];
flags = rand_drbg_flags[RAND_DRBG_TYPE_PRIMARY];
}
if (drbg->parent == NULL) {
reseed_interval = master_reseed_interval;
reseed_time_interval = master_reseed_time_interval;
reseed_interval = primary_reseed_interval;
reseed_time_interval = primary_reseed_time_interval;
} else {
reseed_interval = slave_reseed_interval;
reseed_time_interval = slave_reseed_time_interval;
reseed_interval = secondary_reseed_interval;
reseed_time_interval = secondary_reseed_time_interval;
}
*p++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS,
&reseed_interval);
@ -371,9 +375,10 @@ int RAND_DRBG_set_defaults(int type, unsigned int flags)
}
all = ((flags & RAND_DRBG_TYPE_FLAGS) == 0);
if (all || (flags & RAND_DRBG_FLAG_MASTER) != 0) {
rand_drbg_type[RAND_DRBG_TYPE_MASTER] = type;
rand_drbg_flags[RAND_DRBG_TYPE_MASTER] = flags | RAND_DRBG_FLAG_MASTER;
if (all || (flags & RAND_DRBG_FLAG_PRIMARY) != 0) {
rand_drbg_type[RAND_DRBG_TYPE_PRIMARY] = type;
rand_drbg_flags[RAND_DRBG_TYPE_PRIMARY] = flags
| RAND_DRBG_FLAG_PRIMARY;
}
if (all || (flags & RAND_DRBG_FLAG_PUBLIC) != 0) {
rand_drbg_type[RAND_DRBG_TYPE_PUBLIC] = type;
@ -381,7 +386,8 @@ int RAND_DRBG_set_defaults(int type, unsigned int flags)
}
if (all || (flags & RAND_DRBG_FLAG_PRIVATE) != 0) {
rand_drbg_type[RAND_DRBG_TYPE_PRIVATE] = type;
rand_drbg_flags[RAND_DRBG_TYPE_PRIVATE] = flags | RAND_DRBG_FLAG_PRIVATE;
rand_drbg_flags[RAND_DRBG_TYPE_PRIVATE] = flags
| RAND_DRBG_FLAG_PRIVATE;
}
return 1;
}
@ -473,8 +479,8 @@ int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
return 0;
/* The reset uses the default values for type and flags */
if (drbg->flags & RAND_DRBG_FLAG_MASTER)
index = RAND_DRBG_TYPE_MASTER;
if (drbg->flags & RAND_DRBG_FLAG_PRIMARY)
index = RAND_DRBG_TYPE_PRIMARY;
else if (drbg->flags & RAND_DRBG_FLAG_PRIVATE)
index = RAND_DRBG_TYPE_PRIVATE;
else if (drbg->flags & RAND_DRBG_FLAG_PUBLIC)
@ -730,32 +736,32 @@ int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval)
/*
* Set the default values for reseed (time) intervals of new DRBG instances
*
* The default values can be set independently for master DRBG instances
* (without a parent) and slave DRBG instances (with parent).
* The default values can be set independently for primary DRBG instances
* (without a parent) and secondary DRBG instances (with parent).
*
* Returns 1 on success, 0 on failure.
*/
int RAND_DRBG_set_reseed_defaults(
unsigned int _master_reseed_interval,
unsigned int _slave_reseed_interval,
time_t _master_reseed_time_interval,
time_t _slave_reseed_time_interval
unsigned int _primary_reseed_interval,
unsigned int _secondary_reseed_interval,
time_t _primary_reseed_time_interval,
time_t _secondary_reseed_time_interval
)
{
if (_master_reseed_interval > MAX_RESEED_INTERVAL
|| _slave_reseed_interval > MAX_RESEED_INTERVAL)
if (_primary_reseed_interval > MAX_RESEED_INTERVAL
|| _secondary_reseed_interval > MAX_RESEED_INTERVAL)
return 0;
if (_master_reseed_time_interval > MAX_RESEED_TIME_INTERVAL
|| _slave_reseed_time_interval > MAX_RESEED_TIME_INTERVAL)
if (_primary_reseed_time_interval > MAX_RESEED_TIME_INTERVAL
|| _secondary_reseed_time_interval > MAX_RESEED_TIME_INTERVAL)
return 0;
master_reseed_interval = _master_reseed_interval;
slave_reseed_interval = _slave_reseed_interval;
primary_reseed_interval = _primary_reseed_interval;
secondary_reseed_interval = _secondary_reseed_interval;
master_reseed_time_interval = _master_reseed_time_interval;
slave_reseed_time_interval = _slave_reseed_time_interval;
primary_reseed_time_interval = _primary_reseed_time_interval;
secondary_reseed_time_interval = _secondary_reseed_time_interval;
return 1;
}
@ -793,7 +799,7 @@ static RAND_DRBG *drbg_setup(OPENSSL_CTX *ctx, RAND_DRBG *parent, int drbg_type)
if (drbg == NULL)
return NULL;
/* Only the master DRBG needs to have a lock */
/* Only the primary DRBG needs to have a lock */
if (parent == NULL && EVP_RAND_enable_locking(drbg->rand) == 0)
goto err;
@ -878,30 +884,30 @@ int RAND_DRBG_verify_zeroization(RAND_DRBG *drbg)
}
/*
* Get the master DRBG.
* Get the primary DRBG.
* Returns pointer to the DRBG on success, NULL on failure.
*
*/
RAND_DRBG *OPENSSL_CTX_get0_master_drbg(OPENSSL_CTX *ctx)
RAND_DRBG *OPENSSL_CTX_get0_primary_drbg(OPENSSL_CTX *ctx)
{
DRBG_GLOBAL *dgbl = drbg_get_global(ctx);
if (dgbl == NULL)
return NULL;
if (dgbl->master_drbg == NULL) {
if (dgbl->primary_drbg == NULL) {
if (!CRYPTO_THREAD_write_lock(dgbl->lock))
return NULL;
if (dgbl->master_drbg == NULL)
dgbl->master_drbg = drbg_setup(ctx, NULL, RAND_DRBG_TYPE_MASTER);
if (dgbl->primary_drbg == NULL)
dgbl->primary_drbg = drbg_setup(ctx, NULL, RAND_DRBG_TYPE_PRIMARY);
CRYPTO_THREAD_unlock(dgbl->lock);
}
return dgbl->master_drbg;
return dgbl->primary_drbg;
}
RAND_DRBG *RAND_DRBG_get0_master(void)
{
return OPENSSL_CTX_get0_master_drbg(NULL);
return OPENSSL_CTX_get0_primary_drbg(NULL);
}
/*
@ -911,15 +917,15 @@ RAND_DRBG *RAND_DRBG_get0_master(void)
RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx)
{
DRBG_GLOBAL *dgbl = drbg_get_global(ctx);
RAND_DRBG *drbg, *master;
RAND_DRBG *drbg, *primary;
if (dgbl == NULL)
return NULL;
drbg = CRYPTO_THREAD_get_local(&dgbl->public_drbg);
if (drbg == NULL) {
master = OPENSSL_CTX_get0_master_drbg(ctx);
if (master == NULL)
primary = OPENSSL_CTX_get0_primary_drbg(ctx);
if (primary == NULL)
return NULL;
ctx = openssl_ctx_get_concrete(ctx);
@ -930,7 +936,7 @@ RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx)
if (CRYPTO_THREAD_get_local(&dgbl->private_drbg) == NULL
&& !ossl_init_thread_start(NULL, ctx, drbg_delete_thread_state))
return NULL;
drbg = drbg_setup(ctx, master, RAND_DRBG_TYPE_PUBLIC);
drbg = drbg_setup(ctx, primary, RAND_DRBG_TYPE_PUBLIC);
CRYPTO_THREAD_set_local(&dgbl->public_drbg, drbg);
}
return drbg;
@ -948,15 +954,15 @@ RAND_DRBG *RAND_DRBG_get0_public(void)
RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx)
{
DRBG_GLOBAL *dgbl = drbg_get_global(ctx);
RAND_DRBG *drbg, *master;
RAND_DRBG *drbg, *primary;
if (dgbl == NULL)
return NULL;
drbg = CRYPTO_THREAD_get_local(&dgbl->private_drbg);
if (drbg == NULL) {
master = OPENSSL_CTX_get0_master_drbg(ctx);
if (master == NULL)
primary = OPENSSL_CTX_get0_primary_drbg(ctx);
if (primary == NULL)
return NULL;
ctx = openssl_ctx_get_concrete(ctx);
@ -967,7 +973,7 @@ RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx)
if (CRYPTO_THREAD_get_local(&dgbl->public_drbg) == NULL
&& !ossl_init_thread_start(NULL, ctx, drbg_delete_thread_state))
return NULL;
drbg = drbg_setup(ctx, master, RAND_DRBG_TYPE_PRIVATE);
drbg = drbg_setup(ctx, primary, RAND_DRBG_TYPE_PRIVATE);
CRYPTO_THREAD_set_local(&dgbl->private_drbg, drbg);
}
return drbg;

View File

@ -26,10 +26,11 @@
# define MAX_RESEED_TIME_INTERVAL (1 << 20) /* approx. 12 days */
/* Default reseed intervals */
# define MASTER_RESEED_INTERVAL (1 << 8)
# define SLAVE_RESEED_INTERVAL (1 << 16)
# define MASTER_RESEED_TIME_INTERVAL (60 * 60) /* 1 hour */
# define SLAVE_RESEED_TIME_INTERVAL (7 * 60) /* 7 minutes */
# define PRIMARY_RESEED_INTERVAL (1 << 8)
# define SECONDARY_RESEED_INTERVAL (1 << 16)
# define PRIMARY_RESEED_TIME_INTERVAL (60 * 60) /* 1 hour */
# define SECONDARY_RESEED_TIME_INTERVAL (7 * 60) /* 7 minutes */
/*
* The state of all types of DRBGs.
*/

View File

@ -2,7 +2,7 @@
=head1 NAME
OPENSSL_CTX_get0_master_drbg,
OPENSSL_CTX_get0_primary_drbg,
OPENSSL_CTX_get0_public_drbg,
OPENSSL_CTX_get0_private_drbg,
RAND_DRBG_get0_master,
@ -14,7 +14,7 @@ RAND_DRBG_get0_private
#include <openssl/rand_drbg.h>
RAND_DRBG *OPENSSL_CTX_get0_master_drbg(OPENSSL_CTX *ctx);
RAND_DRBG *OPENSSL_CTX_get0_primary_drbg(OPENSSL_CTX *ctx);
RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx);
RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx);
RAND_DRBG *RAND_DRBG_get0_master(void);
@ -36,7 +36,7 @@ These functions here provide access to the shared DRBG instances.
=head1 RETURN VALUES
OPENSSL_CTX_get0_master_drbg() returns a pointer to the I<master> DRBG instance
OPENSSL_CTX_get0_primary_drbg() returns a pointer to the I<master> DRBG instance
for the given OPENSSL_CTX B<ctx>.
OPENSSL_CTX_get0_public_drbg() returns a pointer to the I<public> DRBG instance
@ -48,7 +48,7 @@ for the given OPENSSL_CTX B<ctx>.
In all the above cases the B<ctx> parameter can
be NULL in which case the default OPENSSL_CTX is used. RAND_DRBG_get0_master(),
RAND_DRBG_get0_public() and RAND_DRBG_get0_private() are the same as
OPENSSL_CTX_get0_master_drbg(), OPENSSL_CTX_get0_public_drbg() and
OPENSSL_CTX_get0_primary_drbg(), OPENSSL_CTX_get0_public_drbg() and
OPENSSL_CTX_get0_private_drbg() respectively except that the default OPENSSL_CTX
is always used.
@ -80,7 +80,7 @@ L<RAND_DRBG(7)>
=head1 HISTORY
The OPENSSL_CTX_get0_master_drbg(), OPENSSL_CTX_get0_public_drbg() and
The OPENSSL_CTX_get0_primary_drbg(), OPENSSL_CTX_get0_public_drbg() and
OPENSSL_CTX_get0_private_drbg() functions were added in OpenSSL 3.0.
All other RAND_DRBG functions were added in OpenSSL 1.1.1.

View File

@ -84,7 +84,7 @@ see [NIST SP 800-90A Rev. 1].
Enables use of HMAC instead of the HASH DRBG.
=item RAND_DRBG_FLAG_MASTER
=item RAND_DRBG_FLAG_PRIMARY
=item RAND_DRBG_FLAG_PUBLIC

View File

@ -23,10 +23,10 @@ RAND_DRBG_set_reseed_defaults
time_t interval);
int RAND_DRBG_set_reseed_defaults(
unsigned int master_reseed_interval,
unsigned int slave_reseed_interval,
time_t master_reseed_time_interval,
time_t slave_reseed_time_interval
unsigned int primary_reseed_interval,
unsigned int secondary_reseed_interval,
time_t primary_reseed_time_interval,
time_t secondary_reseed_time_interval
);
@ -60,12 +60,13 @@ elapsed time since its last reseeding exceeds the given reseed time interval.
If B<interval> == 0, then this feature is disabled.
RAND_DRBG_set_reseed_defaults() sets the default values for the reseed interval
(B<master_reseed_interval> and B<slave_reseed_interval>)
(B<primary_reseed_interval> and B<secondary_reseed_interval>)
and the reseed time interval
(B<master_reseed_time_interval> and B<slave_reseed_tme_interval>)
(B<primary_reseed_time_interval> and B<secondary_reseed_tme_interval>)
of DRBG instances.
The default values are set independently for master DRBG instances (which don't
have a parent) and slave DRBG instances (which are chained to a parent DRBG).
The default values are set independently for primary DRBG instances (which don't
have a parent) and secondary DRBG instances (which are chained to a parent
DRBG).
=head1 RETURN VALUES
@ -74,7 +75,6 @@ RAND_DRBG_set_reseed_interval(), and
RAND_DRBG_set_reseed_time_interval(),
return 1 on success, 0 on failure.
=head1 NOTES
The default OpenSSL random generator is already set up for automatic reseeding,
@ -89,9 +89,9 @@ by providing application defined callbacks using RAND_DRBG_set_callbacks().
The reseeding default values are applied only during creation of a DRBG instance.
To ensure that they are applied to the global and thread-local DRBG instances
(<master>, resp. <public> and <private>), it is necessary to call
RAND_DRBG_set_reseed_defaults() before creating any thread and before calling any
cryptographic routines that obtain random data directly or indirectly.
(<primary>, resp. <public> and <private>), it is necessary to call
RAND_DRBG_set_reseed_defaults() before creating any thread and before calling
any cryptographic routines that obtain random data directly or indirectly.
=head1 SEE ALSO

View File

@ -35,8 +35,8 @@
*/
# define RAND_DRBG_FLAG_HMAC 0x2
/* Used by RAND_DRBG_set_defaults() to set the master DRBG type and flags. */
# define RAND_DRBG_FLAG_MASTER 0x4
/* Used by RAND_DRBG_set_defaults() to set the primary DRBG type and flags. */
# define RAND_DRBG_FLAG_PRIMARY 0x4
/* Used by RAND_DRBG_set_defaults() to set the public DRBG type and flags. */
# define RAND_DRBG_FLAG_PUBLIC 0x8
/* Used by RAND_DRBG_set_defaults() to set the private DRBG type and flags. */
@ -104,19 +104,26 @@ int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, unsigned int interval);
int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval);
int RAND_DRBG_set_reseed_defaults(
unsigned int master_reseed_interval,
unsigned int slave_reseed_interval,
time_t master_reseed_time_interval,
time_t slave_reseed_time_interval
unsigned int primary_reseed_interval,
unsigned int secondary_reseed_interval,
time_t primary_reseed_time_interval,
time_t secondary_reseed_time_interval
);
RAND_DRBG *OPENSSL_CTX_get0_master_drbg(OPENSSL_CTX *ctx);
RAND_DRBG *OPENSSL_CTX_get0_primary_drbg(OPENSSL_CTX *ctx);
RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx);
RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx);
RAND_DRBG *RAND_DRBG_get0_master(void);
RAND_DRBG *RAND_DRBG_get0_public(void);
RAND_DRBG *RAND_DRBG_get0_private(void);
# ifndef OPENSSL_NO_DEPRECATED_3_0
/* Retain legacy deprecated names */
# define RAND_DRBG_FLAG_MASTER RAND_DRBG_FLAG_PRIMARY
# define OPENSSL_CTX_get0_master_drbg OPENSSL_CTX_get0_primary_drbg
# define RAND_DRBG_get0_master RAND_DRBG_get0_master
# endif
/*
* EXDATA
*/

View File

@ -625,7 +625,7 @@ err:
* expected.
*
* |expect_success|: expected outcome (as reported by RAND_status())
* |master|, |public|, |private|: pointers to the three shared DRBGs
* |primary|, |public|, |private|: pointers to the three shared DRBGs
* |expect_xxx_reseed| =
* 1: it is expected that the specified DRBG is reseeded
* 0: it is expected that the specified DRBG is not reseeded
@ -634,10 +634,10 @@ err:
* |before_reseed| time.
*/
static int test_drbg_reseed(int expect_success,
RAND_DRBG *master,
RAND_DRBG *primary,
RAND_DRBG *public,
RAND_DRBG *private,
int expect_master_reseed,
int expect_primary_reseed,
int expect_public_reseed,
int expect_private_reseed,
time_t reseed_when
@ -646,14 +646,14 @@ static int test_drbg_reseed(int expect_success,
unsigned char buf[32];
time_t before_reseed, after_reseed;
int expected_state = (expect_success ? DRBG_READY : DRBG_ERROR);
unsigned int master_reseed, public_reseed, private_reseed;
unsigned int primary_reseed, public_reseed, private_reseed;
/*
* step 1: check preconditions
*/
/* Test whether seed propagation is enabled */
if (!TEST_int_ne(master_reseed = reseed_counter(master), 0)
if (!TEST_int_ne(primary_reseed = reseed_counter(primary), 0)
|| !TEST_int_ne(public_reseed = reseed_counter(public), 0)
|| !TEST_int_ne(private_reseed = reseed_counter(private), 0))
return 0;
@ -666,7 +666,7 @@ static int test_drbg_reseed(int expect_success,
reseed_when = time(NULL);
/* Generate random output from the public and private DRBG */
before_reseed = expect_master_reseed == 1 ? reseed_when : 0;
before_reseed = expect_primary_reseed == 1 ? reseed_when : 0;
if (!TEST_int_eq(RAND_bytes(buf, sizeof(buf)), expect_success)
|| !TEST_int_eq(RAND_priv_bytes(buf, sizeof(buf)), expect_success))
return 0;
@ -678,14 +678,14 @@ static int test_drbg_reseed(int expect_success,
*/
/* Test whether reseeding succeeded as expected */
if (/*!TEST_int_eq(state(master), expected_state)
if (/*!TEST_int_eq(state(primary), expected_state)
|| */!TEST_int_eq(state(public), expected_state)
|| !TEST_int_eq(state(private), expected_state))
return 0;
if (expect_master_reseed >= 0) {
/* Test whether master DRBG was reseeded as expected */
if (!TEST_int_ge(reseed_counter(master), master_reseed))
if (expect_primary_reseed >= 0) {
/* Test whether primary DRBG was reseeded as expected */
if (!TEST_int_ge(reseed_counter(primary), primary_reseed))
return 0;
}
@ -693,7 +693,7 @@ static int test_drbg_reseed(int expect_success,
/* Test whether public DRBG was reseeded as expected */
if (!TEST_int_ge(reseed_counter(public), public_reseed)
|| !TEST_uint_ge(reseed_counter(public),
reseed_counter(master)))
reseed_counter(primary)))
return 0;
}
@ -701,19 +701,19 @@ static int test_drbg_reseed(int expect_success,
/* Test whether public DRBG was reseeded as expected */
if (!TEST_int_ge(reseed_counter(private), private_reseed)
|| !TEST_uint_ge(reseed_counter(private),
reseed_counter(master)))
reseed_counter(primary)))
return 0;
}
if (expect_success == 1) {
/* Test whether reseed time of master DRBG is set correctly */
if (!TEST_time_t_le(before_reseed, reseed_time(master))
|| !TEST_time_t_le(reseed_time(master), after_reseed))
/* Test whether reseed time of primary DRBG is set correctly */
if (!TEST_time_t_le(before_reseed, reseed_time(primary))
|| !TEST_time_t_le(reseed_time(primary), after_reseed))
return 0;
/* Test whether reseed times of child DRBGs are synchronized with master */
if (!TEST_time_t_ge(reseed_time(public), reseed_time(master))
|| !TEST_time_t_ge(reseed_time(private), reseed_time(master)))
/* Test whether reseed times of child DRBGs are synchronized with primary */
if (!TEST_time_t_ge(reseed_time(public), reseed_time(primary))
|| !TEST_time_t_ge(reseed_time(private), reseed_time(primary)))
return 0;
} else {
ERR_clear_error();
@ -725,10 +725,10 @@ static int test_drbg_reseed(int expect_success,
#if defined(OPENSSL_SYS_UNIX)
/*
* Test whether master, public and private DRBG are reseeded after
* Test whether primary, public and private DRBG are reseeded after
* forking the process.
*/
static int test_drbg_reseed_after_fork(RAND_DRBG *master,
static int test_drbg_reseed_after_fork(RAND_DRBG *primary,
RAND_DRBG *public,
RAND_DRBG *private)
{
@ -745,7 +745,7 @@ static int test_drbg_reseed_after_fork(RAND_DRBG *master,
}
/* I'm the child; check whether all three DRBGs reseed. */
if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1, 0)))
if (!TEST_true(test_drbg_reseed(1, primary, public, private, 1, 1, 1, 0)))
status = 1;
exit(status);
}
@ -758,7 +758,7 @@ static int test_drbg_reseed_after_fork(RAND_DRBG *master,
*/
static int test_rand_drbg_reseed(void)
{
RAND_DRBG *master, *public, *private;
RAND_DRBG *primary, *public, *private;
unsigned char rand_add_buf[256];
int rv = 0;
time_t before_reseed;
@ -771,25 +771,25 @@ static int test_rand_drbg_reseed(void)
return 0;
/* All three DRBGs should be non-null */
if (!TEST_ptr(master = RAND_DRBG_get0_master())
if (!TEST_ptr(primary = RAND_DRBG_get0_master())
|| !TEST_ptr(public = RAND_DRBG_get0_public())
|| !TEST_ptr(private = RAND_DRBG_get0_private()))
return 0;
/* There should be three distinct DRBGs, two of them chained to master */
/* There should be three distinct DRBGs, two of them chained to primary */
if (!TEST_ptr_ne(public, private)
|| !TEST_ptr_ne(public, master)
|| !TEST_ptr_ne(private, master)
|| !TEST_ptr_eq(public->parent, master)
|| !TEST_ptr_eq(private->parent, master))
|| !TEST_ptr_ne(public, primary)
|| !TEST_ptr_ne(private, primary)
|| !TEST_ptr_eq(public->parent, primary)
|| !TEST_ptr_eq(private->parent, primary))
return 0;
/* Disable CRNG testing for the master DRBG */
if (!TEST_true(disable_crngt(master)))
/* Disable CRNG testing for the primary DRBG */
if (!TEST_true(disable_crngt(primary)))
return 0;
/* uninstantiate the three global DRBGs */
RAND_DRBG_uninstantiate(master);
RAND_DRBG_uninstantiate(primary);
RAND_DRBG_uninstantiate(private);
RAND_DRBG_uninstantiate(public);
@ -797,44 +797,44 @@ static int test_rand_drbg_reseed(void)
/*
* Test initial seeding of shared DRBGs
*/
if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1, 0)))
if (!TEST_true(test_drbg_reseed(1, primary, public, private, 1, 1, 1, 0)))
goto error;
/*
* Test initial state of shared DRBGs
*/
if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 0, 0)))
if (!TEST_true(test_drbg_reseed(1, primary, public, private, 0, 0, 0, 0)))
goto error;
/*
* Test whether the public and private DRBG are both reseeded when their
* reseed counters differ from the master's reseed counter.
* reseed counters differ from the primary's reseed counter.
*/
inc_reseed_counter(master);
if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 1, 1, 0)))
inc_reseed_counter(primary);
if (!TEST_true(test_drbg_reseed(1, primary, public, private, 0, 1, 1, 0)))
goto error;
/*
* Test whether the public DRBG is reseeded when its reseed counter differs
* from the master's reseed counter.
* from the primary's reseed counter.
*/
inc_reseed_counter(master);
inc_reseed_counter(primary);
inc_reseed_counter(private);
if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 1, 0, 0)))
if (!TEST_true(test_drbg_reseed(1, primary, public, private, 0, 1, 0, 0)))
goto error;
/*
* Test whether the private DRBG is reseeded when its reseed counter differs
* from the master's reseed counter.
* from the primary's reseed counter.
*/
inc_reseed_counter(master);
inc_reseed_counter(primary);
inc_reseed_counter(public);
if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 1, 0)))
if (!TEST_true(test_drbg_reseed(1, primary, public, private, 0, 0, 1, 0)))
goto error;
#if defined(OPENSSL_SYS_UNIX)
if (!TEST_true(test_drbg_reseed_after_fork(master, public, private)))
if (!TEST_true(test_drbg_reseed_after_fork(primary, public, private)))
goto error;
#endif
@ -845,14 +845,14 @@ static int test_rand_drbg_reseed(void)
/*
* Test whether all three DRBGs are reseeded by RAND_add().
* The before_reseed time has to be measured here and passed into the
* test_drbg_reseed() test, because the master DRBG gets already reseeded
* test_drbg_reseed() test, because the primary DRBG gets already reseeded
* in RAND_add(), whence the check for the condition
* before_reseed <= reseed_time(master) will fail if the time value happens
* before_reseed <= reseed_time(primary) will fail if the time value happens
* to increase between the RAND_add() and the test_drbg_reseed() call.
*/
before_reseed = time(NULL);
RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf));
if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1,
if (!TEST_true(test_drbg_reseed(1, primary, public, private, 1, 1, 1,
before_reseed)))
goto error;
#else /* FIPS_MODULE */
@ -864,7 +864,7 @@ static int test_rand_drbg_reseed(void)
*/
before_reseed = time(NULL);
RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf));
if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 0,
if (!TEST_true(test_drbg_reseed(1, primary, public, private, 0, 0, 0,
before_reseed)))
goto error;
#endif
@ -983,84 +983,88 @@ static int test_multi_thread(void)
static int test_rand_drbg_prediction_resistance(void)
{
RAND_DRBG *m = NULL, *i = NULL, *s = NULL;
RAND_DRBG *x = NULL, *y = NULL, *z = NULL;
unsigned char buf1[51], buf2[sizeof(buf1)];
int ret = 0, mreseed, ireseed, sreseed;
int ret = 0, xreseed, yreseed, zreseed;
if (crngt_skip())
return TEST_skip("CRNGT cannot be disabled");
/* Initialise a three long DRBG chain */
if (!TEST_ptr(m = RAND_DRBG_new(0, 0, NULL))
|| !TEST_true(disable_crngt(m))
|| !TEST_true(RAND_DRBG_instantiate(m, NULL, 0))
|| !TEST_ptr(i = RAND_DRBG_new(0, 0, m))
|| !TEST_true(RAND_DRBG_instantiate(i, NULL, 0))
|| !TEST_ptr(s = RAND_DRBG_new(0, 0, i))
|| !TEST_true(RAND_DRBG_instantiate(s, NULL, 0)))
if (!TEST_ptr(x = RAND_DRBG_new(0, 0, NULL))
|| !TEST_true(disable_crngt(x))
|| !TEST_true(RAND_DRBG_instantiate(x, NULL, 0))
|| !TEST_ptr(y = RAND_DRBG_new(0, 0, x))
|| !TEST_true(RAND_DRBG_instantiate(y, NULL, 0))
|| !TEST_ptr(z = RAND_DRBG_new(0, 0, y))
|| !TEST_true(RAND_DRBG_instantiate(z, NULL, 0)))
goto err;
/* During a normal reseed, only the slave DRBG should be reseed */
inc_reseed_counter(i);
mreseed = reseed_counter(m);
ireseed = reseed_counter(i);
sreseed = reseed_counter(s);
if (!TEST_true(RAND_DRBG_reseed(s, NULL, 0, 0))
|| !TEST_int_eq(reseed_counter(m), mreseed)
|| !TEST_int_eq(reseed_counter(i), ireseed)
|| !TEST_int_gt(reseed_counter(s), sreseed))
/*
* During a normal reseed, only the last DRBG in the chain should
* be reseeded.
*/
inc_reseed_counter(y);
xreseed = reseed_counter(x);
yreseed = reseed_counter(y);
zreseed = reseed_counter(z);
if (!TEST_true(RAND_DRBG_reseed(z, NULL, 0, 0))
|| !TEST_int_eq(reseed_counter(x), xreseed)
|| !TEST_int_eq(reseed_counter(y), yreseed)
|| !TEST_int_gt(reseed_counter(z), zreseed))
goto err;
/*
* When prediction resistance is requested, the request should be
* propagated to the master, so that the entire DRBG chain reseeds.
* propagated to the primary, so that the entire DRBG chain reseeds.
*/
sreseed = reseed_counter(s);
if (!TEST_true(RAND_DRBG_reseed(s, NULL, 0, 1))
|| !TEST_int_gt(reseed_counter(m), mreseed)
|| !TEST_int_gt(reseed_counter(i), ireseed)
|| !TEST_int_gt(reseed_counter(s), sreseed))
zreseed = reseed_counter(z);
if (!TEST_true(RAND_DRBG_reseed(z, NULL, 0, 1))
|| !TEST_int_gt(reseed_counter(x), xreseed)
|| !TEST_int_gt(reseed_counter(y), yreseed)
|| !TEST_int_gt(reseed_counter(z), zreseed))
goto err;
/* During a normal generate, only the slave DRBG should be reseed */
inc_reseed_counter(i);
mreseed = reseed_counter(m);
ireseed = reseed_counter(i);
sreseed = reseed_counter(s);
if (!TEST_true(RAND_DRBG_generate(s, buf1, sizeof(buf1), 0, NULL, 0))
|| !TEST_int_eq(reseed_counter(m), mreseed)
|| !TEST_int_eq(reseed_counter(i), ireseed)
|| !TEST_int_gt(reseed_counter(s), sreseed))
/*
* During a normal generate, only the last DRBG should be reseed */
inc_reseed_counter(y);
xreseed = reseed_counter(x);
yreseed = reseed_counter(y);
zreseed = reseed_counter(z);
if (!TEST_true(RAND_DRBG_generate(z, buf1, sizeof(buf1), 0, NULL, 0))
|| !TEST_int_eq(reseed_counter(x), xreseed)
|| !TEST_int_eq(reseed_counter(y), yreseed)
|| !TEST_int_gt(reseed_counter(z), zreseed))
goto err;
/*
* When a prediction resistant generate is requested, the request
* should be propagated to the master, reseeding the entire DRBG chain.
* should be propagated to the primary, reseeding the entire DRBG chain.
*/
sreseed = reseed_counter(s);
if (!TEST_true(RAND_DRBG_generate(s, buf2, sizeof(buf2), 1, NULL, 0))
|| !TEST_int_gt(reseed_counter(m), mreseed)
|| !TEST_int_gt(reseed_counter(i), ireseed)
|| !TEST_int_gt(reseed_counter(s), sreseed)
zreseed = reseed_counter(z);
if (!TEST_true(RAND_DRBG_generate(z, buf2, sizeof(buf2), 1, NULL, 0))
|| !TEST_int_gt(reseed_counter(x), xreseed)
|| !TEST_int_gt(reseed_counter(y), yreseed)
|| !TEST_int_gt(reseed_counter(z), zreseed)
|| !TEST_mem_ne(buf1, sizeof(buf1), buf2, sizeof(buf2)))
goto err;
/* Verify that a normal reseed still only reseeds the slave DRBG */
inc_reseed_counter(i);
mreseed = reseed_counter(m);
ireseed = reseed_counter(i);
sreseed = reseed_counter(s);
if (!TEST_true(RAND_DRBG_reseed(s, NULL, 0, 0))
|| !TEST_int_eq(reseed_counter(m), mreseed)
|| !TEST_int_eq(reseed_counter(i), ireseed)
|| !TEST_int_gt(reseed_counter(s), sreseed))
/* Verify that a normal reseed still only reseeds the last DRBG */
inc_reseed_counter(y);
xreseed = reseed_counter(x);
yreseed = reseed_counter(y);
zreseed = reseed_counter(z);
if (!TEST_true(RAND_DRBG_reseed(z, NULL, 0, 0))
|| !TEST_int_eq(reseed_counter(x), xreseed)
|| !TEST_int_eq(reseed_counter(y), yreseed)
|| !TEST_int_gt(reseed_counter(z), zreseed))
goto err;
ret = 1;
err:
RAND_DRBG_free(s);
RAND_DRBG_free(i);
RAND_DRBG_free(m);
RAND_DRBG_free(z);
RAND_DRBG_free(y);
RAND_DRBG_free(x);
return ret;
}
@ -1106,15 +1110,15 @@ err:
static int test_set_defaults(void)
{
RAND_DRBG *master = NULL, *public = NULL, *private = NULL;
RAND_DRBG *primary = NULL, *public = NULL, *private = NULL;
/* Check the default type and flags for master, public and private */
return TEST_ptr(master = RAND_DRBG_get0_master())
/* Check the default type and flags for primary, public and private */
return TEST_ptr(primary = RAND_DRBG_get0_master())
&& TEST_ptr(public = RAND_DRBG_get0_public())
&& TEST_ptr(private = RAND_DRBG_get0_private())
&& TEST_int_eq(master->type, RAND_DRBG_TYPE)
&& TEST_int_eq(master->flags,
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_MASTER)
&& TEST_int_eq(primary->type, RAND_DRBG_TYPE)
&& TEST_int_eq(primary->flags,
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIMARY)
&& TEST_int_eq(public->type, RAND_DRBG_TYPE)
&& TEST_int_eq(public->flags,
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC)
@ -1122,12 +1126,12 @@ static int test_set_defaults(void)
&& TEST_int_eq(private->flags,
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIVATE)
/* change master DRBG and check again */
/* change primary DRBG and check again */
&& TEST_true(RAND_DRBG_set_defaults(NID_sha256,
RAND_DRBG_FLAG_MASTER))
&& TEST_true(RAND_DRBG_uninstantiate(master))
&& TEST_int_eq(master->type, NID_sha256)
&& TEST_int_eq(master->flags, RAND_DRBG_FLAG_MASTER)
RAND_DRBG_FLAG_PRIMARY))
&& TEST_true(RAND_DRBG_uninstantiate(primary))
&& TEST_int_eq(primary->type, NID_sha256)
&& TEST_int_eq(primary->flags, RAND_DRBG_FLAG_PRIMARY)
&& TEST_int_eq(public->type, RAND_DRBG_TYPE)
&& TEST_int_eq(public->flags,
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC)
@ -1138,8 +1142,8 @@ static int test_set_defaults(void)
&& TEST_true(RAND_DRBG_set_defaults(NID_sha256,
RAND_DRBG_FLAG_PRIVATE|RAND_DRBG_FLAG_HMAC))
&& TEST_true(RAND_DRBG_uninstantiate(private))
&& TEST_int_eq(master->type, NID_sha256)
&& TEST_int_eq(master->flags, RAND_DRBG_FLAG_MASTER)
&& TEST_int_eq(primary->type, NID_sha256)
&& TEST_int_eq(primary->flags, RAND_DRBG_FLAG_PRIMARY)
&& TEST_int_eq(public->type, RAND_DRBG_TYPE)
&& TEST_int_eq(public->flags,
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC)
@ -1151,8 +1155,8 @@ static int test_set_defaults(void)
RAND_DRBG_FLAG_PUBLIC
| RAND_DRBG_FLAG_HMAC))
&& TEST_true(RAND_DRBG_uninstantiate(public))
&& TEST_int_eq(master->type, NID_sha256)
&& TEST_int_eq(master->flags, RAND_DRBG_FLAG_MASTER)
&& TEST_int_eq(primary->type, NID_sha256)
&& TEST_int_eq(primary->flags, RAND_DRBG_FLAG_PRIMARY)
&& TEST_int_eq(public->type, NID_sha1)
&& TEST_int_eq(public->flags,
RAND_DRBG_FLAG_PUBLIC | RAND_DRBG_FLAG_HMAC)
@ -1167,21 +1171,21 @@ static int test_set_defaults(void)
/* FIPS mode doesn't support CTR DRBG without a derivation function */
#ifndef FIPS_MODULE
/* Change DRBG defaults and change master and check again */
/* Change DRBG defaults and change primary and check again */
&& TEST_true(RAND_DRBG_set_defaults(NID_aes_256_ctr,
RAND_DRBG_FLAG_CTR_NO_DF))
&& TEST_true(RAND_DRBG_uninstantiate(master))
&& TEST_int_eq(master->type, NID_aes_256_ctr)
&& TEST_int_eq(master->flags,
RAND_DRBG_FLAG_MASTER|RAND_DRBG_FLAG_CTR_NO_DF)
&& TEST_true(RAND_DRBG_uninstantiate(primary))
&& TEST_int_eq(primary->type, NID_aes_256_ctr)
&& TEST_int_eq(primary->flags,
RAND_DRBG_FLAG_PRIMARY|RAND_DRBG_FLAG_CTR_NO_DF)
#endif
/* Reset back to the standard defaults */
&& TEST_true(RAND_DRBG_set_defaults(RAND_DRBG_TYPE,
RAND_DRBG_FLAGS
| RAND_DRBG_FLAG_MASTER
| RAND_DRBG_FLAG_PRIMARY
| RAND_DRBG_FLAG_PUBLIC
| RAND_DRBG_FLAG_PRIVATE))
&& TEST_true(RAND_DRBG_uninstantiate(master))
&& TEST_true(RAND_DRBG_uninstantiate(primary))
&& TEST_true(RAND_DRBG_uninstantiate(public))
&& TEST_true(RAND_DRBG_uninstantiate(private));
}

View File

@ -4642,7 +4642,7 @@ ERR_load_CMP_strings ? 3_0_0 EXIST::FUNCTION:CMP
EVP_MD_CTX_set_params ? 3_0_0 EXIST::FUNCTION:
EVP_MD_CTX_get_params ? 3_0_0 EXIST::FUNCTION:
RAND_DRBG_new_ex ? 3_0_0 EXIST::FUNCTION:
OPENSSL_CTX_get0_master_drbg ? 3_0_0 EXIST::FUNCTION:
OPENSSL_CTX_get0_primary_drbg ? 3_0_0 EXIST::FUNCTION:
OPENSSL_CTX_get0_public_drbg ? 3_0_0 EXIST::FUNCTION:
OPENSSL_CTX_get0_private_drbg ? 3_0_0 EXIST::FUNCTION:
BN_CTX_new_ex ? 3_0_0 EXIST::FUNCTION: