X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=crypto%2Fevp%2Fevp_rand.c;h=ecfc876cda8617b23914c97ac360b1ad12b2d66e;hb=da1c088f599af3755aaeed1c447a39621ef12e1f;hp=07d1ad9db265241995e2af5ee30f6c0f63bf722f;hpb=9311d0c471ca2eaa259e8c1bbbeb7c46394c7ba2;p=thirdparty%2Fopenssl.git diff --git a/crypto/evp/evp_rand.c b/crypto/evp/evp_rand.c index 07d1ad9db2..ecfc876cda 100644 --- a/crypto/evp/evp_rand.c +++ b/crypto/evp/evp_rand.c @@ -1,5 +1,5 @@ /* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 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 @@ -7,29 +7,26 @@ * https://www.openssl.org/source/license.html */ -#include - #include #include -#include #include -#include #include #include #include #include -#include "crypto/asn1.h" -#include "crypto/evp.h" #include "internal/cryptlib.h" #include "internal/numbers.h" #include "internal/provider.h" +#include "internal/core.h" +#include "crypto/evp.h" #include "evp_local.h" struct evp_rand_st { OSSL_PROVIDER *prov; int name_id; + char *type_name; + const char *description; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *refcnt_lock; const OSSL_DISPATCH *dispatch; OSSL_FUNC_rand_newctx_fn *newctx; @@ -57,34 +54,37 @@ static int evp_rand_up_ref(void *vrand) int ref = 0; if (rand != NULL) - return CRYPTO_UP_REF(&rand->refcnt, &ref, rand->refcnt_lock); + return CRYPTO_UP_REF(&rand->refcnt, &ref); return 1; } -static void evp_rand_free(void *vrand){ +static void evp_rand_free(void *vrand) +{ EVP_RAND *rand = (EVP_RAND *)vrand; int ref = 0; - if (rand != NULL) { - CRYPTO_DOWN_REF(&rand->refcnt, &ref, rand->refcnt_lock); - if (ref <= 0) { - ossl_provider_free(rand->prov); - CRYPTO_THREAD_lock_free(rand->refcnt_lock); - OPENSSL_free(rand); - } - } + if (rand == NULL) + return; + CRYPTO_DOWN_REF(&rand->refcnt, &ref); + if (ref > 0) + return; + OPENSSL_free(rand->type_name); + ossl_provider_free(rand->prov); + CRYPTO_FREE_REF(&rand->refcnt); + OPENSSL_free(rand); } static void *evp_rand_new(void) { EVP_RAND *rand = OPENSSL_zalloc(sizeof(*rand)); - if (rand == NULL - || (rand->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { + if (rand == NULL) + return NULL; + + if (!CRYPTO_NEW_REF(&rand->refcnt, 1)) { OPENSSL_free(rand); return NULL; } - rand->refcnt = 1; return rand; } @@ -92,7 +92,7 @@ static void *evp_rand_new(void) int EVP_RAND_enable_locking(EVP_RAND_CTX *rand) { if (rand->meth->enable_locking != NULL) - return rand->meth->enable_locking(rand->data); + return rand->meth->enable_locking(rand->algctx); ERR_raise(ERR_LIB_EVP, EVP_R_LOCKING_NOT_SUPPORTED); return 0; } @@ -101,7 +101,7 @@ int EVP_RAND_enable_locking(EVP_RAND_CTX *rand) static int evp_rand_lock(EVP_RAND_CTX *rand) { if (rand->meth->lock != NULL) - return rand->meth->lock(rand->data); + return rand->meth->lock(rand->algctx); return 1; } @@ -109,24 +109,30 @@ static int evp_rand_lock(EVP_RAND_CTX *rand) static void evp_rand_unlock(EVP_RAND_CTX *rand) { if (rand->meth->unlock != NULL) - rand->meth->unlock(rand->data); + rand->meth->unlock(rand->algctx); } -static void *evp_rand_from_dispatch(int name_id, - const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov) +static void *evp_rand_from_algorithm(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) { + const OSSL_DISPATCH *fns = algodef->implementation; EVP_RAND *rand = NULL; - int fnrandcnt = 0, fnctxcnt = 0, fnlockcnt = 0; + int fnrandcnt = 0, fnctxcnt = 0, fnlockcnt = 0, fnenablelockcnt = 0; #ifdef FIPS_MODULE int fnzeroizecnt = 0; #endif if ((rand = evp_rand_new()) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return NULL; } rand->name_id = name_id; + if ((rand->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { + evp_rand_free(rand); + return NULL; + } + rand->description = algodef->algorithm_description; rand->dispatch = fns; for (; fns->function_id != 0; fns++) { switch (fns->function_id) { @@ -174,7 +180,7 @@ static void *evp_rand_from_dispatch(int name_id, if (rand->enable_locking != NULL) break; rand->enable_locking = OSSL_FUNC_rand_enable_locking(fns); - fnlockcnt++; + fnenablelockcnt++; break; case OSSL_FUNC_RAND_LOCK: if (rand->lock != NULL) @@ -243,7 +249,8 @@ static void *evp_rand_from_dispatch(int name_id, */ if (fnrandcnt != 3 || fnctxcnt != 3 - || (fnlockcnt != 0 && fnlockcnt != 3) + || (fnenablelockcnt != 0 && fnenablelockcnt != 1) + || (fnlockcnt != 0 && fnlockcnt != 2) #ifdef FIPS_MODULE || fnzeroizecnt != 1 #endif @@ -267,7 +274,7 @@ EVP_RAND *EVP_RAND_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, const char *properties) { return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties, - evp_rand_from_dispatch, evp_rand_up_ref, + evp_rand_from_algorithm, evp_rand_up_ref, evp_rand_free); } @@ -281,22 +288,27 @@ void EVP_RAND_free(EVP_RAND *rand) evp_rand_free(rand); } -int EVP_RAND_number(const EVP_RAND *rand) +int evp_rand_get_number(const EVP_RAND *rand) { return rand->name_id; } -const char *EVP_RAND_name(const EVP_RAND *rand) +const char *EVP_RAND_get0_name(const EVP_RAND *rand) { - return evp_first_name(rand->prov, rand->name_id); + return rand->type_name; +} + +const char *EVP_RAND_get0_description(const EVP_RAND *rand) +{ + return rand->description; } int EVP_RAND_is_a(const EVP_RAND *rand, const char *name) { - return evp_is_a(rand->prov, rand->name_id, NULL, name); + return rand != NULL && evp_is_a(rand->prov, rand->name_id, NULL, name); } -const OSSL_PROVIDER *EVP_RAND_provider(const EVP_RAND *rand) +const OSSL_PROVIDER *EVP_RAND_get0_provider(const EVP_RAND *rand) { return rand->prov; } @@ -308,11 +320,11 @@ int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[]) return 1; } -static int evp_rand_ctx_up_ref(EVP_RAND_CTX *ctx) +int EVP_RAND_CTX_up_ref(EVP_RAND_CTX *ctx) { int ref = 0; - return CRYPTO_UP_REF(&ctx->refcnt, &ref, ctx->refcnt_lock); + return CRYPTO_UP_REF(&ctx->refcnt, &ref); } EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) @@ -327,63 +339,58 @@ EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) } ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL || (ctx->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { + if (ctx == NULL) + return NULL; + if (!CRYPTO_NEW_REF(&ctx->refcnt, 1)) { OPENSSL_free(ctx); - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return NULL; } if (parent != NULL) { - if (!EVP_RAND_enable_locking(parent)) { - ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_PARENT_LOCKING); - CRYPTO_THREAD_lock_free(ctx->refcnt_lock); - OPENSSL_free(ctx); - return NULL; - } - if (!evp_rand_ctx_up_ref(parent)) { + if (!EVP_RAND_CTX_up_ref(parent)) { ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); - CRYPTO_THREAD_lock_free(ctx->refcnt_lock); + CRYPTO_FREE_REF(&ctx->refcnt); OPENSSL_free(ctx); return NULL; } - parent_ctx = parent->data; + parent_ctx = parent->algctx; parent_dispatch = parent->meth->dispatch; } - if ((ctx->data = rand->newctx(ossl_provider_ctx(rand->prov), parent_ctx, - parent_dispatch)) == NULL + if ((ctx->algctx = rand->newctx(ossl_provider_ctx(rand->prov), parent_ctx, + parent_dispatch)) == NULL || !EVP_RAND_up_ref(rand)) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); - rand->freectx(ctx->data); - CRYPTO_THREAD_lock_free(ctx->refcnt_lock); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); + rand->freectx(ctx->algctx); + CRYPTO_FREE_REF(&ctx->refcnt); OPENSSL_free(ctx); EVP_RAND_CTX_free(parent); return NULL; } ctx->meth = rand; ctx->parent = parent; - ctx->refcnt = 1; return ctx; } void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx) { - if (ctx != NULL) { - int ref = 0; + int ref = 0; + EVP_RAND_CTX *parent; - CRYPTO_DOWN_REF(&ctx->refcnt, &ref, ctx->refcnt_lock); - if (ref <= 0) { - EVP_RAND_CTX *parent = ctx->parent; + if (ctx == NULL) + return; - ctx->meth->freectx(ctx->data); - ctx->data = NULL; - EVP_RAND_free(ctx->meth); - CRYPTO_THREAD_lock_free(ctx->refcnt_lock); - OPENSSL_free(ctx); - EVP_RAND_CTX_free(parent); - } - } + CRYPTO_DOWN_REF(&ctx->refcnt, &ref); + if (ref > 0) + return; + parent = ctx->parent; + ctx->meth->freectx(ctx->algctx); + ctx->algctx = NULL; + EVP_RAND_free(ctx->meth); + CRYPTO_FREE_REF(&ctx->refcnt); + OPENSSL_free(ctx); + EVP_RAND_CTX_free(parent); } -EVP_RAND *EVP_RAND_CTX_rand(EVP_RAND_CTX *ctx) +EVP_RAND *EVP_RAND_CTX_get0_rand(EVP_RAND_CTX *ctx) { return ctx->meth; } @@ -391,10 +398,10 @@ EVP_RAND *EVP_RAND_CTX_rand(EVP_RAND_CTX *ctx) static int evp_rand_get_ctx_params_locked(EVP_RAND_CTX *ctx, OSSL_PARAM params[]) { - return ctx->meth->get_ctx_params(ctx->data, params); + return ctx->meth->get_ctx_params(ctx->algctx, params); } -int EVP_RAND_get_ctx_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]) +int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]) { int res; @@ -409,11 +416,11 @@ static int evp_rand_set_ctx_params_locked(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]) { if (ctx->meth->set_ctx_params != NULL) - return ctx->meth->set_ctx_params(ctx->data, params); + return ctx->meth->set_ctx_params(ctx->algctx, params); return 1; } -int EVP_RAND_set_ctx_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]) +int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]) { int res; @@ -428,23 +435,47 @@ const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand) { if (rand->gettable_params == NULL) return NULL; - return rand->gettable_params(ossl_provider_ctx(EVP_RAND_provider(rand))); + return rand->gettable_params(ossl_provider_ctx(EVP_RAND_get0_provider(rand))); } const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand) { + void *provctx; + if (rand->gettable_ctx_params == NULL) return NULL; - return rand->gettable_ctx_params( - ossl_provider_ctx(EVP_RAND_provider(rand))); + provctx = ossl_provider_ctx(EVP_RAND_get0_provider(rand)); + return rand->gettable_ctx_params(NULL, provctx); } const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand) { + void *provctx; + if (rand->settable_ctx_params == NULL) return NULL; - return rand->settable_ctx_params( - ossl_provider_ctx(EVP_RAND_provider(rand))); + provctx = ossl_provider_ctx(EVP_RAND_get0_provider(rand)); + return rand->settable_ctx_params(NULL, provctx); +} + +const OSSL_PARAM *EVP_RAND_CTX_gettable_params(EVP_RAND_CTX *ctx) +{ + void *provctx; + + if (ctx->meth->gettable_ctx_params == NULL) + return NULL; + provctx = ossl_provider_ctx(EVP_RAND_get0_provider(ctx->meth)); + return ctx->meth->gettable_ctx_params(ctx->algctx, provctx); +} + +const OSSL_PARAM *EVP_RAND_CTX_settable_params(EVP_RAND_CTX *ctx) +{ + void *provctx; + + if (ctx->meth->settable_ctx_params == NULL) + return NULL; + provctx = ossl_provider_ctx(EVP_RAND_get0_provider(ctx->meth)); + return ctx->meth->settable_ctx_params(ctx->algctx, provctx); } void EVP_RAND_do_all_provided(OSSL_LIB_CTX *libctx, @@ -453,42 +484,46 @@ void EVP_RAND_do_all_provided(OSSL_LIB_CTX *libctx, { evp_generic_do_all(libctx, OSSL_OP_RAND, (void (*)(void *, void *))fn, arg, - evp_rand_from_dispatch, evp_rand_free); + evp_rand_from_algorithm, evp_rand_up_ref, + evp_rand_free); } -void EVP_RAND_names_do_all(const EVP_RAND *rand, - void (*fn)(const char *name, void *data), - void *data) +int EVP_RAND_names_do_all(const EVP_RAND *rand, + void (*fn)(const char *name, void *data), + void *data) { if (rand->prov != NULL) - evp_names_do_all(rand->prov, rand->name_id, fn, data); + return evp_names_do_all(rand->prov, rand->name_id, fn, data); + + return 1; } static int evp_rand_instantiate_locked (EVP_RAND_CTX *ctx, unsigned int strength, int prediction_resistance, - const unsigned char *pstr, size_t pstr_len) + const unsigned char *pstr, size_t pstr_len, const OSSL_PARAM params[]) { - return ctx->meth->instantiate(ctx->data, strength, prediction_resistance, - pstr, pstr_len); + return ctx->meth->instantiate(ctx->algctx, strength, prediction_resistance, + pstr, pstr_len, params); } int EVP_RAND_instantiate(EVP_RAND_CTX *ctx, unsigned int strength, int prediction_resistance, - const unsigned char *pstr, size_t pstr_len) + const unsigned char *pstr, size_t pstr_len, + const OSSL_PARAM params[]) { int res; if (!evp_rand_lock(ctx)) return 0; res = evp_rand_instantiate_locked(ctx, strength, prediction_resistance, - pstr, pstr_len); + pstr, pstr_len, params); evp_rand_unlock(ctx); return res; } static int evp_rand_uninstantiate_locked(EVP_RAND_CTX *ctx) { - return ctx->meth->uninstantiate(ctx->data); + return ctx->meth->uninstantiate(ctx->algctx); } int EVP_RAND_uninstantiate(EVP_RAND_CTX *ctx) @@ -511,7 +546,7 @@ static int evp_rand_generate_locked(EVP_RAND_CTX *ctx, unsigned char *out, size_t chunk, max_request = 0; OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - params[0] = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MAX_REQUEST, + params[0] = OSSL_PARAM_construct_size_t(OSSL_RAND_PARAM_MAX_REQUEST, &max_request); if (!evp_rand_get_ctx_params_locked(ctx, params) || max_request == 0) { @@ -520,7 +555,7 @@ static int evp_rand_generate_locked(EVP_RAND_CTX *ctx, unsigned char *out, } for (; outlen > 0; outlen -= chunk, out += chunk) { chunk = outlen > max_request ? max_request : outlen; - if (!ctx->meth->generate(ctx->data, out, chunk, strength, + if (!ctx->meth->generate(ctx->algctx, out, chunk, strength, prediction_resistance, addin, addin_len)) { ERR_raise(ERR_LIB_EVP, EVP_R_GENERATE_ERROR); return 0; @@ -553,7 +588,7 @@ static int evp_rand_reseed_locked(EVP_RAND_CTX *ctx, int prediction_resistance, const unsigned char *addin, size_t addin_len) { if (ctx->meth->reseed != NULL) - return ctx->meth->reseed(ctx->data, prediction_resistance, + return ctx->meth->reseed(ctx->algctx, prediction_resistance, ent, ent_len, addin, addin_len); return 1; } @@ -583,7 +618,7 @@ static unsigned int evp_rand_strength_locked(EVP_RAND_CTX *ctx) return strength; } -unsigned int EVP_RAND_strength(EVP_RAND_CTX *ctx) +unsigned int EVP_RAND_get_strength(EVP_RAND_CTX *ctx) { unsigned int res; @@ -601,7 +636,7 @@ static int evp_rand_nonce_locked(EVP_RAND_CTX *ctx, unsigned char *out, if (ctx->meth->nonce == NULL) return 0; - if (ctx->meth->nonce(ctx->data, out, str, outlen, outlen)) + if (ctx->meth->nonce(ctx->algctx, out, str, outlen, outlen)) return 1; return evp_rand_generate_locked(ctx, out, outlen, str, 0, NULL, 0); } @@ -617,13 +652,13 @@ int EVP_RAND_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen) return res; } -int EVP_RAND_state(EVP_RAND_CTX *ctx) +int EVP_RAND_get_state(EVP_RAND_CTX *ctx) { OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; int state; params[0] = OSSL_PARAM_construct_int(OSSL_RAND_PARAM_STATE, &state); - if (!EVP_RAND_get_ctx_params(ctx, params)) + if (!EVP_RAND_CTX_get_params(ctx, params)) state = EVP_RAND_STATE_ERROR; return state; } @@ -631,7 +666,7 @@ int EVP_RAND_state(EVP_RAND_CTX *ctx) static int evp_rand_verify_zeroization_locked(EVP_RAND_CTX *ctx) { if (ctx->meth->verify_zeroization != NULL) - return ctx->meth->verify_zeroization(ctx->data); + return ctx->meth->verify_zeroization(ctx->algctx); return 0; }