fips: use seed source requested

Fixes #21909

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21964)
This commit is contained in:
Pauli 2023-09-05 12:51:05 +10:00 committed by Matt Caswell
parent a9483b8aa0
commit 4cde7585ce
11 changed files with 350 additions and 55 deletions

View File

@ -257,7 +257,7 @@ void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *libctx)
if (tlocal == NULL)
return NULL;
if (!CRYPTO_THREAD_init_local(tlocal, NULL)) {
if (!CRYPTO_THREAD_init_local(tlocal, NULL)) {
goto err;
}

View File

@ -1930,10 +1930,12 @@ OSSL_FUNC_BIO_free_fn ossl_core_bio_free;
OSSL_FUNC_BIO_vprintf_fn ossl_core_bio_vprintf;
OSSL_FUNC_BIO_vsnprintf_fn BIO_vsnprintf;
static OSSL_FUNC_self_test_cb_fn core_self_test_get_callback;
OSSL_FUNC_get_entropy_fn ossl_rand_get_entropy;
OSSL_FUNC_cleanup_entropy_fn ossl_rand_cleanup_entropy;
OSSL_FUNC_get_nonce_fn ossl_rand_get_nonce;
OSSL_FUNC_cleanup_nonce_fn ossl_rand_cleanup_nonce;
static OSSL_FUNC_get_user_entropy_fn rand_get_user_entropy;
static OSSL_FUNC_get_entropy_fn rand_get_entropy;
static OSSL_FUNC_cleanup_entropy_fn rand_cleanup_entropy;
static OSSL_FUNC_get_user_nonce_fn rand_get_user_nonce;
static OSSL_FUNC_get_nonce_fn rand_get_nonce;
static OSSL_FUNC_cleanup_nonce_fn rand_cleanup_nonce;
#endif
OSSL_FUNC_CRYPTO_malloc_fn CRYPTO_malloc;
OSSL_FUNC_CRYPTO_zalloc_fn CRYPTO_zalloc;
@ -2094,6 +2096,54 @@ static void core_self_test_get_callback(OPENSSL_CORE_CTX *libctx,
OSSL_SELF_TEST_get_callback((OSSL_LIB_CTX *)libctx, cb, cbarg);
}
static size_t rand_get_entropy(const OSSL_CORE_HANDLE *handle,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len)
{
return ossl_rand_get_entropy((OSSL_LIB_CTX *)core_get_libctx(handle),
pout, entropy, min_len, max_len);
}
static size_t rand_get_user_entropy(const OSSL_CORE_HANDLE *handle,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len)
{
return ossl_rand_get_user_entropy((OSSL_LIB_CTX *)core_get_libctx(handle),
pout, entropy, min_len, max_len);
}
static void rand_cleanup_entropy(const OSSL_CORE_HANDLE *handle,
unsigned char *buf, size_t len)
{
ossl_rand_cleanup_entropy((OSSL_LIB_CTX *)core_get_libctx(handle),
buf, len);
}
static size_t rand_get_nonce(const OSSL_CORE_HANDLE *handle,
unsigned char **pout,
size_t min_len, size_t max_len,
const void *salt, size_t salt_len)
{
return ossl_rand_get_nonce((OSSL_LIB_CTX *)core_get_libctx(handle),
pout, min_len, max_len, salt, salt_len);
}
static size_t rand_get_user_nonce(const OSSL_CORE_HANDLE *handle,
unsigned char **pout,
size_t min_len, size_t max_len,
const void *salt, size_t salt_len)
{
return ossl_rand_get_user_nonce((OSSL_LIB_CTX *)core_get_libctx(handle),
pout, min_len, max_len, salt, salt_len);
}
static void rand_cleanup_nonce(const OSSL_CORE_HANDLE *handle,
unsigned char *buf, size_t len)
{
ossl_rand_cleanup_nonce((OSSL_LIB_CTX *)core_get_libctx(handle),
buf, len);
}
static const char *core_provider_get0_name(const OSSL_CORE_HANDLE *prov)
{
return OSSL_PROVIDER_get0_name((const OSSL_PROVIDER *)prov);
@ -2187,10 +2237,12 @@ static const OSSL_DISPATCH core_dispatch_[] = {
{ OSSL_FUNC_BIO_VPRINTF, (void (*)(void))ossl_core_bio_vprintf },
{ OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf },
{ OSSL_FUNC_SELF_TEST_CB, (void (*)(void))core_self_test_get_callback },
{ OSSL_FUNC_GET_ENTROPY, (void (*)(void))ossl_rand_get_entropy },
{ OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))ossl_rand_cleanup_entropy },
{ OSSL_FUNC_GET_NONCE, (void (*)(void))ossl_rand_get_nonce },
{ OSSL_FUNC_CLEANUP_NONCE, (void (*)(void))ossl_rand_cleanup_nonce },
{ OSSL_FUNC_GET_ENTROPY, (void (*)(void))rand_get_entropy },
{ OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))rand_cleanup_entropy },
{ OSSL_FUNC_GET_NONCE, (void (*)(void))rand_get_nonce },
{ OSSL_FUNC_CLEANUP_NONCE, (void (*)(void))rand_cleanup_nonce },
{ OSSL_FUNC_GET_USER_ENTROPY, (void (*)(void))rand_get_user_entropy },
{ OSSL_FUNC_GET_USER_NONCE, (void (*)(void))rand_get_user_nonce },
#endif
{ OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc },
{ OSSL_FUNC_CRYPTO_ZALLOC, (void (*)(void))CRYPTO_zalloc },

View File

@ -7,12 +7,14 @@
* https://www.openssl.org/source/license.html
*/
#include "rand_local.h"
#include "crypto/rand.h"
#include "crypto/rand_pool.h"
#include "internal/core.h"
#include <openssl/core_dispatch.h>
#include <openssl/err.h>
size_t ossl_rand_get_entropy(ossl_unused const OSSL_CORE_HANDLE *handle,
size_t ossl_rand_get_entropy(ossl_unused OSSL_LIB_CTX *ctx,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len)
{
@ -38,14 +40,46 @@ size_t ossl_rand_get_entropy(ossl_unused const OSSL_CORE_HANDLE *handle,
return ret;
}
void ossl_rand_cleanup_entropy(ossl_unused const OSSL_CORE_HANDLE *handle,
size_t ossl_rand_get_user_entropy(OSSL_LIB_CTX *ctx,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len)
{
unsigned char *buf;
EVP_RAND_CTX *rng = ossl_rand_get0_seed_noncreating(ctx);
size_t ret;
if (rng == NULL)
return ossl_rand_get_entropy(ctx, pout, entropy, min_len, max_len);
/* Determine how many bytes to generate */
ret = entropy > 0 ? (size_t)(7 + entropy) / 8 : min_len;
if (ret < min_len)
ret = min_len;
else if (ret > max_len)
ret = max_len;
/* Allocate the return buffer */
if ((buf = OPENSSL_secure_malloc(ret)) == NULL)
return 0;
/* Fill the buffer */
if (!EVP_RAND_generate(rng, buf, ret, entropy, 0, NULL, 0)) {
OPENSSL_free(buf);
return 0;
}
*pout = buf;
return ret;
}
void ossl_rand_cleanup_entropy(ossl_unused OSSL_LIB_CTX *ctx,
unsigned char *buf, size_t len)
{
OPENSSL_secure_clear_free(buf, len);
}
size_t ossl_rand_get_nonce(ossl_unused const OSSL_CORE_HANDLE *handle,
unsigned char **pout, size_t min_len, size_t max_len,
size_t ossl_rand_get_nonce(ossl_unused OSSL_LIB_CTX *ctx,
unsigned char **pout,
size_t min_len, ossl_unused size_t max_len,
const void *salt, size_t salt_len)
{
size_t ret = 0;
@ -69,7 +103,29 @@ size_t ossl_rand_get_nonce(ossl_unused const OSSL_CORE_HANDLE *handle,
return ret;
}
void ossl_rand_cleanup_nonce(ossl_unused const OSSL_CORE_HANDLE *handle,
size_t ossl_rand_get_user_nonce(OSSL_LIB_CTX *ctx,
unsigned char **pout,
size_t min_len, size_t max_len,
const void *salt, size_t salt_len)
{
unsigned char *buf;
EVP_RAND_CTX *rng = ossl_rand_get0_seed_noncreating(ctx);
if (rng == NULL)
return ossl_rand_get_nonce(ctx, pout, min_len, max_len, salt, salt_len);
if ((buf = OPENSSL_malloc(min_len)) == NULL)
return 0;
if (!EVP_RAND_generate(rng, buf, min_len, 0, 0, salt, salt_len)) {
OPENSSL_free(buf);
return 0;
}
*pout = buf;
return min_len;
}
void ossl_rand_cleanup_nonce(ossl_unused OSSL_LIB_CTX *ctx,
unsigned char *buf, size_t len)
{
OPENSSL_clear_free(buf, len);

View File

@ -30,6 +30,7 @@
# include "crypto/rand_pool.h"
# include "prov/seeding.h"
# include "internal/e_os.h"
# include "internal/property.h"
# ifndef OPENSSL_NO_ENGINE
/* non-NULL if default_RAND_meth is ENGINE-provided */
@ -345,8 +346,6 @@ int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num,
}
#endif
if (num < 0)
return 0;
rand = RAND_get0_private(ctx);
if (rand != NULL)
return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0);
@ -356,6 +355,8 @@ int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num,
int RAND_priv_bytes(unsigned char *buf, int num)
{
if (num < 0)
return 0;
return RAND_priv_bytes_ex(NULL, buf, (size_t)num, 0);
}
@ -374,8 +375,6 @@ int RAND_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num,
}
#endif
if (num < 0)
return 0;
rand = RAND_get0_public(ctx);
if (rand != NULL)
return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0);
@ -385,6 +384,8 @@ int RAND_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num,
int RAND_bytes(unsigned char *buf, int num)
{
if (num < 0)
return 0;
return RAND_bytes_ex(NULL, buf, (size_t)num, 0);
}
@ -534,29 +535,104 @@ static EVP_RAND_CTX *rand_new_seed(OSSL_LIB_CTX *libctx)
{
EVP_RAND *rand;
RAND_GLOBAL *dgbl = rand_get_global(libctx);
EVP_RAND_CTX *ctx;
char *name;
EVP_RAND_CTX *ctx = NULL;
const char *propq = dgbl->seed_propq;
char *name, *props = NULL;
size_t props_len;
OSSL_PROPERTY_LIST *pl1, *pl2, *pl3 = NULL;
if (dgbl == NULL)
return NULL;
name = dgbl->seed_name != NULL ? dgbl->seed_name : "SEED-SRC";
rand = EVP_RAND_fetch(libctx, name, dgbl->seed_propq);
if (dgbl->seed_name != NULL) {
name = dgbl->seed_name;
} else {
/*
* Default to our internal seed source. This isn't part of the FIPS
* provider so we need to override any FIPS properties.
*/
if (propq == NULL || *propq == '\0') {
propq = "-fips";
} else {
pl1 = ossl_parse_query(libctx, propq, 1);
if (pl1 == NULL) {
ERR_raise(ERR_LIB_RAND, RAND_R_INVALID_PROPERTY_QUERY);
return NULL;
}
pl2 = ossl_parse_query(libctx, "-fips", 1);
if (pl2 == NULL) {
ossl_property_free(pl1);
ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
return NULL;
}
pl3 = ossl_property_merge(pl2, pl1);
ossl_property_free(pl1);
ossl_property_free(pl2);
if (pl3 == NULL) {
ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
return NULL;
}
props_len = ossl_property_list_to_string(libctx, pl3, NULL, 0);
if (props_len == 0) {
/* Shouldn't happen since we added a query element */
ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
goto err;
} else {
props = OPENSSL_malloc(props_len);
if (props == NULL) {
ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE);
goto err;
}
if (ossl_property_list_to_string(libctx, pl3,
props, props_len) == 0) {
ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
goto err;
}
ossl_property_free(pl3);
pl3 = NULL;
propq = props;
}
}
name = "SEED-SRC";
}
rand = EVP_RAND_fetch(libctx, name, propq);
if (rand == NULL) {
ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
return NULL;
goto err;
}
ctx = EVP_RAND_CTX_new(rand, NULL);
EVP_RAND_free(rand);
if (ctx == NULL) {
ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG);
return NULL;
goto err;
}
if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0, NULL)) {
ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG);
EVP_RAND_CTX_free(ctx);
return NULL;
goto err;
}
OPENSSL_free(props);
return ctx;
err:
EVP_RAND_CTX_free(ctx);
ossl_property_free(pl3);
OPENSSL_free(props);
return NULL;
}
EVP_RAND_CTX *ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX *ctx)
{
RAND_GLOBAL *dgbl = rand_get_global(ctx);
EVP_RAND_CTX *ret;
if (dgbl == NULL)
return NULL;
if (!CRYPTO_THREAD_read_lock(dgbl->lock))
return NULL;
ret = dgbl->seed;
CRYPTO_THREAD_unlock(dgbl->lock);
return ret;
}
#endif
@ -882,7 +958,7 @@ int RAND_set_seed_source_type(OSSL_LIB_CTX *ctx, const char *seed,
if (dgbl == NULL)
return 0;
if (dgbl->primary != NULL) {
if (dgbl->seed != NULL) {
ERR_raise(ERR_LIB_CRYPTO, RAND_R_ALREADY_INSTANTIATED);
return 0;
}

View File

@ -2,8 +2,8 @@
=head1 NAME
ossl_rand_get_entropy, ossl_rand_cleanup_entropy,
ossl_rand_get_nonce, ossl_rand_cleanup_nonce
ossl_rand_get_entropy, ossl_rand_get_user_entropy, ossl_rand_cleanup_entropy,
ossl_rand_get_nonce, ossl_rand_get_user_nonce, ossl_rand_cleanup_nonce
- get seed material from the operating system
=head1 SYNOPSIS
@ -13,11 +13,17 @@ ossl_rand_get_nonce, ossl_rand_cleanup_nonce
size_t ossl_rand_get_entropy(OSSL_CORE_HANDLE *handle,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len);
size_t ossl_rand_get_user_entropy(OSSL_CORE_HANDLE *handle,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len);
void ossl_rand_cleanup_entropy(OSSL_CORE_HANDLE *handle,
unsigned char *buf, size_t len);
size_t ossl_rand_get_nonce(OSSL_CORE_HANDLE *handle,
unsigned char **pout, size_t min_len,
size_t max_len, const void *salt, size_t salt_len);
size_t ossl_rand_get_user_nonce(OSSL_CORE_HANDLE *handle, unsigned char **pout,
size_t min_len, size_t max_len,
const void *salt, size_t salt_len);
void ossl_rand_cleanup_nonce(OSSL_CORE_HANDLE *handle,
unsigned char *buf, size_t len);
@ -29,9 +35,14 @@ stored in a buffer which contains at least I<min_len> and at most I<max_len>
bytes. The buffer address is stored in I<*pout> and the buffer length is
returned to the caller.
ossl_rand_get_user_entropy() is the same as ossl_rand_get_entropy()
except that it retrieves the seeding material from the library context's
DRBG seed source. By default this is the operating system but it can
be changed by calling L<RAND_set_seed_source_type(3)>.
ossl_rand_cleanup_entropy() cleanses and frees any storage allocated by
ossl_rand_get_entropy(). The seeding buffer is pointed to by I<buf> and is
of length I<len> bytes.
ossl_rand_get_entropy() or ossl_rand_get_user_entropy(). The entropy
buffer is pointed to by I<buf> and is of length I<len> bytes.
ossl_rand_get_nonce() retrieves a nonce using the passed I<salt> parameter
of length I<salt_len> and operating system specific information.
@ -41,18 +52,34 @@ The output is stored in a buffer which contains at least I<min_len> and at
most I<max_len> bytes. The buffer address is stored in I<*pout> and the
buffer length returned to the caller.
ossl_rand_get_user_nonce() is the same as ossl_rand_get_nonce() except
that it retrieves the seeding material from the library context's DRBG
seed source. By default this is the operating system but it can be
changed by calling L<RAND_set_seed_source_type(3)>.
ossl_rand_cleanup_nonce() cleanses and frees any storage allocated by
ossl_rand_get_nonce(). The nonce buffer is pointed to by I<buf> and is
of length I<len> bytes.
ossl_rand_get_nonce() or ossl_rand_get_user_nonce(). The nonce buffer
is pointed to by I<buf> and is of length I<len> bytes.
=head1 NOTES
FIPS providers 3.0.0, 3.0.8 and 3.0.9 incorrectly pass a provider
internal pointer to ossl_rand_get_entropy(), ossl_rand_cleanup_entropy(),
ossl_rand_get_nonce() and ossl_rand_cleanup_nonce(). This pointer cannot
be safely dereferenced.
=head1 RETURN VALUES
ossl_rand_get_entropy() and ossl_rand_get_nonce() return the number of bytes
in I<*pout> or 0 on error.
ossl_rand_get_entropy(), ossl_rand_get_user_entropy(),
ossl_rand_get_nonce() and ossl_rand_get_user_nonce() return the number
of bytes in I<*pout> or 0 on error.
=head1 HISTORY
The functions described here were all added in OpenSSL 3.0.
The functions ossl_rand_get_user_entropy() and ossl_rand_get_user_nonce()
were added in OpenSSL 3.0.12, 3.1.4 and 3.2.0.
The remaining functions described here were all added in OpenSSL 3.0.
=head1 COPYRIGHT

View File

@ -60,6 +60,13 @@ If there are insufficient data present to satisfy a call, an error is returned.
Sets the bytes returned when the test generator is sent a nonce request.
Each nonce request will return all of the bytes.
=item "generate" (B<OSSL_RAND_PARAM_GENERATE>) <integer>
If this parameter is zero, it will only emit the nonce and entropy data
supplied via the aforementioned parameters. Otherwise, low quality
non-cryptographic pseudorandom output is produced. This parameter defaults
to zero.
=back
=head1 NOTES

View File

@ -76,11 +76,17 @@ provider-base
size_t get_entropy(const OSSL_CORE_HANDLE *handle,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len);
size_t get_user_entropy(const OSSL_CORE_HANDLE *handle,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len);
void cleanup_entropy(const OSSL_CORE_HANDLE *handle,
unsigned char *buf, size_t len);
size_t get_nonce(const OSSL_CORE_HANDLE *handle,
unsigned char **pout, size_t min_len, size_t max_len,
const void *salt, size_t salt_len);
size_t get_user_nonce(const OSSL_CORE_HANDLE *handle,
unsigned char **pout, size_t min_len, size_t max_len,
const void *salt, size_t salt_len);
void cleanup_nonce(const OSSL_CORE_HANDLE *handle,
unsigned char *buf, size_t len);
@ -171,8 +177,10 @@ provider):
OPENSSL_cleanse OSSL_FUNC_OPENSSL_CLEANSE
OSSL_SELF_TEST_set_callback OSSL_FUNC_SELF_TEST_CB
ossl_rand_get_entropy OSSL_FUNC_GET_ENTROPY
ossl_rand_get_user_entropy OSSL_FUNC_GET_USER_ENTROPY
ossl_rand_cleanup_entropy OSSL_FUNC_CLEANUP_ENTROPY
ossl_rand_get_nonce OSSL_FUNC_GET_NONCE
ossl_rand_get_user_nonce OSSL_FUNC_GET_USER_NONCE
ossl_rand_cleanup_nonce OSSL_FUNC_CLEANUP_NONCE
provider_register_child_cb OSSL_FUNC_PROVIDER_REGISTER_CHILD_CB
provider_deregister_child_cb OSSL_FUNC_PROVIDER_DEREGISTER_CHILD_CB
@ -302,9 +310,14 @@ output will have at least I<min_len> and at most I<max_len> bytes.
The buffer address is stored in I<*pout> and the buffer length is
returned to the caller. On error, zero is returned.
get_user_entropy() is the same as get_entropy() except that it will
attempt to gather seed material via the seed source specified by a call to
L<RAND_set_seed_source_type(3)> or via L<config(5)/Random Configuration>.
cleanup_entropy() is used to clean up and free the buffer returned by
get_entropy(). The entropy pointer returned by get_entropy() is passed in
B<buf> and its length in B<len>.
get_entropy() or get_user_entropy(). The entropy pointer returned by
get_entropy() or get_user_entropy() is passed in B<buf> and its length
in B<len>.
get_nonce() retrieves a nonce using the passed I<salt> parameter
of length I<salt_len> and operating system specific information.
@ -314,9 +327,14 @@ The output is stored in a buffer which contains at least I<min_len> and at
most I<max_len> bytes. The buffer address is stored in I<*pout> and the
buffer length returned to the caller. On error, zero is returned.
cleanup_nonce() is used to clean up and free the buffer returned by
get_nonce(). The nonce pointer returned by get_nonce() is passed in
B<buf> and its length in B<len>.
get_user_nonce() is the same as get_nonce() except that it will attempt
to gather seed material via the seed source specified by a call to
L<RAND_set_seed_source_type(3)> or via L<config(5)/Random Configuration>.
cleanup_nonce() is used to clean up and free the buffer returned
by get_nonce() or get_user_nonce(). The nonce pointer returned by
get_nonce() or get_user_nonce() is passed in B<buf> and its length
in B<len>.
provider_register_child_cb() registers callbacks for being informed about the
loading and unloading of providers in the application's library context.

View File

@ -108,15 +108,21 @@ void ossl_random_add_conf_module(void);
/*
* Get and cleanup random seed material.
*/
size_t ossl_rand_get_entropy(ossl_unused const OSSL_CORE_HANDLE *handle,
size_t ossl_rand_get_entropy(OSSL_LIB_CTX *ctx,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len);
void ossl_rand_cleanup_entropy(ossl_unused const OSSL_CORE_HANDLE *handle,
size_t ossl_rand_get_user_entropy(OSSL_LIB_CTX *ctx,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len);
void ossl_rand_cleanup_entropy(OSSL_LIB_CTX *ctx,
unsigned char *buf, size_t len);
size_t ossl_rand_get_nonce(ossl_unused const OSSL_CORE_HANDLE *handle,
size_t ossl_rand_get_nonce(OSSL_LIB_CTX *ctx,
unsigned char **pout, size_t min_len, size_t max_len,
const void *salt, size_t salt_len);
void ossl_rand_cleanup_nonce(ossl_unused const OSSL_CORE_HANDLE *handle,
size_t ossl_rand_get_user_nonce(OSSL_LIB_CTX *ctx, unsigned char **pout,
size_t min_len, size_t max_len,
const void *salt, size_t salt_len);
void ossl_rand_cleanup_nonce(OSSL_LIB_CTX *ctx,
unsigned char *buf, size_t len);
/*
@ -127,6 +133,7 @@ int ossl_pool_add_nonce_data(RAND_POOL *pool);
# ifdef FIPS_MODULE
EVP_RAND_CTX *ossl_rand_get0_private_noncreating(OSSL_LIB_CTX *ctx);
# else
EVP_RAND_CTX *ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX *ctx);
# endif
#endif

View File

@ -176,6 +176,10 @@ OSSL_CORE_MAKE_FUNC(int, BIO_vsnprintf,
OSSL_CORE_MAKE_FUNC(int, BIO_ctrl, (OSSL_CORE_BIO *bio,
int cmd, long num, void *ptr))
/* New seeding functions prototypes with the 101-104 series */
#define OSSL_FUNC_GET_USER_ENTROPY 98
#define OSSL_FUNC_GET_USER_NONCE 99
#define OSSL_FUNC_SELF_TEST_CB 100
OSSL_CORE_MAKE_FUNC(void, self_test_cb, (OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **cb,
void **cbarg))
@ -188,12 +192,19 @@ OSSL_CORE_MAKE_FUNC(void, self_test_cb, (OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **
OSSL_CORE_MAKE_FUNC(size_t, get_entropy, (const OSSL_CORE_HANDLE *handle,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len))
OSSL_CORE_MAKE_FUNC(size_t, get_user_entropy, (const OSSL_CORE_HANDLE *handle,
unsigned char **pout, int entropy,
size_t min_len, size_t max_len))
OSSL_CORE_MAKE_FUNC(void, cleanup_entropy, (const OSSL_CORE_HANDLE *handle,
unsigned char *buf, size_t len))
OSSL_CORE_MAKE_FUNC(size_t, get_nonce, (const OSSL_CORE_HANDLE *handle,
unsigned char **pout, size_t min_len,
size_t max_len, const void *salt,
size_t salt_len))
OSSL_CORE_MAKE_FUNC(size_t, get_user_nonce, (const OSSL_CORE_HANDLE *handle,
unsigned char **pout, size_t min_len,
size_t max_len, const void *salt,
size_t salt_len))
OSSL_CORE_MAKE_FUNC(void, cleanup_nonce, (const OSSL_CORE_HANDLE *handle,
unsigned char *buf, size_t len))

View File

@ -19,6 +19,7 @@
#include "prov/providercommon.h"
#include "prov/implementations.h"
#include "prov/provider_util.h"
#include "prov/names.h"
/*
* Forward declarations to ensure that interface functions are correctly
@ -90,6 +91,11 @@ static const OSSL_ALGORITHM base_store[] = {
#undef STORE
};
static const OSSL_ALGORITHM base_rands[] = {
{ PROV_NAMES_SEED_SRC, "provider=base", ossl_seed_src_functions },
{ NULL, NULL, NULL }
};
static const OSSL_ALGORITHM *base_query(void *provctx, int operation_id,
int *no_cache)
{
@ -101,6 +107,8 @@ static const OSSL_ALGORITHM *base_query(void *provctx, int operation_id,
return base_decoder;
case OSSL_OP_STORE:
return base_store;
case OSSL_OP_RAND:
return base_rands;
}
return NULL;
}

View File

@ -9,12 +9,33 @@
#include <openssl/core_dispatch.h>
#include "prov/seeding.h"
#include "prov/providercommon.h"
static OSSL_FUNC_get_entropy_fn *c_get_entropy = NULL;
static OSSL_FUNC_get_user_entropy_fn *c_get_user_entropy = NULL;
static OSSL_FUNC_cleanup_entropy_fn *c_cleanup_entropy = NULL;
static OSSL_FUNC_get_nonce_fn *c_get_nonce = NULL;
static OSSL_FUNC_get_user_nonce_fn *c_get_user_nonce = NULL;
static OSSL_FUNC_cleanup_nonce_fn *c_cleanup_nonce = NULL;
#ifdef FIPS_MODULE
/*
* The FIPS provider uses an internal library context which is what the
* passed provider context references. Since the seed source is external
* to the FIPS provider, this is the wrong one. We need to convert this
* to the correct core handle before up-calling libcrypto.
*/
# define CORE_HANDLE(provctx) \
FIPS_get_core_handle(ossl_prov_ctx_get0_libctx(provctx))
#else
/*
* The non-FIPS path *should* be unused because the full DRBG chain including
* seed source is instantiated. However, that might not apply for third
* party providers, so this is retained for compatibility.
*/
# define CORE_HANDLE(provctx) ossl_prov_ctx_get0_handle(provctx)
#endif
int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns)
{
for (; fns->function_id != 0; fns++) {
@ -29,12 +50,18 @@ int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns)
case OSSL_FUNC_GET_ENTROPY:
set_func(c_get_entropy, OSSL_FUNC_get_entropy(fns));
break;
case OSSL_FUNC_GET_USER_ENTROPY:
set_func(c_get_user_entropy, OSSL_FUNC_get_user_entropy(fns));
break;
case OSSL_FUNC_CLEANUP_ENTROPY:
set_func(c_cleanup_entropy, OSSL_FUNC_cleanup_entropy(fns));
break;
case OSSL_FUNC_GET_NONCE:
set_func(c_get_nonce, OSSL_FUNC_get_nonce(fns));
break;
case OSSL_FUNC_GET_USER_NONCE:
set_func(c_get_user_nonce, OSSL_FUNC_get_user_nonce(fns));
break;
case OSSL_FUNC_CLEANUP_NONCE:
set_func(c_cleanup_nonce, OSSL_FUNC_cleanup_nonce(fns));
break;
@ -47,31 +74,37 @@ int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns)
size_t ossl_prov_get_entropy(PROV_CTX *prov_ctx, unsigned char **pout,
int entropy, size_t min_len, size_t max_len)
{
if (c_get_entropy == NULL)
return 0;
return c_get_entropy(ossl_prov_ctx_get0_handle(prov_ctx),
pout, entropy, min_len, max_len);
const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx);
if (c_get_user_entropy != NULL)
return c_get_user_entropy(handle, pout, entropy, min_len, max_len);
if (c_get_entropy != NULL)
return c_get_entropy(handle, pout, entropy, min_len, max_len);
return 0;
}
void ossl_prov_cleanup_entropy(PROV_CTX *prov_ctx, unsigned char *buf,
size_t len)
{
if (c_cleanup_entropy != NULL)
c_cleanup_entropy(ossl_prov_ctx_get0_handle(prov_ctx), buf, len);
c_cleanup_entropy(CORE_HANDLE(prov_ctx), buf, len);
}
size_t ossl_prov_get_nonce(PROV_CTX *prov_ctx, unsigned char **pout,
size_t min_len, size_t max_len,
const void *salt, size_t salt_len)
{
if (c_get_nonce == NULL)
return 0;
return c_get_nonce(ossl_prov_ctx_get0_handle(prov_ctx), pout,
min_len, max_len, salt, salt_len);
const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx);
if (c_get_user_nonce != NULL)
return c_get_user_nonce(handle, pout, min_len, max_len, salt, salt_len);
if (c_get_nonce != NULL)
return c_get_nonce(handle, pout, min_len, max_len, salt, salt_len);
return 0;
}
void ossl_prov_cleanup_nonce(PROV_CTX *prov_ctx, unsigned char *buf, size_t len)
{
if (c_cleanup_nonce != NULL)
c_cleanup_nonce(ossl_prov_ctx_get0_handle(prov_ctx), buf, len);
c_cleanup_nonce(CORE_HANDLE(prov_ctx), buf, len);
}