JITTER: implement error handling from jitter library

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24844)
This commit is contained in:
Dimitri John Ledkov 2024-07-12 21:55:14 +01:00 committed by Pauli
parent 1e7ff7be23
commit f8c510cd20
5 changed files with 38 additions and 35 deletions

View File

@ -1321,15 +1321,14 @@ if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
============================== WARNING ===============================
You have selected the --with-rand-seed=none option, which effectively
disables automatic reseeding of the OpenSSL random generator.
disables automatic reseeding of the OpenSSL SEED-SRC random generator.
All operations depending on the random generator such as creating keys
will not work unless the random generator is seeded manually by the
application.
Alternative to manually seeding is to compile with JITTER RNG enabled,
it will be used instead of rand-seed=none. Or specify alternative
seed= provider in openssl.cnf (for example from a 3rd party entropy
provider).
Instead of manually seeding, a different random generator can be set
at runtime in openssl.cnf or configured at build time with
-DOPENSSL_DEFAULT_SEED_SRC.
Please read the 'Note on random number generation' section in the
INSTALL.md instructions and the RAND_DRBG(7) manual page for more

View File

@ -189,11 +189,12 @@ DEFINE_RUN_ONCE_STATIC(init_info_strings)
add_seeds_string("os-specific");
#endif
#ifndef OPENSSL_NO_JITTER
{
{
char jent_version_string[32];
sprintf(jent_version_string, "JITTER (%d)", jent_version());
add_seeds_string(jent_version_string);
}
}
#endif
seed_sources = seeds;
}

View File

@ -227,7 +227,7 @@ In most cases OpenSSL will automatically choose a suitable seed source
for automatically seeding and reseeding its <primary> DRBG. The
default seed source can be configured when OpenSSL is compiled by
setting B<-DOPENSSL_DEFAULT_SEED_SRC='\"SEED-SRC\"'>. If not set then
"SEED-SRC" is used. One can specify third-party provider seed-source,
"SEED-SRC" is used. One can specify a third-party provider seed-source,
or B<-DOPENSSL_DEFAULT_SEED_SRC='\"JITTER\"'> if available.
In some cases however, it will be necessary to explicitly specify a

View File

@ -13,7 +13,6 @@
/* Hardware-based seeding functions. */
size_t ossl_prov_acquire_entropy_from_tsc(RAND_POOL *pool);
size_t ossl_prov_acquire_entropy_from_cpu(RAND_POOL *pool);
size_t ossl_prov_acquire_entropy_from_jitter(RAND_POOL *pool);
/*
* External seeding functions from the core dispatch table.

View File

@ -25,8 +25,6 @@
#ifndef OPENSSL_NO_JITTER
# include <jitterentropy.h>
# define JITTER_MAX_NUM_TRIES 3
static OSSL_FUNC_rand_newctx_fn jitter_new;
static OSSL_FUNC_rand_freectx_fn jitter_free;
static OSSL_FUNC_rand_instantiate_fn jitter_instantiate;
@ -41,20 +39,22 @@ static OSSL_FUNC_rand_lock_fn jitter_lock;
static OSSL_FUNC_rand_unlock_fn jitter_unlock;
static OSSL_FUNC_rand_get_seed_fn jitter_get_seed;
static OSSL_FUNC_rand_clear_seed_fn jitter_clear_seed;
static size_t get_jitter_random_value(unsigned char *buf, size_t len);
typedef struct {
void *provctx;
int state;
} PROV_JITTER;
static size_t get_jitter_random_value(PROV_JITTER *s, unsigned char *buf, size_t len);
/*
* Acquire entropy from jitterentropy library
*
* Returns the total entropy count, if it exceeds the requested
* entropy count. Otherwise, returns an entropy count of 0.
*/
size_t ossl_prov_acquire_entropy_from_jitter(RAND_POOL *pool)
static size_t ossl_prov_acquire_entropy_from_jitter(PROV_JITTER *s,
RAND_POOL *pool)
{
size_t bytes_needed;
unsigned char *buffer;
@ -64,7 +64,7 @@ size_t ossl_prov_acquire_entropy_from_jitter(RAND_POOL *pool)
buffer = ossl_rand_pool_add_begin(pool, bytes_needed);
if (buffer != NULL) {
if (get_jitter_random_value(buffer, bytes_needed) == bytes_needed) {
if (get_jitter_random_value(s, buffer, bytes_needed) == bytes_needed) {
ossl_rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
} else {
ossl_rand_pool_add_end(pool, 0, 0);
@ -76,34 +76,32 @@ size_t ossl_prov_acquire_entropy_from_jitter(RAND_POOL *pool)
}
/* Obtain random bytes from the jitter library */
static size_t get_jitter_random_value(unsigned char *buf, size_t len)
static size_t get_jitter_random_value(PROV_JITTER *s,
unsigned char *buf, size_t len)
{
struct rand_data *jitter_ec = NULL;
ssize_t result = 0;
size_t num_tries;
jitter_ec = jent_entropy_collector_alloc(0, JENT_FORCE_FIPS);
if (jitter_ec == NULL)
return 0;
for (num_tries = 0; num_tries < JITTER_MAX_NUM_TRIES; num_tries++) {
/*
* Do not use _safe API variant with built-in retries, until
* failure because it reseeds the entropy source which is not
* certifiable
*/
result = jent_read_entropy(jitter_ec, (char *) buf, len);
/* Success */
if (result == len) {
jent_entropy_collector_free(jitter_ec);
return len;
}
}
/*
* Do not use _safe API variant with built-in retries, until
* failure because it reseeds the entropy source which is not
* certifiable
*/
result = jent_read_entropy(jitter_ec, (char *) buf, len);
jent_entropy_collector_free(jitter_ec);
/* Catastrophic failure, maybe should abort here */
/* Success */
if (result == len)
return len;
/* Failure */
s->state = EVP_RAND_STATE_ERROR;
ERR_raise_data(ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ENTROPY,
"jent_read_entropy (%d)", result);
return 0;
}
@ -138,9 +136,14 @@ static int jitter_instantiate(void *vseed, unsigned int strength,
ossl_unused const OSSL_PARAM params[])
{
PROV_JITTER *s = (PROV_JITTER *)vseed;
int ret;
if (jent_entropy_init_ex(0, JENT_FORCE_FIPS))
if ((ret = jent_entropy_init_ex(0, JENT_FORCE_FIPS)) != 0) {
ERR_raise_data(ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ENTROPY,
"jent_entropy_init_ex (%d)", ret);
s->state = EVP_RAND_STATE_ERROR;
return 0;
}
s->state = EVP_RAND_STATE_READY;
return 1;
@ -178,7 +181,7 @@ static int jitter_generate(void *vseed, unsigned char *out, size_t outlen,
}
/* Get entropy from jitter entropy library. */
entropy_available = ossl_prov_acquire_entropy_from_jitter(pool);
entropy_available = ossl_prov_acquire_entropy_from_jitter(s, pool);
if (entropy_available > 0)
memcpy(out, ossl_rand_pool_buffer(pool), ossl_rand_pool_length(pool));
@ -252,6 +255,7 @@ static size_t jitter_get_seed(void *vseed, unsigned char **pout,
size_t entropy_available = 0;
size_t i;
RAND_POOL *pool;
PROV_JITTER *s = (PROV_JITTER *)vseed;
pool = ossl_rand_pool_new(entropy, 1, min_len, max_len);
if (pool == NULL) {
@ -260,7 +264,7 @@ static size_t jitter_get_seed(void *vseed, unsigned char **pout,
}
/* Get entropy from jitter entropy library. */
entropy_available = ossl_prov_acquire_entropy_from_jitter(pool);
entropy_available = ossl_prov_acquire_entropy_from_jitter(s, pool);
if (entropy_available > 0) {
ret = ossl_rand_pool_length(pool);