rand_drbg: remove RAND_DRBG.

The RAND_DRBG API did not fit well into the new provider concept as
implemented by EVP_RAND and EVP_RAND_CTX. The main reason is that the
RAND_DRBG API is a mixture of 'front end' and 'back end' API calls
and some of its API calls are rather low-level. This holds in particular
for the callback mechanism (RAND_DRBG_set_callbacks()) and the RAND_DRBG
type changing mechanism (RAND_DRBG_set()).

Adding a compatibility layer to continue supporting the RAND_DRBG API as
a legacy API for a regular deprecation period turned out to come at the
price of complicating the new provider API unnecessarily. Since the
RAND_DRBG API exists only since version 1.1.1, it was decided by the OMC
to drop it entirely.

Other related changes:

Use RNG instead of DRBG in EVP_RAND documentation.  The documentation was
using DRBG in places where it should have been RNG or CSRNG.

Move the RAND_DRBG(7) documentation to EVP_RAND(7).

Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
(Merged from https://github.com/openssl/openssl/pull/12509)
master
Pauli 3 years ago
parent 4df0d37ff6
commit 7d615e2178

@ -23,6 +23,22 @@ OpenSSL 3.0
### Changes between 1.1.1 and 3.0 [xx XXX xxxx]
* Remove the RAND_DRBG API
The RAND_DRBG API did not fit well into the new provider concept as
implemented by EVP_RAND and EVP_RAND_CTX. The main reason is that the
RAND_DRBG API is a mixture of 'front end' and 'back end' API calls
and some of its API calls are rather low-level. This holds in particular
for the callback mechanism (RAND_DRBG_set_callbacks()).
Adding a compatibility layer to continue supporting the RAND_DRBG API as
a legacy API for a regular deprecation period turned out to come at the
price of complicating the new provider API unnecessarily. Since the
RAND_DRBG API exists only since version 1.1.1, it was decided by the OMC
to drop it entirely.
*Paul Dale and Matthias St. Pierre*
* Allow SSL_set1_host() and SSL_add1_host() to take IP literal addresses
as well as actual hostnames.

@ -20,6 +20,7 @@ OpenSSL 3.0
### Major changes between OpenSSL 1.1.1 and OpenSSL 3.0 [under development]
* Remove the `RAND_DRBG` API.
* Deprecated the `ENGINE` API.
* Added `OPENSSL_CTX`, a libcrypto library context.
* Interactive mode is removed from the 'openssl' program.

@ -2989,6 +2989,8 @@ RAND_R_RESEED_ERROR:118:reseed error
RAND_R_SELFTEST_FAILURE:119:selftest failure
RAND_R_TOO_LITTLE_NONCE_REQUESTED:135:too little nonce requested
RAND_R_TOO_MUCH_NONCE_REQUESTED:136:too much nonce requested
RAND_R_UNABLE_TO_CREATE_DRBG:143:unable to create drbg
RAND_R_UNABLE_TO_FETCH_DRBG:144:unable to fetch drbg
RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER:141:\
unable to get parent reseed prop counter
RAND_R_UNABLE_TO_GET_PARENT_STRENGTH:138:unable to get parent strength
@ -3467,13 +3469,13 @@ X509V3_R_INCORRECT_POLICY_SYNTAX_TAG:152:incorrect policy syntax tag
X509V3_R_INVALID_ASNUMBER:162:invalid asnumber
X509V3_R_INVALID_ASRANGE:163:invalid asrange
X509V3_R_INVALID_BOOLEAN_STRING:104:invalid boolean string
X509V3_R_INVALID_EMPTY_NAME:108:invalid empty name
X509V3_R_INVALID_EXTENSION_STRING:105:invalid extension string
X509V3_R_INVALID_INHERITANCE:165:invalid inheritance
X509V3_R_INVALID_IPADDRESS:166:invalid ipaddress
X509V3_R_INVALID_MULTIPLE_RDNS:161:invalid multiple rdns
X509V3_R_INVALID_NAME:106:invalid name
X509V3_R_INVALID_NULL_ARGUMENT:107:invalid null argument
X509V3_R_INVALID_EMPTY_NAME:108:invalid empty name
X509V3_R_INVALID_NULL_VALUE:109:invalid null value
X509V3_R_INVALID_NUMBER:140:invalid number
X509V3_R_INVALID_NUMBERS:141:invalid numbers

@ -13,7 +13,6 @@
# include <openssl/evp.h>
# include <openssl/modes.h>
# include <openssl/rand.h>
# include <openssl/rand_drbg.h>
# include "crypto/aria.h"
# include "crypto/evp.h"
# include "crypto/modes.h"

@ -16,7 +16,6 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/rand_drbg.h>
#include <openssl/engine.h>
#include <openssl/params.h>
#include <openssl/core_names.h>

@ -71,33 +71,6 @@ struct evp_rand_ctx_st {
void *data; /* Algorithm-specific data */
} /* EVP_RAND_CTX */ ;
struct evp_rand_st {
OSSL_PROVIDER *prov;
int name_id;
CRYPTO_REF_COUNT refcnt;
CRYPTO_RWLOCK *refcnt_lock;
const OSSL_DISPATCH *dispatch;
OSSL_FUNC_rand_newctx_fn *newctx;
OSSL_FUNC_rand_freectx_fn *freectx;
OSSL_FUNC_rand_instantiate_fn *instantiate;
OSSL_FUNC_rand_uninstantiate_fn *uninstantiate;
OSSL_FUNC_rand_generate_fn *generate;
OSSL_FUNC_rand_reseed_fn *reseed;
OSSL_FUNC_rand_nonce_fn *nonce;
OSSL_FUNC_rand_enable_locking_fn *enable_locking;
OSSL_FUNC_rand_lock_fn *lock;
OSSL_FUNC_rand_unlock_fn *unlock;
OSSL_FUNC_rand_gettable_params_fn *gettable_params;
OSSL_FUNC_rand_gettable_ctx_params_fn *gettable_ctx_params;
OSSL_FUNC_rand_settable_ctx_params_fn *settable_ctx_params;
OSSL_FUNC_rand_get_params_fn *get_params;
OSSL_FUNC_rand_get_ctx_params_fn *get_ctx_params;
OSSL_FUNC_rand_set_ctx_params_fn *set_ctx_params;
OSSL_FUNC_rand_set_callbacks_fn *set_callbacks;
OSSL_FUNC_rand_verify_zeroization_fn *verify_zeroization;
} /* EVP_RAND */ ;
struct evp_keymgmt_st {
int id; /* libcrypto internal */

@ -25,6 +25,32 @@
#include "internal/provider.h"
#include "evp_local.h"
struct evp_rand_st {
OSSL_PROVIDER *prov;
int name_id;
CRYPTO_REF_COUNT refcnt;
CRYPTO_RWLOCK *refcnt_lock;
const OSSL_DISPATCH *dispatch;
OSSL_FUNC_rand_newctx_fn *newctx;
OSSL_FUNC_rand_freectx_fn *freectx;
OSSL_FUNC_rand_instantiate_fn *instantiate;
OSSL_FUNC_rand_uninstantiate_fn *uninstantiate;
OSSL_FUNC_rand_generate_fn *generate;
OSSL_FUNC_rand_reseed_fn *reseed;
OSSL_FUNC_rand_nonce_fn *nonce;
OSSL_FUNC_rand_enable_locking_fn *enable_locking;
OSSL_FUNC_rand_lock_fn *lock;
OSSL_FUNC_rand_unlock_fn *unlock;
OSSL_FUNC_rand_gettable_params_fn *gettable_params;
OSSL_FUNC_rand_gettable_ctx_params_fn *gettable_ctx_params;
OSSL_FUNC_rand_settable_ctx_params_fn *settable_ctx_params;
OSSL_FUNC_rand_get_params_fn *get_params;
OSSL_FUNC_rand_get_ctx_params_fn *get_ctx_params;
OSSL_FUNC_rand_set_ctx_params_fn *set_ctx_params;
OSSL_FUNC_rand_verify_zeroization_fn *verify_zeroization;
} /* EVP_RAND */ ;
static int evp_rand_up_ref(void *vrand)
{
EVP_RAND *rand = (EVP_RAND *)vrand;
@ -144,11 +170,6 @@ static void *evp_rand_from_dispatch(int name_id,
break;
rand->nonce = OSSL_FUNC_rand_nonce(fns);
break;
case OSSL_FUNC_RAND_SET_CALLBACKS:
if (rand->set_callbacks != NULL)
break;
rand->set_callbacks = OSSL_FUNC_rand_set_callbacks(fns);
break;
case OSSL_FUNC_RAND_ENABLE_LOCKING:
if (rand->enable_locking != NULL)
break;
@ -579,38 +600,6 @@ int EVP_RAND_state(EVP_RAND_CTX *ctx)
return state;
}
static int evp_rand_set_callbacks_locked(EVP_RAND_CTX *ctx,
OSSL_INOUT_CALLBACK *get_entropy,
OSSL_CALLBACK *cleanup_entropy,
OSSL_INOUT_CALLBACK *get_nonce,
OSSL_CALLBACK *cleanup_nonce,
void *arg)
{
if (ctx->meth->set_callbacks == NULL) {
EVPerr(0, EVP_R_UNABLE_TO_SET_CALLBACKS);
return 0;
}
ctx->meth->set_callbacks(ctx->data, get_entropy, cleanup_entropy,
get_nonce, cleanup_nonce, arg);
return 1;
}
int EVP_RAND_set_callbacks(EVP_RAND_CTX *ctx,
OSSL_INOUT_CALLBACK *get_entropy,
OSSL_CALLBACK *cleanup_entropy,
OSSL_INOUT_CALLBACK *get_nonce,
OSSL_CALLBACK *cleanup_nonce, void *arg)
{
int res;
if (!evp_rand_lock(ctx))
return 0;
res = evp_rand_set_callbacks_locked(ctx, get_entropy, cleanup_entropy,
get_nonce, cleanup_nonce, arg);
evp_rand_unlock(ctx);
return res;
}
static int evp_rand_verify_zeroization_locked(EVP_RAND_CTX *ctx)
{
if (ctx->meth->verify_zeroization != NULL)

@ -1,6 +1,6 @@
LIBS=../../libcrypto
$COMMON=drbg_lib.c rand_lib.c
$COMMON=rand_lib.c rand_meth.c
$CRYPTO=randfile.c rand_err.c rand_deprecated.c
IF[{- !$disabled{'egd'} -}]

File diff suppressed because it is too large Load Diff

@ -79,6 +79,10 @@ static const ERR_STRING_DATA RAND_str_reasons[] = {
"too little nonce requested"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_TOO_MUCH_NONCE_REQUESTED),
"too much nonce requested"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_CREATE_DRBG),
"unable to create drbg"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_FETCH_DRBG),
"unable to fetch drbg"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER),
"unable to get parent reseed prop counter"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH),

@ -15,7 +15,9 @@
#include "internal/cryptlib.h"
#include <openssl/opensslconf.h>
#include "crypto/rand.h"
#include "crypto/cryptlib.h"
#include <openssl/engine.h>
#include <openssl/core_names.h>
#include "internal/thread_once.h"
#include "rand_local.h"
#include "e_os.h"
@ -105,16 +107,17 @@ int RAND_poll(void)
{
const RAND_METHOD *meth = RAND_get_rand_method();
int ret = meth == RAND_OpenSSL();
RAND_POOL *pool;
if (meth == NULL)
return 0;
#ifndef OPENSSL_NO_DEPRECATED_3_0
if (!ret) {
/* fill random pool and seed the current legacy RNG */
pool = rand_pool_new(RAND_DRBG_STRENGTH, 1,
(RAND_DRBG_STRENGTH + 7) / 8,
RAND_POOL_MAX_LENGTH);
RAND_POOL *pool = rand_pool_new(RAND_DRBG_STRENGTH, 1,
(RAND_DRBG_STRENGTH + 7) / 8,
RAND_POOL_MAX_LENGTH);
if (pool == NULL)
return 0;
@ -131,6 +134,7 @@ int RAND_poll(void)
err:
rand_pool_free(pool);
}
#endif
return ret;
}
@ -235,15 +239,15 @@ int RAND_pseudo_bytes(unsigned char *buf, int num)
int RAND_status(void)
{
RAND_DRBG *drbg;
EVP_RAND_CTX *rand;
const RAND_METHOD *meth = RAND_get_rand_method();
if (meth != NULL && meth != RAND_OpenSSL())
return meth->status != NULL ? meth->status() : 0;
if ((drbg = RAND_DRBG_get0_master()) == NULL || drbg->rand == NULL)
if ((rand = RAND_get0_primary(NULL)) == NULL)
return EVP_RAND_STATE_UNINITIALISED;
return EVP_RAND_state(drbg->rand) == EVP_RAND_STATE_READY;
return EVP_RAND_state(rand) == EVP_RAND_STATE_READY;
}
#else /* !FIPS_MODULE */
@ -260,7 +264,7 @@ const RAND_METHOD *RAND_get_rand_method(void)
*/
int RAND_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num)
{
RAND_DRBG *drbg;
EVP_RAND_CTX *rand;
const RAND_METHOD *meth = RAND_get_rand_method();
if (meth != NULL && meth != RAND_OpenSSL()) {
@ -270,9 +274,9 @@ int RAND_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num)
return -1;
}
drbg = OPENSSL_CTX_get0_private_drbg(ctx);
if (drbg != NULL)
return RAND_DRBG_bytes(drbg, buf, num);
rand = RAND_get0_private(ctx);
if (rand != NULL)
return EVP_RAND_generate(rand, buf, num, 0, 0, NULL, 0);
return 0;
}
@ -284,7 +288,7 @@ int RAND_priv_bytes(unsigned char *buf, int num)
int RAND_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num)
{
RAND_DRBG *drbg;
EVP_RAND_CTX *rand;
const RAND_METHOD *meth = RAND_get_rand_method();
if (meth != NULL && meth != RAND_OpenSSL()) {
@ -294,9 +298,9 @@ int RAND_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num)
return -1;
}
drbg = OPENSSL_CTX_get0_public_drbg(ctx);
if (drbg != NULL)
return RAND_DRBG_bytes(drbg, buf, num);
rand = RAND_get0_public(ctx);
if (rand != NULL)
return EVP_RAND_generate(rand, buf, num, 0, 0, NULL, 0);
return 0;
}
@ -305,3 +309,254 @@ int RAND_bytes(unsigned char *buf, int num)
{
return RAND_bytes_ex(NULL, buf, num);
}
typedef struct rand_global_st {
/*
* The three shared DRBG instances
*
* 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 <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 <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.
*/
EVP_RAND_CTX *primary;
/*
* The <public> DRBG
*
* Used by default for generating random bytes using RAND_bytes().
*
* The <public> secondary DRBG is thread-local, i.e., there is one instance
* per thread.
*/
CRYPTO_THREAD_LOCAL public;
/*
* The <private> DRBG
*
* Used by default for generating private keys using RAND_priv_bytes()
*
* The <private> secondary DRBG is thread-local, i.e., there is one
* instance per thread.
*/
CRYPTO_THREAD_LOCAL private;
} RAND_GLOBAL;
/*
* Initialize the OPENSSL_CTX global DRBGs on first use.
* Returns the allocated global data on success or NULL on failure.
*/
static void *rand_ossl_ctx_new(OPENSSL_CTX *libctx)
{
RAND_GLOBAL *dgbl = OPENSSL_zalloc(sizeof(*dgbl));
if (dgbl == NULL)
return NULL;
#ifndef FIPS_MODULE
/*
* We need to ensure that base libcrypto thread handling has been
* initialised.
*/
OPENSSL_init_crypto(0, NULL);
#endif
dgbl->lock = CRYPTO_THREAD_lock_new();
if (dgbl->lock == NULL)
goto err1;
if (!CRYPTO_THREAD_init_local(&dgbl->private, NULL))
goto err1;
if (!CRYPTO_THREAD_init_local(&dgbl->public, NULL))
goto err2;
return dgbl;
err2:
CRYPTO_THREAD_cleanup_local(&dgbl->private);
err1:
CRYPTO_THREAD_lock_free(dgbl->lock);
OPENSSL_free(dgbl);
return NULL;
}
static void rand_ossl_ctx_free(void *vdgbl)
{
RAND_GLOBAL *dgbl = vdgbl;
if (dgbl == NULL)
return;
CRYPTO_THREAD_lock_free(dgbl->lock);
EVP_RAND_CTX_free(dgbl->primary);
CRYPTO_THREAD_cleanup_local(&dgbl->private);
CRYPTO_THREAD_cleanup_local(&dgbl->public);
OPENSSL_free(dgbl);
}
static const OPENSSL_CTX_METHOD rand_drbg_ossl_ctx_method = {
rand_ossl_ctx_new,
rand_ossl_ctx_free,
};
static RAND_GLOBAL *rand_get_global(OPENSSL_CTX *libctx)
{
return openssl_ctx_get_data(libctx, OPENSSL_CTX_DRBG_INDEX,
&rand_drbg_ossl_ctx_method);
}
static void rand_delete_thread_state(void *arg)
{
OPENSSL_CTX *ctx = arg;
RAND_GLOBAL *dgbl = rand_get_global(ctx);
EVP_RAND_CTX *rand;
if (dgbl == NULL)
return;
rand = CRYPTO_THREAD_get_local(&dgbl->public);
CRYPTO_THREAD_set_local(&dgbl->public, NULL);
EVP_RAND_CTX_free(rand);
rand = CRYPTO_THREAD_get_local(&dgbl->private);
CRYPTO_THREAD_set_local(&dgbl->private, NULL);
EVP_RAND_CTX_free(rand);
}
static EVP_RAND_CTX *rand_new_drbg(OPENSSL_CTX *libctx, EVP_RAND_CTX *parent,
unsigned int reseed_interval,
time_t reseed_time_interval)
{
EVP_RAND *rand = EVP_RAND_fetch(libctx, "CTR-DRBG", NULL);
EVP_RAND_CTX *ctx;
OSSL_PARAM params[4], *p = params;
if (rand == NULL) {
RANDerr(0, RAND_R_UNABLE_TO_FETCH_DRBG);
return NULL;
}
ctx = EVP_RAND_CTX_new(rand, parent);
EVP_RAND_free(rand);
if (ctx == NULL) {
RANDerr(0, RAND_R_UNABLE_TO_CREATE_DRBG);
return NULL;
}
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER,
"AES-256-CTR", 0);
*p++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS,
&reseed_interval);
*p++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL,
&reseed_time_interval);
*p = OSSL_PARAM_construct_end();
if (!EVP_RAND_set_ctx_params(ctx, params)) {
RANDerr(0, RAND_R_ERROR_INITIALISING_DRBG);
EVP_RAND_CTX_free(ctx);
ctx = NULL;
}
return ctx;
}
/*
* Get the primary random generator.
* Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
*
*/
EVP_RAND_CTX *RAND_get0_primary(OPENSSL_CTX *ctx)
{
RAND_GLOBAL *dgbl = rand_get_global(ctx);
if (dgbl == NULL)
return NULL;
if (dgbl->primary == NULL) {
if (!CRYPTO_THREAD_write_lock(dgbl->lock))
return NULL;
if (dgbl->primary == NULL)
dgbl->primary = rand_new_drbg(ctx, NULL, PRIMARY_RESEED_INTERVAL,
PRIMARY_RESEED_TIME_INTERVAL);
CRYPTO_THREAD_unlock(dgbl->lock);
}
return dgbl->primary;
}
/*
* Get the public random generator.
* Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
*/
EVP_RAND_CTX *RAND_get0_public(OPENSSL_CTX *ctx)
{
RAND_GLOBAL *dgbl = rand_get_global(ctx);
EVP_RAND_CTX *rand, *primary;
if (dgbl == NULL)
return NULL;
rand = CRYPTO_THREAD_get_local(&dgbl->public);
if (rand == NULL) {
primary = RAND_get0_primary(ctx);
if (primary == NULL)
return NULL;
ctx = openssl_ctx_get_concrete(ctx);
/*
* If the private is also NULL then this is the first time we've
* used this thread.
*/
if (CRYPTO_THREAD_get_local(&dgbl->private) == NULL
&& !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state))
return NULL;
rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL,
SECONDARY_RESEED_TIME_INTERVAL);
CRYPTO_THREAD_set_local(&dgbl->public, rand);
}
return rand;
}
/*
* Get the private random generator.
* Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
*/
EVP_RAND_CTX *RAND_get0_private(OPENSSL_CTX *ctx)
{
RAND_GLOBAL *dgbl = rand_get_global(ctx);
EVP_RAND_CTX *rand, *primary;
if (dgbl == NULL)
return NULL;
rand = CRYPTO_THREAD_get_local(&dgbl->private);
if (rand == NULL) {
primary = RAND_get0_primary(ctx);
if (primary == NULL)
return NULL;
ctx = openssl_ctx_get_concrete(ctx);
/*
* If the public is also NULL then this is the first time we've
* used this thread.
*/
if (CRYPTO_THREAD_get_local(&dgbl->public) == NULL
&& !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state))
return NULL;
rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL,
SECONDARY_RESEED_TIME_INTERVAL);
CRYPTO_THREAD_set_local(&dgbl->private, rand);
}
return rand;
}

@ -15,48 +15,16 @@
# include <openssl/sha.h>
# include <openssl/hmac.h>
# include <openssl/ec.h>
# include <openssl/rand_drbg.h>
# include <openssl/rand.h>
# include "internal/tsan_assist.h"
# include "crypto/rand.h"
# include "internal/numbers.h"
/* Maximum reseed intervals */
# define MAX_RESEED_INTERVAL (1 << 24)
# define MAX_RESEED_TIME_INTERVAL (1 << 20) /* approx. 12 days */
/* Default reseed intervals */
# 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.
*/
struct rand_drbg_st {
CRYPTO_RWLOCK *lock;
/* The library context this DRBG is associated with, if any */
OPENSSL_CTX *libctx;
RAND_DRBG *parent;
int type; /* the nid of the underlying algorithm */
unsigned short flags; /* various external flags */
/* Application data, mainly used in the KATs. */
CRYPTO_EX_DATA ex_data;
/* Implementation */
EVP_RAND_CTX *rand;
/* Callback functions. See comments in rand_lib.c */
RAND_DRBG_get_entropy_fn get_entropy;
RAND_DRBG_cleanup_entropy_fn cleanup_entropy;
RAND_DRBG_get_nonce_fn get_nonce;
RAND_DRBG_cleanup_nonce_fn cleanup_nonce;
void *callback_data;
};
/* The global RAND method, and the global buffer and DRBG instance. */
extern RAND_METHOD rand_meth;

@ -0,0 +1,69 @@
/*
* Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "rand_local.h"
/* Implements the default OpenSSL RAND_add() method */
static int drbg_add(const void *buf, int num, double randomness)
{
EVP_RAND_CTX *drbg = RAND_get0_primary(NULL);
if (drbg == NULL || num <= 0)
return 0;
return EVP_RAND_reseed(drbg, 0, NULL, 0, buf, num);
}
/* Implements the default OpenSSL RAND_seed() method */
static int drbg_seed(const void *buf, int num)
{
return drbg_add(buf, num, num);
}
/* Implements the default OpenSSL RAND_status() method */
static int drbg_status(void)
{
EVP_RAND_CTX *drbg = RAND_get0_primary(NULL);
if (drbg == NULL)
return 0;
return EVP_RAND_state(drbg) == EVP_RAND_STATE_READY ? 1 : 0;
}
/* Implements the default OpenSSL RAND_bytes() method */
static int drbg_bytes(unsigned char *out, int count)
{
EVP_RAND_CTX *drbg = RAND_get0_public(NULL);
if (drbg == NULL)
return 0;
return EVP_RAND_generate(drbg, out, count, 0, 0, NULL, 0);
}
RAND_METHOD rand_meth = {
drbg_seed,
drbg_bytes,
NULL,
drbg_add,
drbg_bytes,
drbg_status
};
RAND_METHOD *RAND_OpenSSL(void)
{
#ifndef FIPS_MODULE
return &rand_meth;
#else
return NULL;
#endif
}

@ -16,7 +16,6 @@
#include <openssl/crypto.h>
#include <openssl/rand.h>
#include <openssl/rand_drbg.h>
#include <openssl/buffer.h>
#ifdef OPENSSL_SYS_VMS

@ -28,7 +28,7 @@ The random bytes are generated using the L<RAND_bytes(3)> function,
which provides a security level of 256 bits, provided it managed to
seed itself successfully from a trusted operating system entropy source.
Otherwise, the command will fail with a nonzero error code.
For more details, see L<RAND_bytes(3)>, L<RAND(7)>, and L<RAND_DRBG(7)>.
For more details, see L<RAND_bytes(3)>, L<RAND(7)>, and L<EVP_RAND(7)>.
=head1 OPTIONS
@ -63,7 +63,7 @@ Show the output as a hex string.
L<openssl(1)>,
L<RAND_bytes(3)>,
L<RAND(7)>,
L<RAND_DRBG(7)>
L<EVP_RAND(7)>
=head1 HISTORY

@ -10,7 +10,6 @@ ECDH_get_ex_new_index, ECDH_set_ex_data, ECDH_get_ex_data,
EC_KEY_get_ex_new_index, EC_KEY_set_ex_data, EC_KEY_get_ex_data,
ENGINE_get_ex_new_index, ENGINE_set_ex_data, ENGINE_get_ex_data,
EVP_PKEY_get_ex_new_index, EVP_PKEY_set_ex_data, EVP_PKEY_get_ex_data,
RAND_DRBG_set_ex_data, RAND_DRBG_get_ex_data, RAND_DRBG_get_ex_new_index,
RSA_get_ex_new_index, RSA_set_ex_data, RSA_get_ex_data,
RSA_set_app_data, RSA_get_app_data,
SSL_get_ex_new_index, SSL_set_ex_data, SSL_get_ex_data,
@ -70,8 +69,6 @@ TYPE_set_app_data() is a macro that invokes TYPE_set_ex_data() with
B<idx> set to zero.
TYPE_get_app_data() is a macro that invokes TYPE_get_ex_data() with
B<idx> set to zero.
Note that these functions are not defined for the B<RAND_DRBG> type because
there are no backward compatibility concerns.
=head1 RETURN VALUES

@ -82,7 +82,7 @@ L<RAND_add(3)>,
L<RAND_bytes(3)>,
L<RAND_priv_bytes(3)>,
L<RAND(7)>,
L<RAND_DRBG(7)>
L<EVP_RAND(7)>
=head1 HISTORY

@ -50,7 +50,6 @@ The specific structures are:
EC_KEY
ENGINE
EVP_PKEY
RAND_DRBG
RSA
SSL
SSL_CTX

@ -5,7 +5,7 @@
EVP_RAND, EVP_RAND_fetch, EVP_RAND_free, EVP_RAND_up_ref, EVP_RAND_CTX,
EVP_RAND_CTX_new, EVP_RAND_CTX_free, EVP_RAND_instantiate,
EVP_RAND_uninstantiate, EVP_RAND_generate, EVP_RAND_reseed,
EVP_RAND_nonce, EVP_RAND_enable_locking, EVP_RAND_set_callbacks,
EVP_RAND_nonce, EVP_RAND_enable_locking,
EVP_RAND_verify_zeroization, EVP_RAND_strength, EVP_RAND_state,
EVP_RAND_provider, EVP_RAND_CTX_rand, EVP_RAND_is_a, EVP_RAND_number,
EVP_RAND_name, EVP_RAND_names_do_all, EVP_RAND_get_ctx_params,
@ -57,10 +57,6 @@ EVP_RAND_STATE_ERROR - EVP RAND routines
const unsigned char *addin, size_t addin_len);
int EVP_RAND_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen);
int EVP_RAND_enable_locking(EVP_RAND_CTX *ctx);
int EVP_RAND_set_callbacks(EVP_RAND_CTX *ctx, OSSL_CALLBACK *get_entropy,
OSSL_CALLBACK *cleanup_entropy,
OSSL_CALLBACK *get_nonce,
OSSL_CALLBACK *cleanup_nonce, void *arg);
int EVP_RAND_verify_zeroization(EVP_RAND_CTX *ctx);
unsigned int EVP_RAND_strength(EVP_RAND_CTX *ctx);
int EVP_RAND_state(EVP_RAND_CTX *ctx);
@ -157,12 +153,6 @@ EVP_RAND_enable_locking() enables locking for the RAND I<ctx> and all of
its parents. After this I<ctx> will operate in a thread safe manner, albeit
more slowly.
EVP_RAND_set_callbacks() sets callbacks on the RAND I<ctx> to accept
external entropy and nonce input. The callback I<get_entropy> fills a buffer
with new randomness and the callback I<cleanup_entropy> clears and frees the
buffer. Likewise for I<get_nonce> and I<cleanup_nonce>. In all cases the
callbacks are passed I<arg> in addition to an OSSL_PARAM array.
EVP_RAND_get_params() retrieves details about the implementation
I<rand>.
The set of parameters given with I<params> determine exactly what
@ -198,22 +188,22 @@ See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
EVP_RAND_strength() returns the security strength of the RAND I<ctx>.
EVP_RAND_state() returns the current state of the RAND I<ctx>.
States defined by the OpenSSL DRBGs are:
States defined by the OpenSSL RNGs are:
=over 4
=item *
EVP_RAND_STATE_UNINITIALISED: this DRBG is currently uninitialised.
EVP_RAND_STATE_UNINITIALISED: this RNG is currently uninitialised.
The instantiate call will change this to the ready state.
=item *
EVP_RAND_STATE_READY: this DRBG is currently ready to generate output.
EVP_RAND_STATE_READY: this RNG is currently ready to generate output.
=item *
EVP_RAND_STATE_ERROR: this DRBG is in an error state.
EVP_RAND_STATE_ERROR: this RNG is in an error state.
=back

@ -1,90 +0,0 @@
=pod
=head1 NAME
RAND_DRBG_generate,
RAND_DRBG_bytes
- generate random bytes using the given drbg instance
=head1 SYNOPSIS
#include <openssl/rand_drbg.h>
int RAND_DRBG_generate(RAND_DRBG *drbg,
unsigned char *out, size_t outlen,
int prediction_resistance,
const unsigned char *adin, size_t adinlen);
int RAND_DRBG_bytes(RAND_DRBG *drbg,
unsigned char *out, size_t outlen);
=head1 DESCRIPTION
RAND_DRBG_generate() generates B<outlen> random bytes using the given
DRBG instance B<drbg> and stores them in the buffer at B<out>.
Before generating the output, the DRBG instance checks whether the maximum
number of generate requests (I<reseed interval>) or the maximum timespan
(I<reseed time interval>) since its last seeding have been reached.
If this is the case, the DRBG reseeds automatically.
Additionally, an immediate reseeding can be requested by setting the
B<prediction_resistance> flag to 1.
Requesting prediction resistance is a relative expensive operation.
See NOTES section for more details.
The caller can optionally provide additional data to be used for reseeding
by passing a pointer B<adin> to a buffer of length B<adinlen>.
This additional data is mixed into the internal state of the random
generator but does not contribute to the entropy count.
The additional data can be omitted by setting B<adin> to NULL and
B<adinlen> to 0;
RAND_DRBG_bytes() generates B<outlen> random bytes using the given
DRBG instance B<drbg> and stores them in the buffer at B<out>.
This function is a wrapper around the RAND_DRBG_generate() call,
which collects some additional data from low entropy sources
(e.g., a high resolution timer) and calls
RAND_DRBG_generate(drbg, out, outlen, 0, adin, adinlen).
=head1 RETURN VALUES
RAND_DRBG_generate() and RAND_DRBG_bytes() return 1 on success,
and 0 on failure.
=head1 NOTES
The I<reseed interval> and I<reseed time interval> of the B<drbg> are set to
reasonable default values, which in general do not have to be adjusted.
If necessary, they can be changed using L<RAND_DRBG_set_reseed_interval(3)>
and L<RAND_DRBG_set_reseed_time_interval(3)>, respectively.
A request for prediction resistance can only be satisfied by pulling fresh
entropy from a live entropy source (section 5.5.2 of [NIST SP 800-90C]).
It is up to the user to ensure that a live entropy source is configured
and is being used.
=head1 SEE ALSO
L<RAND_bytes(3)>,
L<RAND_DRBG_set_reseed_interval(3)>,
L<RAND_DRBG_set_reseed_time_interval(3)>,
L<RAND_DRBG(7)>
=head1 HISTORY
The RAND_DRBG functions were added in OpenSSL 1.1.1.
Prediction resistance is supported from OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

@ -1,97 +0,0 @@
=pod
=head1 NAME
OPENSSL_CTX_get0_primary_drbg,
OPENSSL_CTX_get0_public_drbg,
OPENSSL_CTX_get0_private_drbg,
RAND_DRBG_get0_master,
RAND_DRBG_get0_public,
RAND_DRBG_get0_private
- get access to the global RAND_DRBG instances
=head1 SYNOPSIS
#include <openssl/rand_drbg.h>
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);
=head1 DESCRIPTION
The default RAND API implementation (RAND_OpenSSL()) utilizes three
shared DRBG instances which are accessed via the RAND API:
The I<public> and I<private> DRBG are thread-local instances, which are used
by RAND_bytes() and RAND_priv_bytes(), respectively.
The I<master> DRBG is a global instance, which is not intended to be used
directly, but is used internally to reseed the other two instances.
These functions here provide access to the shared DRBG instances.
=head1 RETURN VALUES
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
for the given OPENSSL_CTX B<ctx>.
OPENSSL_CTX_get0_private_drbg() returns a pointer to the I<private> DRBG instance
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_primary_drbg(), OPENSSL_CTX_get0_public_drbg() and
OPENSSL_CTX_get0_private_drbg() respectively except that the default OPENSSL_CTX
is always used.
=head1 NOTES
It is not thread-safe to access the I<master> DRBG instance.
The I<public> and I<private> DRBG instance can be accessed safely, because
they are thread-local. Note however, that changes to these two instances
apply only to the current thread.
For that reason it is recommended not to change the settings of these
three instances directly.
Instead, an application should change the default settings for new DRBG instances
at initialization time, before creating additional threads.
During initialization, it is possible to change the reseed interval
and reseed time interval.
It is also possible to exchange the reseeding callbacks entirely.
=head1 SEE ALSO
L<RAND_DRBG_set_callbacks(3)>,
L<RAND_DRBG_set_reseed_defaults(3)>,
L<RAND_DRBG_set_reseed_interval(3)>,
L<RAND_DRBG_set_reseed_time_interval(3)>,
L<RAND_DRBG_set_callbacks(3)>,
L<RAND_DRBG_generate(3)>,
L<RAND_DRBG(7)>
=head1 HISTORY
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.
=head1 COPYRIGHT
Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

@ -1,170 +0,0 @@
=pod
=head1 NAME
RAND_DRBG_new_ex,
RAND_DRBG_new,
RAND_DRBG_set,
RAND_DRBG_set_defaults,
RAND_DRBG_instantiate,
RAND_DRBG_uninstantiate,
RAND_DRBG_free,
RAND_DRBG_verify_zeroization
- initialize and cleanup a RAND_DRBG instance
=head1 SYNOPSIS
#include <openssl/rand_drbg.h>
RAND_DRBG *RAND_DRBG_new_ex(OPENSSL_CTX *ctx,
int type,
unsigned int flags,
RAND_DRBG *parent);
RAND_DRBG *RAND_DRBG_new(int type,
unsigned int flags,
RAND_DRBG *parent);
int RAND_DRBG_set_defaults(int type, unsigned int flags);
int RAND_DRBG_instantiate(RAND_DRBG *drbg,
const unsigned char *pers, size_t perslen);
int RAND_DRBG_uninstantiate(RAND_DRBG *drbg);
void RAND_DRBG_free(RAND_DRBG *drbg);
int RAND_DRBG_verify_zeroization(RAND_DRBG *drbg);
Deprecated since OpenSSL 3.0, can be hidden entirely by defining
B<OPENSSL_API_COMPAT> with a suitable version value, see
L<openssl_user_macros(7)>:
int RAND_DRBG_set(RAND_DRBG *drbg,
int type, unsigned int flags);
=head1 DESCRIPTION
RAND_DRBG_new_ex() creates a new DRBG instance of the given B<type> for the
given OPENSSL_CTX <ctx>.
The <ctx> parameter can be NULL in which case the default OPENSSL_CTX is used.
RAND_DRBG_new() is the same as RAND_DRBG_new_ex() except that the default
OPENSSL_CTX is always used.
RAND_DRBG_set() initializes the B<drbg> with the given B<type> and B<flags>.
This function is deprecated. Applications should instead use
RAND_DRBG_new_ex() to create a new DRBG.
RAND_DRBG_set_defaults() sets the default B<type> and B<flags> for new DRBG
instances.
The DRBG types are AES-CTR, HMAC and HASH so B<type> can be one of the
following values:
NID_aes_128_ctr, NID_aes_192_ctr, NID_aes_256_ctr, NID_sha1, NID_sha224,
NID_sha256, NID_sha384, NID_sha512, NID_sha512_224, NID_sha512_256,
NID_sha3_224, NID_sha3_256, NID_sha3_384 or NID_sha3_512.
If this method is not called then the default type is given by NID_aes_256_ctr
and the default flags are zero.
Before the DRBG can be used to generate random bits, it is necessary to set
its type and to instantiate it.
The optional B<flags> argument specifies a set of bit flags which can be
joined using the | operator. The supported flags are:
=over 4
=item RAND_DRBG_FLAG_CTR_NO_DF
Disables the use of the derivation function ctr_df. For an explanation,
see [NIST SP 800-90A Rev. 1].
=item RAND_DRBG_FLAG_HMAC
Enables use of HMAC instead of the HASH DRBG.
=item RAND_DRBG_FLAG_PRIMARY
=item RAND_DRBG_FLAG_PUBLIC
=item RAND_DRBG_FLAG_PRIVATE
These 3 flags can be used to set the individual DRBG types created. Multiple
calls are required to set the types to different values. If none of these 3
flags are used, then the same type and flags are used for all 3 DRBGs in the
B<drbg> chain (<master>, <public> and <private>).
=back
If a B<parent> instance is specified then this will be used instead of
the default entropy source for reseeding the B<drbg>. It is said that the
B<drbg> is I<chained> to its B<parent>.
For more information, see the NOTES section.
RAND_DRBG_instantiate()
seeds the B<drbg> instance using random input from trusted entropy sources.
Optionally, a personalization string B<pers> of length B<perslen> can be
specified.
To omit the personalization string, set B<pers>=NULL and B<perslen>=0;
RAND_DRBG_uninstantiate()
clears the internal state of the B<drbg> and puts it back in the
uninstantiated state.
RAND_DRBG_verify_zeroization() confirms if the internal DRBG state is
currently zeroed.
=head1 RETURN VALUES
RAND_DRBG_new_ex() and RAND_DRBG_new() return a pointer to a DRBG instance
allocated on the heap.
RAND_DRBG_set(),
RAND_DRBG_instantiate(), and
RAND_DRBG_uninstantiate()
return 1 on success, and 0 on failure.
RAND_DRBG_verify_zeroization() returns 1 if the DRBG state is current zeroed,
and 0 if not.
RAND_DRBG_free() does not return a value.
=head1 NOTES
The DRBG design supports I<chaining>, which means that a DRBG instance can
use another B<parent> DRBG instance instead of the default entropy source
to obtain fresh random input for reseeding, provided that B<parent> DRBG
instance was properly instantiated, either from a trusted entropy source,
or from yet another parent DRBG instance.
For a detailed description of the reseeding process, see L<RAND_DRBG(7)>.
The default DRBG type and flags 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_defaults() before creating any thread and before calling any
cryptographic routines that obtain random data directly or indirectly.
=head1 SEE ALSO
L<RAND_DRBG_generate(3)>,
L<RAND_DRBG(7)>
=head1 HISTORY
The RAND_DRBG_set() function was deprecated in OpenSSL 3.0.
The RAND_DRBG functions were added in OpenSSL 1.1.1.
=head1 COPYRIGHT
Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

@ -1,118 +0,0 @@
=pod
=head1 NAME
RAND_DRBG_reseed,
RAND_DRBG_set_reseed_interval,
RAND_DRBG_set_reseed_time_interval,
RAND_DRBG_set_reseed_defaults
- reseed a RAND_DRBG instance
=head1 SYNOPSIS
#include <openssl/rand_drbg.h>
int RAND_DRBG_reseed(RAND_DRBG *drbg,
const unsigned char *adin, size_t adinlen,
int prediction_resistance);
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 primary_reseed_interval,
unsigned int secondary_reseed_interval,
time_t primary_reseed_time_interval,
time_t secondary_reseed_time_interval
);
=head1 DESCRIPTION
RAND_DRBG_reseed()
reseeds the given B<drbg>, obtaining entropy input from its entropy source
and mixing in the specified additional data provided in the buffer B<adin>
of length B<adinlen>.
The additional data can be omitted by setting B<adin> to NULL and B<adinlen>
to 0.
An immediate reseeding can be requested by setting the
B<prediction_resistance> flag to 1.
Requesting prediction resistance is a relative expensive operation.
See NOTES section for more details.
RAND_DRBG_set_reseed_interval()
sets the reseed interval of the B<drbg>, which is the maximum allowed number
of generate requests between consecutive reseedings.
If B<interval> > 0, then the B<drbg> will reseed automatically whenever the
number of generate requests since its last seeding exceeds the given reseed
interval.
If B<interval> == 0, then this feature is disabled.
RAND_DRBG_set_reseed_time_interval()
sets the reseed time interval of the B<drbg>, which is the maximum allowed
number of seconds between consecutive reseedings.
If B<interval> > 0, then the B<drbg> will reseed automatically whenever the
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<primary_reseed_interval> and B<secondary_reseed_interval>)
and the reseed time interval
(B<primary_reseed_time_interval> and B<secondary_reseed_tme_interval>)
of DRBG instances.
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
RAND_DRBG_reseed(),
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,
so in general it is not necessary to reseed it explicitly, or to modify
its reseeding thresholds.
Normally, the entropy input for seeding a DRBG is either obtained from a
trusted os entropy source or from a parent DRBG instance, which was seeded
(directly or indirectly) from a trusted os entropy source.
In exceptional cases it is possible to replace the reseeding mechanism entirely
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
(<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
L<RAND_DRBG_generate(3)>,
L<RAND_DRBG_bytes(3)>,
L<RAND_DRBG_set_callbacks(3)>.
L<RAND_DRBG(7)>
=head1 HISTORY
The RAND_DRBG functions were added in OpenSSL 1.1.1.
Prediction resistance is supported from OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

@ -1,171 +0,0 @@
=pod
=head1 NAME
RAND_DRBG_set_callbacks,
RAND_DRBG_set_callback_data,
RAND_DRBG_get_callback_data,
RAND_DRBG_get_entropy_fn,
RAND_DRBG_cleanup_entropy_fn,
RAND_DRBG_get_nonce_fn,
RAND_DRBG_cleanup_nonce_fn
- set callbacks for reseeding
=head1 SYNOPSIS
#include <openssl/rand_drbg.h>
int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
RAND_DRBG_get_entropy_fn get_entropy,
RAND_DRBG_cleanup_entropy_fn cleanup_entropy,
RAND_DRBG_get_nonce_fn get_nonce,
RAND_DRBG_cleanup_nonce_fn cleanup_nonce);
int RAND_DRBG_set_callback_data(RAND_DRBG *drbg, void *ctx);
void *RAND_DRBG_get_callback_data(RAND_DRBG *drbg);
=head2 Callback Functions
typedef size_t (*RAND_DRBG_get_entropy_fn)(
RAND_DRBG *drbg,
unsigned char **pout,
int entropy,
size_t min_len, size_t max_len,
int prediction_resistance);
typedef void (*RAND_DRBG_cleanup_entropy_fn)(
RAND_DRBG *drbg,
unsigned char *out, size_t outlen);
typedef size_t (*RAND_DRBG_get_nonce_fn)(
RAND_DRBG *drbg,
unsigned char **pout,
int entropy,
size_t min_len, size_t max_len);
typedef void (*RAND_DRBG_cleanup_nonce_fn)(
RAND_DRBG *drbg,
unsigned char *out, size_t outlen);
=head1 DESCRIPTION
RAND_DRBG_set_callbacks() sets the callbacks for obtaining fresh entropy and
the nonce when reseeding the given B<drbg>.
The callback functions are implemented and provided by the caller.
Their parameter lists need to match the function prototypes above.
RAND_DRBG_set_callback_data() can be used to store a pointer to some context
specific data, which can subsequently be retrieved by the entropy and nonce
callbacks using RAND_DRBG_get_callback_data().
The ownership of the context data remains with the caller, i.e., it is the
caller's responsibility to keep it available as long as it is needed by the
callbacks and free it after use.
For more information about the callback data see the NOTES section.
Setting the callbacks or the callback data is allowed only if the DRBG has
not been initialized yet.
Otherwise, the operation will fail.
To change the settings for one of the three shared DRBGs it is necessary to call
RAND_DRBG_uninstantiate() first.
The B<get_entropy>() callback is called by the B<drbg> when it requests fresh
random input.
It is expected that the callback allocates and fills a random buffer of size
B<min_len> <= size <= B<max_len> (in bytes) which contains at least B<entropy>
bits of randomness.
The B<prediction_resistance> flag indicates whether the reseeding was
triggered by a prediction resistance request.
The buffer's address is to be returned in *B<pout> and the number of collected
randomness bytes as return value.
If the callback fails to acquire at least B<entropy> bits of randomness,
it must indicate an error by returning a buffer length of 0.
If B<prediction_resistance> was requested and the random source of the DRBG
does not satisfy the conditions requested by [NIST SP 800-90C], then
it must also indicate an error by returning a buffer length of 0.
See NOTES section for more details.
The B<cleanup_entropy>() callback is called from the B<drbg> to clear and
free the buffer allocated previously by get_entropy().
The values B<out> and B<outlen> are the random buffer's address and length,
as returned by the get_entropy() callback.
The B<get_nonce>() and B<cleanup_nonce>() callbacks are used to obtain a nonce
and free it again. A nonce is only required for instantiation (not for reseeding)
and only in the case where the DRBG uses a derivation function.
The callbacks are analogous to get_entropy() and cleanup_entropy(),
except for the missing prediction_resistance flag.
If the derivation function is disabled, then no nonce is used for instantiation,
and the B<get_nonce>() and B<cleanup_nonce>() callbacks can be omitted by
setting them to NULL.
=head1 RETURN VALUES
RAND_DRBG_set_callbacks() returns 1 on success, and 0 on failure.
RAND_DRBG_set_callback_data() returns 1 on success, and 0 on failure.
RAND_DRBG_get_callback_data() returns the pointer to the callback data,
which is NULL if none has been set previously.
=head1 NOTES
It is important that B<cleanup_entropy>() and B<cleanup_nonce>() clear the buffer
contents safely before freeing it, in order not to leave sensitive information
about the DRBG's state in memory.
A request for prediction resistance can only be satisfied by pulling fresh
entropy from a live entropy source (section 5.5.2 of [NIST SP 800-90C]).
It is up to the user to ensure that a live entropy source is configured
and is being used.
The derivation function is disabled by calling the RAND_DRBG_new_ex()
function with the RAND_DRBG_FLAG_CTR_NO_DF flag. For more information on
the derivation function and when it can be omitted, see [NIST SP 800-90A
Rev. 1]. Roughly speaking it can be omitted if the random source has "full
entropy", that is, it contains 8 bits of entropy per byte. In a FIPS context,
the derivation function can never be omitted.
Even if a nonce is required, the B<get_nonce>() and B<cleanup_nonce>()
callbacks can be omitted by setting them to NULL.
In this case the DRBG will automatically request an extra amount of entropy
(using the B<get_entropy>() and B<cleanup_entropy>() callbacks) which it will
utilize for the nonce, following the recommendations of [NIST SP 800-90A Rev. 1],
section 8.6.7.
The callback data is a rather specialized feature, because in general the
random sources don't (and in fact, they must not) depend on any state provided
by the DRBG.
There are however exceptional cases where this feature is useful, most notably
for implementing known answer tests (KATs) or deterministic signatures like
those specified in RFC6979, which require passing a specified entropy and nonce
for instantiating the DRBG.
=head1 SEE ALSO
L<RAND_DRBG_new(3)>,
L<RAND_DRBG_reseed(3)>,
L<RAND_DRBG(7)>
=head1 HISTORY
The RAND_DRBG functions were added in OpenSSL 1.1.1.
=head1 COPYRIGHT
Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

@ -58,7 +58,7 @@ should consider using L<RAND_load_file(3)> instead.
NOTE: In FIPS mode, random data provided by the application is not considered to
be a trusted entropy source. It is mixed into the internal state of the RNG as
additional data only and this does not count as a full reseed.
For more details, see L<RAND_DRBG(7)>.
For more details, see L<EVP_RAND(7)>.
RAND_seed() is equivalent to RAND_add() with B<randomness> set to B<num>.
@ -92,7 +92,7 @@ L<RAND_bytes(3)>,
L<RAND_egd(3)>,
L<RAND_load_file(3)>,
L<RAND(7)>
L<RAND_DRBG(7)>
L<EVP_RAND(7)>
=head1 HISTORY