[openssl] master update
Dr. Paul Dale
pauli at openssl.org
Tue Sep 22 22:40:04 UTC 2020
The branch master has been updated
via 4640cd00c36f0535d297d1ed10665597c4e2c7f2 (commit)
from 8e3a64fdb6e1e2826a334b095147d3ebe1acac2a (commit)
- Log -----------------------------------------------------------------
commit 4640cd00c36f0535d297d1ed10665597c4e2c7f2
Author: Pauli <paul.dale at oracle.com>
Date: Wed Sep 16 11:10:01 2020 +1000
rand: reference count the EVP_RAND contexts.
This is required before the RAND/DRBG framework can be made user mutable.
Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12904)
-----------------------------------------------------------------------
Summary of changes:
crypto/evp/evp_local.h | 3 +++
crypto/evp/evp_rand.c | 38 +++++++++++++++++++++++++++++++++-----
doc/man3/EVP_RAND.pod | 1 +
3 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h
index 3268aa4109..285c69103b 100644
--- a/crypto/evp/evp_local.h
+++ b/crypto/evp/evp_local.h
@@ -69,6 +69,9 @@ 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 EVP_RAND or NULL if none */
+ CRYPTO_REF_COUNT refcnt; /* Context reference count */
+ CRYPTO_RWLOCK *refcnt_lock;
} /* EVP_RAND_CTX */ ;
struct evp_keymgmt_st {
diff --git a/crypto/evp/evp_rand.c b/crypto/evp/evp_rand.c
index 0e5e8c11f9..2e4edfff34 100644
--- a/crypto/evp/evp_rand.c
+++ b/crypto/evp/evp_rand.c
@@ -308,6 +308,13 @@ 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 ref = 0;
+
+ return CRYPTO_UP_REF(&ctx->refcnt, &ref, ctx->refcnt_lock);
+}
+
EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent)
{
EVP_RAND_CTX *ctx;
@@ -320,13 +327,21 @@ EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent)
}
ctx = OPENSSL_zalloc(sizeof(*ctx));
- if (ctx == NULL) {
+ if (ctx == NULL || (ctx->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) {
+ OPENSSL_free(ctx);
EVPerr(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (parent != NULL) {
if (!EVP_RAND_enable_locking(parent)) {
EVPerr(0, 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)) {
+ EVPerr(0, ERR_R_INTERNAL_ERROR);
+ CRYPTO_THREAD_lock_free(ctx->refcnt_lock);
OPENSSL_free(ctx);
return NULL;
}
@@ -338,20 +353,33 @@ EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent)
|| !EVP_RAND_up_ref(rand)) {
EVPerr(0, ERR_R_MALLOC_FAILURE);
rand->freectx(ctx->data);
+ CRYPTO_THREAD_lock_free(ctx->refcnt_lock);
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) {
- ctx->meth->freectx(ctx->data);
- ctx->data = NULL;
- EVP_RAND_free(ctx->meth);
- OPENSSL_free(ctx);
+ int ref = 0;
+
+ CRYPTO_DOWN_REF(&ctx->refcnt, &ref, ctx->refcnt_lock);
+ if (ref <= 0) {
+ EVP_RAND_CTX *parent = ctx->parent;
+
+ 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);
+ }
}
}
diff --git a/doc/man3/EVP_RAND.pod b/doc/man3/EVP_RAND.pod
index dfd2a7eb4c..b7b836f03e 100644
--- a/doc/man3/EVP_RAND.pod
+++ b/doc/man3/EVP_RAND.pod
@@ -85,6 +85,7 @@ cryptographically secure random bytes.
B<EVP_RAND> is a type that holds the implementation of a RAND.
B<EVP_RAND_CTX> is a context type that holds the algorithm inputs.
+B<EVP_RAND_CTX> structures are reference counted.
=head2 Algorithm implementation fetching
More information about the openssl-commits
mailing list