diff options
author | Pauli <paul.dale@oracle.com> | 2020-07-22 12:55:31 +1000 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2020-08-07 14:16:47 +1000 |
commit | 7d615e2178fbffa53f05a67f68e5741374340308 (patch) | |
tree | 8e5cdbb8c39e24727e64af790831980b2a5d9e6a | |
parent | 4df0d37ff6cc399b93f9ef2524d087c2d67d41b5 (diff) |
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)
52 files changed, 716 insertions, 19796 deletions
diff --git a/CHANGES.md b/CHANGES.md index 75ecfc22f4..3ecdd5d99b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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. diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index cbfc495a0a..af19ab26cd 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -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 diff --git a/crypto/evp/e_aria.c b/crypto/evp/e_aria.c index 9720fcb7e5..ba654f6b94 100644 --- a/crypto/evp/e_aria.c +++ b/crypto/evp/e_aria.c @@ -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" diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 6ade73e978..2f00f9a13b 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -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> diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index 99c53484a6..1e1d689070 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.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 */ diff --git a/crypto/evp/evp_rand.c b/crypto/evp/evp_rand.c index 9056f6d20b..0e5e8c11f9 100644 --- a/crypto/evp/evp_rand.c +++ b/crypto/evp/evp_rand.c @@ -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) diff --git a/crypto/rand/build.info b/crypto/rand/build.info index 7776ca8820..f58a026f3b 100644 --- a/crypto/rand/build.info +++ b/crypto/rand/build.info @@ -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'} -}] diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c deleted file mode 100644 index d2566920cd..0000000000 --- a/crypto/rand/drbg_lib.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* - * 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 - */ - -/* - * RAND_DRBG_set is deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include <string.h> -#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/cryptlib.h" - -/* - * Support framework for NIST SP 800-90A DRBG - * - * See manual page RAND_DRBG(7) for a general overview. - * - * The OpenSSL model is to have new and free functions, and that new - * does all initialization. That is not the NIST model, which has - * instantiation and un-instantiate, and re-use within a new/free - * lifecycle. (No doubt this comes from the desire to support hardware - * DRBG, where allocation of resources on something like an HSM is - * a much bigger deal than just re-setting an allocated resource.) - */ - - -typedef struct drbg_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. - */ - RAND_DRBG *primary_drbg; - /* - * 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_drbg; - /* - * 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_drbg; -} DRBG_GLOBAL; - -#define RAND_DRBG_TYPE_FLAGS ( \ - RAND_DRBG_FLAG_PRIMARY | RAND_DRBG_FLAG_PUBLIC | RAND_DRBG_FLAG_PRIVATE ) - -#define RAND_DRBG_TYPE_PRIMARY 0 -#define RAND_DRBG_TYPE_PUBLIC 1 -#define RAND_DRBG_TYPE_PRIVATE 2 - -/* Defaults */ -static int rand_drbg_type[3] = { - RAND_DRBG_TYPE, /* Primary */ - RAND_DRBG_TYPE, /* Public */ - RAND_DRBG_TYPE /* Private */ -}; -static unsigned int rand_drbg_flags[3] = { - RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIMARY, /* Primary */ - RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC, /* Public */ - RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIVATE /* Private */ -}; - -static unsigned int primary_reseed_interval = PRIMARY_RESEED_INTERVAL; -static unsigned int secondary_reseed_interval = SECONDARY_RESEED_INTERVAL; - -static time_t primary_reseed_time_interval = PRIMARY_RESEED_TIME_INTERVAL; -static time_t secondary_reseed_time_interval = SECONDARY_RESEED_TIME_INTERVAL; - -/* A logical OR of all used DRBG flag bits (currently there is only one) */ -static const unsigned int rand_drbg_used_flags = - RAND_DRBG_FLAG_CTR_NO_DF | RAND_DRBG_FLAG_HMAC | RAND_DRBG_TYPE_FLAGS; - - -static RAND_DRBG *drbg_setup(OPENSSL_CTX *ctx, RAND_DRBG *parent, - int drbg_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 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); \ - } - - 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: - DGST(SN_sha3_512); - } - *p = OSSL_PARAM_construct_end(); - return 1; -} - -/* - * Initialize the OPENSSL_CTX global DRBGs on first use. - * Returns the allocated global data on success or NULL on failure. - */ -static void *drbg_ossl_ctx_new(OPENSSL_CTX *libctx) -{ - DRBG_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 err0; - - if (!CRYPTO_THREAD_init_local(&dgbl->private_drbg, NULL)) - goto err1; - - if (!CRYPTO_THREAD_init_local(&dgbl->public_drbg, NULL)) - goto err2; - - return dgbl; - - err2: - CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg); - err1: - CRYPTO_THREAD_lock_free(dgbl->lock); - err0: - OPENSSL_free(dgbl); - return NULL; -} - -static void drbg_ossl_ctx_free(void *vdgbl) -{ - DRBG_GLOBAL *dgbl = vdgbl; - - if (dgbl == NULL) - return; - - CRYPTO_THREAD_lock_free(dgbl->lock); - RAND_DRBG_free(dgbl->primary_drbg); - CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg); - CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg); - - OPENSSL_free(dgbl); -} - -static const OPENSSL_CTX_METHOD drbg_ossl_ctx_method = { - drbg_ossl_ctx_new, - drbg_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); -} - -/* - * Set the |drbg|'s callback data pointer for the entropy and nonce callbacks - * - * 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 need by the callbacks and free it after use. - * - * Setting the callback data is allowed only if the drbg has not been - * initialized yet. Otherwise, the operation will fail. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set_callback_data(RAND_DRBG *drbg, void *data) -{ - if (EVP_RAND_state(drbg->rand) != EVP_RAND_STATE_UNINITIALISED - || drbg->parent != NULL) - return 0; - - drbg->callback_data = data; - return 1; -} - -/* Retrieve the callback data pointer */ -void *RAND_DRBG_get_callback_data(RAND_DRBG *drbg) -{ - return drbg->callback_data; -} - -/* - * Set/initialize |drbg| to be of type |type|, with optional |flags|. - * - * If |type| and |flags| are zero, use the defaults - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags) -{ - 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; - - RAND_DRBG_get_entropy_fn get_entropy = drbg->get_entropy; - RAND_DRBG_cleanup_entropy_fn cleanup_entropy = drbg->cleanup_entropy; - RAND_DRBG_get_nonce_fn get_nonce = drbg->get_nonce; - RAND_DRBG_cleanup_nonce_fn cleanup_nonce = drbg->cleanup_nonce; - - if (type == 0 && flags == 0) { - type = rand_drbg_type[RAND_DRBG_TYPE_PRIMARY]; - flags = rand_drbg_flags[RAND_DRBG_TYPE_PRIMARY]; - } - - if (drbg->parent == NULL) { - reseed_interval = primary_reseed_interval; - reseed_time_interval = primary_reseed_time_interval; - } else { - reseed_interval = secondary_reseed_interval; - reseed_time_interval = secondary_reseed_time_interval; - } - *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); - use_df = (flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0; - *p++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_USE_DF, &use_df); - - if (!get_drbg_params(type, flags, &name, p)) { - RANDerr(0, RAND_R_UNSUPPORTED_DRBG_TYPE); - return 0; - } - - rand = EVP_RAND_fetch(drbg->libctx, name, NULL); - if (rand == NULL) { - RANDerr(0, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED); - return 0; - } - - EVP_RAND_CTX_free(drbg->rand); - drbg->rand = NULL; - - drbg->flags = flags; - drbg->type = type; - - pctx = drbg->parent != NULL ? drbg->parent->rand : NULL; - drbg->rand = EVP_RAND_CTX_new(rand, pctx); - EVP_RAND_free(rand); - if (drbg->rand == NULL) { - RANDerr(0, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED); - goto err; - } - - if (!EVP_RAND_set_ctx_params(drbg->rand, params)) { - RANDerr(0, RAND_R_ERROR_INITIALISING_DRBG); |