]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
JITTER: implement error handling from jitter library
authorDimitri John Ledkov <dimitri.ledkov@surgut.co.uk>
Fri, 12 Jul 2024 20:55:14 +0000 (21:55 +0100)
committerPauli <ppzgs1@gmail.com>
Wed, 31 Jul 2024 04:44:51 +0000 (14:44 +1000)
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24844)

Configure
crypto/info.c
doc/man7/EVP_RAND.pod
providers/implementations/include/prov/seeding.h
providers/implementations/rands/seed_src_jitter.c

index f4cc4194c5b30842f053f2e2df77b348a05ce1c9..ef1dbca1a98020962b7d6bacbe2ccb9e2cc6a3a4 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -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
index c09c40f548dc7b572c8012903e45fef28c1575dc..1804b8541ea6d50c3de28edd2bb2cfdbec71b0bf 100644 (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;
     }
index 05e494ceee945f413af5871b7dd882eca9c49d19..d80497f98e6077e7c14456a8d99d0a571070aeb0 100644 (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 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
index 5067aa302609de491c2c4c089891366f42c63693..af6cb79fb28f4cb6ba34b74797a8d44e89fd84c9 100644 (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.
index 1d7d6e4bc66182b7f2a4a6db2636dcd62260450b..8029a3cb8d788f19f75fdb5b19ceab0f6a82b160 100644 (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);