#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
-#include "rand_lcl.h"
+#include "rand_local.h"
#include "internal/thread_once.h"
-#include "internal/rand_int.h"
-#include "internal/cryptlib_int.h"
+#include "crypto/rand.h"
+#include "crypto/cryptlib.h"
/*
* Support framework for NIST SP 800-90A DRBG
{
DRBG_GLOBAL *dgbl = vdgbl;
+ if (dgbl == NULL)
+ return;
+
RAND_DRBG_free(dgbl->master_drbg);
CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg);
CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg);
{
DRBG_NONCE_GLOBAL *dngbl = vdngbl;
+ if (dngbl == NULL)
+ return;
+
CRYPTO_THREAD_lock_free(dngbl->rand_nonce_lock);
OPENSSL_free(dngbl);
return 0;
memset(&data, 0, sizeof(data));
- pool = rand_pool_new(0, min_len, max_len);
+ pool = rand_pool_new(0, 0, min_len, max_len);
if (pool == NULL)
return 0;
void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
unsigned char *out, size_t outlen)
{
- OPENSSL_secure_clear_free(out, outlen);
+ OPENSSL_clear_free(out, outlen);
}
/*
drbg->libctx = ctx;
drbg->secure = secure && CRYPTO_secure_allocated(drbg);
- drbg->fork_count = rand_fork_count;
+ drbg->fork_id = openssl_get_fork_id();
drbg->parent = parent;
if (parent == NULL) {
drbg->meth->uninstantiate(drbg);
rand_pool_free(drbg->adin_pool);
CRYPTO_THREAD_lock_free(drbg->lock);
- CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
+#ifndef FIPS_MODE
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RAND_DRBG, drbg, &drbg->ex_data);
+#endif
if (drbg->secure)
OPENSSL_secure_clear_free(drbg, sizeof(*drbg));
}
if (drbg->state != DRBG_UNINITIALISED) {
- RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
- drbg->state == DRBG_ERROR ? RAND_R_IN_ERROR_STATE
- : RAND_R_ALREADY_INSTANTIATED);
+ if (drbg->state == DRBG_ERROR)
+ RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_IN_ERROR_STATE);
+ else
+ RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ALREADY_INSTANTIATED);
goto end;
}
/*
* NIST SP800-90Ar1 section 9.1 says you can combine getting the entropy
* and nonce in 1 call by increasing the entropy with 50% and increasing
- * the minimum length to accomadate the length of the nonce.
+ * the minimum length to accommodate the length of the nonce.
* We do this in case a nonce is require and get_nonce is NULL.
*/
if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) {
int prediction_resistance,
const unsigned char *adin, size_t adinlen)
{
+ int fork_id;
int reseed_required = 0;
if (drbg->state != DRBG_READY) {
return 0;
}
- if (drbg->fork_count != rand_fork_count) {
- drbg->fork_count = rand_fork_count;
+ fork_id = openssl_get_fork_id();
+
+ if (drbg->fork_id != fork_id) {
+ drbg->fork_id = fork_id;
reseed_required = 1;
}
if (drbg->adin_pool == NULL) {
if (drbg->type == 0)
goto err;
- drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen);
+ drbg->adin_pool = rand_pool_new(0, 0, 0, drbg->max_adinlen);
if (drbg->adin_pool == NULL)
goto err;
}
return 1;
}
+#ifndef FIPS_MODE
/*
* Get and set the EXDATA
*/
{
return CRYPTO_get_ex_data(&drbg->ex_data, idx);
}
-
+#endif
/*
* The following functions provide a RAND_METHOD that works on the
return NULL;
}
-static void drbg_delete_thread_state(OPENSSL_CTX *ctx)
+static void drbg_delete_thread_state(void *arg)
{
+ OPENSSL_CTX *ctx = arg;
DRBG_GLOBAL *dgbl = drbg_get_global(ctx);
RAND_DRBG *drbg;
drbg = CRYPTO_THREAD_get_local(&dgbl->public_drbg);
if (drbg == NULL) {
- if (!ossl_init_thread_start(NULL, drbg_delete_thread_state))
+ ctx = openssl_ctx_get_concrete(ctx);
+ /*
+ * If the private_drbg is also NULL then this is the first time we've
+ * used this thread.
+ */
+ 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, dgbl->master_drbg, RAND_DRBG_TYPE_PUBLIC);
CRYPTO_THREAD_set_local(&dgbl->public_drbg, drbg);
drbg = CRYPTO_THREAD_get_local(&dgbl->private_drbg);
if (drbg == NULL) {
- if (!ossl_init_thread_start(NULL, drbg_delete_thread_state))
+ ctx = openssl_ctx_get_concrete(ctx);
+ /*
+ * If the public_drbg is also NULL then this is the first time we've
+ * used this thread.
+ */
+ 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, dgbl->master_drbg, RAND_DRBG_TYPE_PRIVATE);
CRYPTO_THREAD_set_local(&dgbl->private_drbg, drbg);