diff options
24 files changed, 1930 insertions, 1957 deletions
diff --git a/crypto/evp/build.info b/crypto/evp/build.info index edef4930cb..ccd8357453 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -2,7 +2,7 @@ LIBS=../../libcrypto $COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c \ mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c \ m_sigver.c pmeth_lib.c signature.c p_lib.c pmeth_gn.c exchange.c \ - pmeth_check.c rand_meth.c + pmeth_check.c evp_rand.c SOURCE[../../libcrypto]=$COMMON\ encode.c evp_key.c evp_cnf.c \ diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index 03a1f36e1b..132534464f 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -69,16 +69,18 @@ struct evp_kdf_ctx_st { struct evp_rand_ctx_st { EVP_RAND *meth; /* Method structure */ void *data; /* Algorithm-specific data */ - EVP_RAND_CTX *parent; /* Parent seed source */ - size_t max_request; /* Cached: maximum number of bytes generated */ - unsigned int strength; /* Cache: bit strenght of generator */ + size_t max_request; /* + * Cached: maximum number of bytes generated + * in a single call to the generate function + */ + unsigned int strength; /* Cached: bit strength of generator */ } /* EVP_RAND_CTX */ ; struct evp_rand_st { OSSL_PROVIDER *prov; int name_id; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; + CRYPTO_RWLOCK *refcnt_lock; const OSSL_DISPATCH *dispatch; OSSL_OP_rand_newctx_fn *newctx; @@ -88,16 +90,16 @@ struct evp_rand_st { OSSL_OP_rand_generate_fn *generate; OSSL_OP_rand_reseed_fn *reseed; OSSL_OP_rand_nonce_fn *nonce; - OSSL_OP_rand_set_callbacks_fn *set_callbacks; - OSSL_OP_rand_enable_locking_fn *enable_prov_locking; - OSSL_OP_rand_lock_fn *prov_lock; - OSSL_OP_rand_unlock_fn *prov_unlock; + OSSL_OP_rand_enable_locking_fn *enable_locking; + OSSL_OP_rand_lock_fn *lock; + OSSL_OP_rand_unlock_fn *unlock; OSSL_OP_rand_gettable_params_fn *gettable_params; OSSL_OP_rand_gettable_ctx_params_fn *gettable_ctx_params; OSSL_OP_rand_settable_ctx_params_fn *settable_ctx_params; OSSL_OP_rand_get_params_fn *get_params; OSSL_OP_rand_get_ctx_params_fn *get_ctx_params; OSSL_OP_rand_set_ctx_params_fn *set_ctx_params; + OSSL_OP_rand_set_callbacks_fn *set_callbacks; OSSL_OP_rand_verify_zeroization_fn *verify_zeroization; } /* EVP_RAND */ ; diff --git a/crypto/evp/rand_meth.c b/crypto/evp/evp_rand.c index 0f1745411d..f7bc321f29 100644 --- a/crypto/evp/rand_meth.c +++ b/crypto/evp/evp_rand.c @@ -11,7 +11,6 @@ #include <stdio.h> #include <stdlib.h> -#include "internal/cryptlib.h" #include <openssl/engine.h> #include <openssl/evp.h> #include <openssl/x509v3.h> @@ -21,6 +20,7 @@ #include <openssl/crypto.h> #include "crypto/asn1.h" #include "crypto/evp.h" +#include "internal/cryptlib.h" #include "internal/numbers.h" #include "internal/provider.h" #include "evp_local.h" @@ -31,7 +31,7 @@ static int evp_rand_up_ref(void *vrand) int ref = 0; if (rand != NULL) - return CRYPTO_UP_REF(&rand->refcnt, &ref, rand->lock); + return CRYPTO_UP_REF(&rand->refcnt, &ref, rand->refcnt_lock); return 1; } @@ -40,10 +40,10 @@ static void evp_rand_free(void *vrand){ int ref = 0; if (rand != NULL) { - CRYPTO_DOWN_REF(&rand->refcnt, &ref, rand->lock); + CRYPTO_DOWN_REF(&rand->refcnt, &ref, rand->refcnt_lock); if (ref <= 0) { ossl_provider_free(rand->prov); - CRYPTO_THREAD_lock_free(rand->lock); + CRYPTO_THREAD_lock_free(rand->refcnt_lock); OPENSSL_free(rand); } } @@ -51,11 +51,11 @@ static void evp_rand_free(void *vrand){ static void *evp_rand_new(void) { - EVP_RAND *rand = NULL; + EVP_RAND *rand = OPENSSL_zalloc(sizeof(*rand)); - if ((rand = OPENSSL_zalloc(sizeof(*rand))) == NULL - || (rand->lock = CRYPTO_THREAD_lock_new()) == NULL) { - evp_rand_free(rand); + if (rand == NULL + || (rand->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(rand); return NULL; } rand->refcnt = 1; @@ -63,26 +63,27 @@ static void *evp_rand_new(void) } /* Enable locking of the underlying DRBG/RAND if available */ -int EVP_RAND_CTX_enable_locking(EVP_RAND_CTX *rand) +int EVP_RAND_enable_locking(EVP_RAND_CTX *rand) { - if (rand->meth->enable_prov_locking != NULL) - return rand->meth->enable_prov_locking(rand->data); - return 1; + if (rand->meth->enable_locking != NULL) + return rand->meth->enable_locking(rand->data); + EVPerr(0, EVP_R_LOCKING_NOT_SUPPORTED); + return 0; } /* Lock the underlying DRBG/RAND if available */ static int evp_rand_lock(EVP_RAND_CTX *rand) { - if (rand->meth->prov_lock != NULL) - return rand->meth->prov_lock(rand->data); + if (rand->meth->lock != NULL) + return rand->meth->lock(rand->data); return 1; } /* Unlock the underlying DRBG/RAND if available */ static void evp_rand_unlock(EVP_RAND_CTX *rand) { - if (rand->meth->prov_unlock != NULL) - rand->meth->prov_unlock(rand->data); + if (rand->meth->unlock != NULL) + rand->meth->unlock(rand->data); } static void *evp_rand_from_dispatch(int name_id, @@ -90,9 +91,9 @@ static void *evp_rand_from_dispatch(int name_id, OSSL_PROVIDER *prov) { EVP_RAND *rand = NULL; - int fnrandcnt = 0, fnctxcnt = 0; + int fnrandcnt = 0, fnctxcnt = 0, fnlockcnt = 0; #ifdef FIPS_MODULE - int fnfipscnt = 0; + int fnzeroizecnt = 0; #endif if ((rand = evp_rand_new()) == NULL) { @@ -149,19 +150,22 @@ static void *evp_rand_from_dispatch(int name_id, rand->set_callbacks = OSSL_get_OP_rand_set_callbacks(fns); break; case OSSL_FUNC_RAND_ENABLE_LOCKING: - if (rand->enable_prov_locking != NULL) + if (rand->enable_locking != NULL) break; - rand->enable_prov_locking = OSSL_get_OP_rand_enable_locking(fns); + rand->enable_locking = OSSL_get_OP_rand_enable_locking(fns); + fnlockcnt++; break; case OSSL_FUNC_RAND_LOCK: - if (rand->prov_lock != NULL) + if (rand->lock != NULL) break; - rand->prov_lock = OSSL_get_OP_rand_lock(fns); + rand->lock = OSSL_get_OP_rand_lock(fns); + fnlockcnt++; break; case OSSL_FUNC_RAND_UNLOCK: - if (rand->prov_unlock != NULL) + if (rand->unlock != NULL) break; - rand->prov_unlock = OSSL_get_OP_rand_unlock(fns); + rand->unlock = OSSL_get_OP_rand_unlock(fns); + fnlockcnt++; break; case OSSL_FUNC_RAND_GETTABLE_PARAMS: if (rand->gettable_params != NULL) @@ -201,36 +205,44 @@ static void *evp_rand_from_dispatch(int name_id, break; rand->verify_zeroization = OSSL_get_OP_rand_verify_zeroization(fns); #ifdef FIPS_MODULE - fnfipscnt++; + fnzeroizecnt++; #endif break; } } + /* + * In order to be a consistent set of functions we must have at least + * a complete set of "rand" functions and a complete set of context + * management functions. In FIPS mode, we also require the zeroization + * verification function. + * + * In addition, if locking can be enabled, we need a complete set of + * locking functions. + */ if (fnrandcnt != 3 || fnctxcnt != 2 + || (fnlockcnt != 0 && fnlockcnt != 3) #ifdef FIPS_MODULE - || fnfipscnt != 1 + || fnzeroizecnt != 1 #endif ) { - /* - * In order to be a consistent set of functions we must have at least - * a complete set of "rand" functions and a complete set of context - * management functions. In FIPS mode, we also require the zeroization - * verification function. - */ evp_rand_free(rand); ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); return NULL; } + + if (prov != NULL && !ossl_provider_up_ref(prov)) { + evp_rand_free(rand); + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return NULL; + } rand->prov = prov; - if (prov != NULL) - ossl_provider_up_ref(prov); return rand; } EVP_RAND *EVP_RAND_fetch(OPENSSL_CTX *libctx, const char *algorithm, - const char *properties) + const char *properties) { return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties, evp_rand_from_dispatch, evp_rand_up_ref, @@ -274,25 +286,33 @@ int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[]) return 1; } -EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, int secure, EVP_RAND_CTX *parent) +EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) { EVP_RAND_CTX *ctx; void *parent_ctx = NULL; const OSSL_DISPATCH *parent_dispatch = NULL; - if (rand == NULL) + if (rand == NULL) { + EVPerr(0, EVP_R_INVALID_NULL_ALGORITHM); return NULL; + } - ctx = OPENSSL_zalloc(sizeof(EVP_RAND_CTX)); - if (ctx == NULL) + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) { + EVPerr(0, ERR_R_MALLOC_FAILURE); return NULL; + } if (parent != NULL) { - EVP_RAND_CTX_enable_locking(parent); + if (!EVP_RAND_enable_locking(parent)) { + EVPerr(0, EVP_R_UNABLE_TO_ENABLE_PARENT_LOCKING); + OPENSSL_free(ctx); + return NULL; + } parent_ctx = parent->data; parent_dispatch = parent->meth->dispatch; } - if ((ctx->data = rand->newctx(ossl_provider_ctx(rand->prov), secure, - parent_ctx, parent_dispatch)) == NULL + if ((ctx->data = rand->newctx(ossl_provider_ctx(rand->prov), parent_ctx, + parent_dispatch)) == NULL || !EVP_RAND_up_ref(rand)) { EVPerr(0, ERR_R_MALLOC_FAILURE); rand->freectx(ctx->data); @@ -308,7 +328,6 @@ void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx) if (ctx != NULL) { ctx->meth->freectx(ctx->data); ctx->data = NULL; - EVP_RAND_CTX_free(ctx->parent); EVP_RAND_free(ctx->meth); OPENSSL_free(ctx); } @@ -319,7 +338,7 @@ EVP_RAND *EVP_RAND_CTX_rand(EVP_RAND_CTX *ctx) return ctx->meth; } -int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]) +int EVP_RAND_get_ctx_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]) { int res = 1; @@ -332,7 +351,7 @@ int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]) return res; } -int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]) +int EVP_RAND_set_ctx_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]) { int res = 1; @@ -350,23 +369,19 @@ int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]) const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand) { - if (rand->gettable_params == NULL) - return NULL; - return rand->gettable_params(); + return rand->gettable_params == NULL ? NULL : rand->gettable_params(); } const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand) { - if (rand->gettable_ctx_params == NULL) - return NULL; - return rand->gettable_ctx_params(); + return rand->gettable_ctx_params == NULL ? NULL + : rand->gettable_ctx_params(); } const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand) { - if (rand->settable_ctx_params == NULL) - return NULL; - return rand->settable_ctx_params(); + return rand->settable_ctx_params == NULL ? NULL + :rand->settable_ctx_params(); } void EVP_RAND_do_all_provided(OPENSSL_CTX *libctx, @@ -386,9 +401,9 @@ void EVP_RAND_names_do_all(const EVP_RAND *rand, evp_names_do_all(rand->prov, rand->name_id, fn, data); } -int EVP_RAND_CTX_instantiate(EVP_RAND_CTX *ctx, unsigned int strength, - int prediction_resistance, - const unsigned char *pstr, size_t pstr_len) +int EVP_RAND_instantiate(EVP_RAND_CTX *ctx, unsigned int strength, + int prediction_resistance, + const unsigned char *pstr, size_t pstr_len) { int res; @@ -400,7 +415,7 @@ int EVP_RAND_CTX_instantiate(EVP_RAND_CTX *ctx, unsigned int strength, return res; } -int EVP_RAND_CTX_uninstantiate(EVP_RAND_CTX *ctx) +int EVP_RAND_uninstantiate(EVP_RAND_CTX *ctx) { int res; @@ -411,9 +426,9 @@ int EVP_RAND_CTX_uninstantiate(EVP_RAND_CTX *ctx) return res; } -int EVP_RAND_CTX_generate(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen, - unsigned int strength, int prediction_resistance, - const unsigned char *addin, size_t addin_len) +int EVP_RAND_generate(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen, + unsigned int strength, int prediction_resistance, + const unsigned char *addin, size_t addin_len) { size_t chunk; OSSL_PARAM params[2]; @@ -423,17 +438,26 @@ int EVP_RAND_CTX_generate(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen, return 0; if (ctx->max_request == 0) { params[0] = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MAX_REQUEST, - &ctx->max_request); + &chunk); params[1] = OSSL_PARAM_construct_end(); - if (!EVP_RAND_CTX_get_params(ctx, params) - || ctx->max_request == 0) + if (!EVP_RAND_get_ctx_params(ctx, params) || chunk == 0) { + EVPerr(0, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE); goto err; + } + ctx->max_request = chunk; } for (; outlen > 0; outlen -= chunk, out += chunk) { chunk = outlen > ctx->max_request ? ctx->max_request : outlen; if (!ctx->meth->generate(ctx->data, out, chunk, strength, - prediction_resistance, addin, addin_len)) + prediction_resistance, addin, addin_len)) { + EVPerr(0, EVP_R_GENERATE_ERROR); goto err; + } + /* + * Prediction resistance is only relevant the first time around, + * subsequently, the DRBG has already been properly reseeded. + */ + prediction_resistance = 0; } res = 1; err: @@ -441,9 +465,9 @@ err: return res; } -int EVP_RAND_CTX_reseed(EVP_RAND_CTX *ctx, int prediction_resistance, - const unsigned char *ent, size_t ent_len, - const unsigned char *addin, size_t addin_len) +int EVP_RAND_reseed(EVP_RAND_CTX *ctx, int prediction_resistance, + const unsigned char *ent, size_t ent_len, + const unsigned char *addin, size_t addin_len) { int res = 1; @@ -456,39 +480,41 @@ int EVP_RAND_CTX_reseed(EVP_RAND_CTX *ctx, int prediction_resistance, return res; } -int EVP_RAND_CTX_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen) +int EVP_RAND_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen) { int res = 1; + unsigned int str = EVP_RAND_strength(ctx); if (!evp_rand_lock(ctx)) return 0; if (ctx->meth->nonce == NULL - || !ctx->meth->nonce(ctx->data, out, 0, outlen, outlen)) - res = ctx->meth->generate(ctx->data, out, outlen, 0, 0, NULL, 0); + || !ctx->meth->nonce(ctx->data, out, str, outlen, outlen)) + res = ctx->meth->generate(ctx->data, out, outlen, str, 0, NULL, 0); evp_rand_unlock(ctx); return res; } -unsigned int EVP_RAND_CTX_strength(EVP_RAND_CTX *ctx) +unsigned int EVP_RAND_strength(EVP_RAND_CTX *ctx) { OSSL_PARAM params[2]; + unsigned int t; int res; if (ctx->strength == 0) { - params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, - &ctx->strength); + params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, &t); params[1] = OSSL_PARAM_construct_end(); if (!evp_rand_lock(ctx)) return 0; - res = EVP_RAND_CTX_get_params(ctx, params); + res = EVP_RAND_get_ctx_params(ctx, params); evp_rand_unlock(ctx); if (!res) return 0; + ctx->strength = t; } return ctx->strength; } -int EVP_RAND_CTX_state(EVP_RAND_CTX *ctx) +int EVP_RAND_state(EVP_RAND_CTX *ctx) { OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; int status, res; @@ -497,14 +523,29 @@ int EVP_RAND_CTX_state(EVP_RAND_CTX *ctx) &status); if (!evp_rand_lock(ctx)) return 0; - res = EVP_RAND_CTX_get_params(ctx, params); + res = EVP_RAND_get_ctx_params(ctx, params); evp_rand_unlock(ctx); if (!res) status = EVP_RAND_STATE_ERROR; return status; } -int EVP_RAND_CTX_verify_zeroization(EVP_RAND_CTX *ctx) +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) +{ + 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_verify_zeroization(EVP_RAND_CTX *ctx) { int res = 0; diff --git a/crypto/rand/build.info b/crypto/rand/build.info index 7840428045..b7a4d598f1 100644 --- a/crypto/rand/build.info +++ b/crypto/rand/build.info @@ -1,16 +1,10 @@ LIBS=../../libcrypto -$COMMON=rand_pool.c rand_lib.c drbg_lib.c drbg_ctr.c drbg_hash.c drbg_hmac.c -$CRYPTO=rand_unix.c rand_win.c randfile.c rand_err.c +$COMMON=drbg_lib.c rand_lib.c +$CRYPTO=randfile.c rand_err.c IF[{- !$disabled{'egd'} -}] - $CYPTO=$CYPTO rand_egd.c -ENDIF -IF[{- $config{target} =~ /vxworks/i -}] - $CYPTO=$CYPTO rand_vxworks.c -ENDIF -IF[{- $config{target} =~ /vms/i -}] - $CYPTO=$CYPTO rand_vms.c + $CRYPTO=$CRYPTO rand_egd.c ENDIF diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c index 94a4e98d73..80759cbfaf 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -11,10 +11,10 @@ #include <openssl/crypto.h> #include <openssl/err.h> #include <openssl/rand.h> +#include <openssl/core_names.h> #include "rand_local.h" #include "internal/thread_once.h" #include "crypto/rand.h" -#include "crypto/rand_pool.h" #include "crypto/cryptlib.h" /* @@ -37,6 +37,7 @@ typedef struct drbg_global_st { * * There are three shared DRBG instances: <master>, <public>, and <private>. */ + CRYPTO_RWLOCK *lock; /* * The <master> DRBG @@ -70,14 +71,6 @@ typedef struct drbg_global_st { CRYPTO_THREAD_LOCAL private_drbg; } DRBG_GLOBAL; -typedef struct drbg_nonce_global_st { - CRYPTO_RWLOCK *rand_nonce_lock; - int rand_nonce_count; -} DRBG_NONCE_GLOBAL; - -/* NIST SP 800-90A DRBG recommends the use of a personalization string. */ -static const char ossl_pers_string[] = DRBG_DEFAULT_PERS_STRING; - #define RAND_DRBG_TYPE_FLAGS ( \ RAND_DRBG_FLAG_MASTER | RAND_DRBG_FLAG_PUBLIC | RAND_DRBG_FLAG_PRIVATE ) @@ -110,45 +103,76 @@ static const unsigned int rand_drbg_used_flags = static RAND_DRBG *drbg_setup(OPENSSL_CTX *ctx, RAND_DRBG *parent, int drbg_type); -static RAND_DRBG *rand_drbg_new(OPENSSL_CTX *ctx, - int secure, - int type, - unsigned int flags, - RAND_DRBG *parent); - -static int rand_drbg_set(RAND_DRBG *drbg, int type, unsigned int flags); -static int rand_drbg_init_method(RAND_DRBG *drbg); - -static int is_ctr(int type) +static int get_drbg_params(int type, unsigned int flags, const char **name, + OSSL_PARAM params[3]) { + OSSL_PARAM *p = params; + switch (type) { - case NID_aes_128_ctr: - case NID_aes_192_ctr: - case NID_aes_256_ctr: + case 0: return 1; default: return 0; + +#define CTR(v) \ + *name = "CTR-DRBG"; \ + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, v, 0) + + case NID_aes_128_ctr: + CTR(SN_aes_128_ctr); + break; + case NID_aes_192_ctr: + CTR(SN_aes_192_ctr); + break; + case NID_aes_256_ctr: + CTR(SN_aes_256_ctr); + break; + +#define DGST(v) \ + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST, v, 0); \ + if ((flags & RAND_DRBG_FLAG_HMAC) == 0) { \ + *name = "HASH-DRBG"; \ + } else { \ + *name = "HMAC-DRBG"; \ + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_MAC, \ + SN_hmac, 0); \ } -} -static int is_digest(int type) -{ - switch (type) { case NID_sha1: + DGST(SN_sha1); + break; case NID_sha224: + DGST(SN_sha224); + break; case NID_sha256: + DGST(SN_sha256); + break; case NID_sha384: + DGST(SN_sha384); + break; case NID_sha512: + DGST(SN_sha512); + break; case NID_sha512_224: + DGST(SN_sha512_224); + break; case NID_sha512_256: + DGST(SN_sha512_256); + break; case NID_sha3_224: + DGST(SN_sha3_224); + break; case NID_sha3_256: + DGST(SN_sha3_256); + break; case NID_sha3_384: + DGST(SN_sha3_384); + break; case NID_sha3_512: - return 1; - default: - return 0; + DGST(SN_sha3_512); } + *p = OSSL_PARAM_construct_end(); + return 1; } /* @@ -170,23 +194,23 @@ static void *drbg_ossl_ctx_new(OPENSSL_CTX *libctx) OPENSSL_init_crypto(0, NULL); #endif + dgbl->lock = CRYPTO_THREAD_lock_new(); + if (dgbl->lock == NULL) + goto err0; + if (!CRYPTO_THREAD_init_local(&dgbl->private_drbg, NULL)) goto err1; if (!CRYPTO_THREAD_init_local(&dgbl->public_drbg, NULL)) goto err2; - dgbl->master_drbg = drbg_setup(libctx, NULL, RAND_DRBG_TYPE_MASTER); - if (dgbl->master_drbg == NULL) - goto err3; - return dgbl; - err3: - CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg); err2: CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg); err1: + CRYPTO_THREAD_lock_free(dgbl->lock); + err0: OPENSSL_free(dgbl); return NULL; } @@ -198,6 +222,7 @@ static void drbg_ossl_ctx_free(void *vdgbl) if (dgbl == NULL) return; + CRYPTO_THREAD_lock_free(dgbl->lock); RAND_DRBG_free(dgbl->master_drbg); CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg); CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg); @@ -210,104 +235,12 @@ static const OPENSSL_CTX_METHOD drbg_ossl_ctx_method = { drbg_ossl_ctx_free, }; -/* - * drbg_ossl_ctx_new() calls drgb_setup() which calls rand_drbg_get_nonce() - * which needs to get the rand_nonce_lock out of the OPENSSL_CTX...but since - * drbg_ossl_ctx_new() hasn't finished running yet we need the rand_nonce_lock - * to be in a different global data object. Otherwise we will go into an - * infinite recursion loop. - */ -static void *drbg_nonce_ossl_ctx_new(OPENSSL_CTX *libctx) -{ - DRBG_NONCE_GLOBAL *dngbl = OPENSSL_zalloc(sizeof(*dngbl)); - - if (dngbl == NULL) - return NULL; - - dngbl->rand_nonce_lock = CRYPTO_THREAD_lock_new(); - if (dngbl->rand_nonce_lock == NULL) { - OPENSSL_free(dngbl); - return NULL; - } - - return dngbl; -} - -static void drbg_nonce_ossl_ctx_free(void *vdngbl) -{ - DRBG_NONCE_GLOBAL *dngbl = vdngbl; - - if (dngbl == NULL) - return; - - CRYPTO_THREAD_lock_free(dngbl->rand_nonce_lock); - - OPENSSL_free(dngbl); -} - -static const OPENSSL_CTX_METHOD drbg_nonce_ossl_ctx_method = { - drbg_nonce_ossl_ctx_new, - drbg_nonce_ossl_ctx_free, -}; - static DRBG_GLOBAL *drbg_get_global(OPENSSL_CTX *libctx) { return openssl_ctx_get_data(libctx, OPENSSL_CTX_DRBG_INDEX, &drbg_ossl_ctx_method); } -/* Implements the get_nonce() callback (see RAND_DRBG_set_callbacks()) */ -size_t rand_drbg_get_nonce(RAND_DRBG *drbg, - unsigned char **pout, - int entropy, size_t min_len, size_t max_len) -{ - size_t ret = 0; - RAND_POOL *pool; - DRBG_NONCE_GLOBAL *dngbl - = openssl_ctx_get_data(drbg->libctx, OPENSSL_CTX_DRBG_NONCE_INDEX, - &drbg_nonce_ossl_ctx_method); - struct { - void *instance; - int count; - } data; - - if (dngbl == NULL) - return 0; - - memset(&data, 0, sizeof(data)); - pool = rand_pool_new(0, 0, min_len, max_len); - if (pool == NULL) - return 0; - - if (rand_pool_add_nonce_data(pool) == 0) - goto err; - - data.instance = drbg; - CRYPTO_atomic_add(&dngbl->rand_nonce_count, 1, &data.count, - dngbl->rand_nonce_lock); - - if (rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0) == 0) - goto err; - - ret = rand_pool_length(pool); - *pout = rand_pool_detach(pool); - - err: - rand_pool_free(pool); - - return ret; -} - -/* - * Implements the cleanup_nonce() callback (see RAND_DRBG_set_callbacks()) - * - */ -void rand_drbg_cleanup_nonce(RAND_DRBG *drbg, - unsigned char *out, size_t outlen) -{ - OPENSSL_clear_free(out, outlen); -} - /* * Set the |drbg|'s callback data pointer for the entropy and nonce callbacks * @@ -322,8 +255,8 @@ void rand_drbg_cleanup_nonce(RAND_DRBG *drbg, */ int RAND_DRBG_set_callback_data(RAND_DRBG *drbg, void *data) { - if (drbg->state != DRBG_UNINITIALISED - || drbg->parent != NULL) + if (EVP_RAND_state(drbg->rand) != EVP_RAND_STATE_UNINITIALISED + || drbg->parent != NULL) return 0; drbg->callback_data = data; @@ -345,68 +278,71 @@ void *RAND_DRBG_get_callback_data(RAND_DRBG *drbg) */ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags) { - return rand_drbg_set(drbg, type, flags) && rand_drbg_init_method(drbg); -} + OSSL_PARAM params[6], *p = params; + unsigned int reseed_interval; + time_t reseed_time_interval; + const char *name = NULL; + EVP_RAND *rand; + EVP_RAND_CTX *pctx; + int use_df; -static int rand_drbg_set(RAND_DRBG *drbg, int type, unsigned int flags) -{ if (type == 0 && flags == 0) { type = rand_drbg_type[RAND_DRBG_TYPE_MASTER]; flags = rand_drbg_flags[RAND_DRBG_TYPE_MASTER]; } - /* If set is called multiple times - clear the old one */ - if (drbg->type != 0 && (type != drbg->type || flags != drbg->flags)) { - if (drbg->meth != NULL) - drbg->meth->uninstantiate(drbg); - rand_pool_free(drbg->adin_pool); - drbg->adin_pool = NULL; + if (drbg->parent == NULL) { + reseed_interval = master_reseed_interval; |