File openssl-3-jitterentropy-3.4.0.patch of Package openssl-3

Index: openssl-3.1.4/Configurations/00-base-templates.conf
===================================================================
--- openssl-3.1.4.orig/Configurations/00-base-templates.conf
+++ openssl-3.1.4/Configurations/00-base-templates.conf
@@ -71,9 +71,12 @@ my %targets=(
         lflags          =>
             sub { $withargs{zlib_lib} ? "-L".$withargs{zlib_lib} : () },
         ex_libs         =>
-            sub { !defined($disabled{zlib})
-                  && defined($disabled{"zlib-dynamic"})
-                  ? "-lz" : () },
+            sub {
+                   my @libs = ();
+                   push(@libs, "-lz") if !defined($disabled{zlib}) && defined($disabled{"zlib-dynamic"});
+                   push(@libs, "-ljitterentropy") if !defined($disabled{jitterentropy});
+                   return join(" ", @libs);
+                },
         HASHBANGPERL    => "/usr/bin/env perl", # Only Unix actually cares
         RANLIB          => sub { which("$config{cross_compile_prefix}ranlib")
                                      ? "ranlib" : "" },
Index: openssl-3.1.4/crypto/rand/rand_jitter_entropy.c
===================================================================
--- /dev/null
+++ openssl-3.1.4/crypto/rand/rand_jitter_entropy.c
@@ -0,0 +1,97 @@
+# include "jitterentropy.h"
+# include "prov/jitter_entropy.h"
+
+struct rand_data* ec = NULL;
+CRYPTO_RWLOCK *jent_lock = NULL;
+int stop = 0;
+
+struct rand_data* FIPS_entropy_init(void)
+{
+    if (ec != NULL) {
+        /* Entropy source has been initiated and collector allocated */
+        return ec;
+    }
+    if (stop != 0) {
+        /* FIPS_entropy_cleanup() already called, don't initialize it again */
+        return NULL;
+    }
+    if (jent_lock == NULL) {
+        /* Allocates a new lock to serialize access to jent library */
+        jent_lock = CRYPTO_THREAD_lock_new();
+        if (jent_lock == NULL) {
+            return NULL;
+        }
+    }
+    if (CRYPTO_THREAD_write_lock(jent_lock) == 0) {
+        return NULL;
+    }
+    /* If the initialization is successful, the call returns with 0 */
+    if (jent_entropy_init_ex(1, JENT_FORCE_FIPS) == 0) {
+        /* Allocate entropy collector */
+        ec = jent_entropy_collector_alloc(1, JENT_FORCE_FIPS);
+    } else {
+        /* abort if jitter rng fails initialization */
+        abort();
+    }
+    if (ec == NULL) {
+        /* abort if jitter rng fails initialization */
+        abort();
+    }
+    CRYPTO_THREAD_unlock(jent_lock);
+
+    return ec;
+}
+
+/*
+ * The following error codes can be returned by jent_read_entropy_safe():
+ *   -1  entropy_collector is NULL
+ *   -2  RCT failed
+ *   -3  APT failed
+ *   -4  The timer cannot be initialized
+ *   -5  LAG failure
+ *   -6  RCT permanent failure
+ *   -7  APT permanent failure
+ *   -8  LAG permanent failure
+ */
+ssize_t FIPS_jitter_entropy(unsigned char *buf, size_t buflen)
+{
+    ssize_t ent_bytes = -1;
+
+    /*
+     * Order is important. We need to call FIPS_entropy_init() before we
+     * acquire jent_lock, otherwise it can lead to deadlock. Once we have
+     * jent_lock, we need to ensure that FIPS_entropy_cleanup() was not called
+     * in the meantime. Then it's safe to read entropy.
+     */
+    if (buf != NULL
+        && buflen != 0
+        && FIPS_entropy_init()
+        && CRYPTO_THREAD_write_lock(jent_lock) != 0
+        && stop == 0) {
+        /* Get entropy */
+        ent_bytes = jent_read_entropy_safe(&ec, (char *)buf, buflen);
+        if (ent_bytes < 0) {
+            /* abort if jitter rng fails entropy gathering because health tests failed. */
+            abort();
+        }
+        CRYPTO_THREAD_unlock(jent_lock);
+    }
+
+    return ent_bytes;
+}
+
+void FIPS_entropy_cleanup(void)
+{
+    if (jent_lock != NULL && stop == 0) {
+        CRYPTO_THREAD_write_lock(jent_lock);
+    }
+    /* Disable re-initialization in FIPS_entropy_init() */
+    stop = 1;
+    /* Free entropy collector */
+    if (ec != NULL) {
+        jent_entropy_collector_free(ec);
+        ec = NULL;
+    }
+    CRYPTO_THREAD_lock_free(jent_lock);
+    jent_lock = NULL;
+}
Index: openssl-3.1.4/providers/implementations/rands/seeding/rand_unix.c
===================================================================
--- openssl-3.1.4.orig/providers/implementations/rands/seeding/rand_unix.c
+++ openssl-3.1.4/providers/implementations/rands/seeding/rand_unix.c
@@ -20,6 +20,7 @@
 #include "internal/dso.h"
 #include "internal/nelem.h"
 #include "prov/seeding.h"
+#include "prov/jitter_entropy.h"
 
 #ifdef __linux
 # include <sys/syscall.h>
@@ -631,6 +632,31 @@ size_t ossl_pool_acquire_entropy(RAND_PO
 
     (void)entropy_available;    /* avoid compiler warning */
 
+    /* Use jitter entropy in FIPS mode */
+    if (EVP_default_properties_is_fips_enabled(NULL))
+    {
+        size_t bytes_needed;
+        unsigned char *buffer;
+        ssize_t bytes;
+        /* Maximum allowed number of consecutive unsuccessful attempts */
+        int attempts = 3;
+
+        bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
+        while (bytes_needed != 0 && attempts-- > 0) {
+            buffer = ossl_rand_pool_add_begin(pool, bytes_needed);
+            bytes = FIPS_jitter_entropy(buffer, bytes_needed);
+            if (bytes > 0) {
+                ossl_rand_pool_add_end(pool, bytes, 8 * bytes);
+                bytes_needed -= bytes;
+                attempts = 3; /* reset counter after successful attempt */
+            } else if (bytes < 0) {
+                break;
+            }
+        }
+        entropy_available = ossl_rand_pool_entropy_available(pool);
+        return entropy_available;
+    }
+
 #   if defined(OPENSSL_RAND_SEED_GETRANDOM)
     {
         size_t bytes_needed;
Index: openssl-3.1.4/providers/implementations/include/prov/jitter_entropy.h
===================================================================
--- /dev/null
+++ openssl-3.1.4/providers/implementations/include/prov/jitter_entropy.h
@@ -0,0 +1,17 @@
+#ifndef OSSL_PROVIDERS_JITTER_ENTROPY_H
+# define OSSL_PROVIDERS_JITTER_ENTROPY_H
+
+# include <openssl/core.h>
+# include <openssl/types.h>
+# include <openssl/crypto.h>
+# include <openssl/fips.h>
+
+extern struct rand_data* ec;
+extern CRYPTO_RWLOCK *jent_lock;
+extern int stop;
+
+struct rand_data* FIPS_entropy_init(void);
+ssize_t FIPS_jitter_entropy(unsigned char *buf, size_t buflen);
+void FIPS_entropy_cleanup(void);
+
+#endif
Index: openssl-3.1.4/providers/fips/self_test.c
===================================================================
--- openssl-3.1.4.orig/providers/fips/self_test.c
+++ openssl-3.1.4/providers/fips/self_test.c
@@ -20,6 +20,7 @@
 #include "internal/tsan_assist.h"
 #include "prov/providercommon.h"
 #include "crypto/rand.h"
+#include "prov/jitter_entropy.h"
 
 /*
  * We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS
@@ -392,6 +393,11 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS
         return 0;
     }
 
+    if (!FIPS_entropy_init()) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_ENTROPY_INIT_FAILED);
+        goto end;
+    }
+
     if (st == NULL) {
         ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA);
         goto end;
Index: openssl-3.1.4/include/openssl/proverr.h
===================================================================
--- openssl-3.1.4.orig/include/openssl/proverr.h
+++ openssl-3.1.4/include/openssl/proverr.h
@@ -44,6 +44,7 @@
 # define PROV_R_FAILED_TO_GET_PARAMETER                   103
 # define PROV_R_FAILED_TO_SET_PARAMETER                   104
 # define PROV_R_FAILED_TO_SIGN                            175
+# define PROV_R_FIPS_ENTROPY_INIT_FAILED                  234
 # define PROV_R_FIPS_MODULE_CONDITIONAL_ERROR             227
 # define PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE          224
 # define PROV_R_FIPS_MODULE_IN_ERROR_STATE                225
Index: openssl-3.1.4/providers/common/provider_err.c
===================================================================
--- openssl-3.1.4.orig/providers/common/provider_err.c
+++ openssl-3.1.4/providers/common/provider_err.c
@@ -54,6 +54,8 @@ static const ERR_STRING_DATA PROV_str_re
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER),
     "failed to set parameter"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SIGN), "failed to sign"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_ENTROPY_INIT_FAILED),
+    "fips module jitter entropy init failed"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR),
     "fips module conditional error"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE),
Index: openssl-3.1.4/crypto/rand/build.info
===================================================================
--- openssl-3.1.4.orig/crypto/rand/build.info
+++ openssl-3.1.4/crypto/rand/build.info
@@ -1,6 +1,6 @@
 LIBS=../../libcrypto
 
-$COMMON=rand_lib.c
+$COMMON=rand_lib.c rand_jitter_entropy.c
 $CRYPTO=randfile.c rand_err.c rand_deprecated.c prov_seed.c rand_pool.c
 
 IF[{- !$disabled{'egd'} -}]
Index: openssl-3.1.4/providers/fips/fipsprov.c
===================================================================
--- openssl-3.1.4.orig/providers/fips/fipsprov.c
+++ openssl-3.1.4/providers/fips/fipsprov.c
@@ -27,6 +27,7 @@
 #include "crypto/context.h"
 #include "internal/core.h"
 #include "indicator.h"
+#include "prov/jitter_entropy.h"
 
 static const char FIPS_DEFAULT_PROPERTIES[] = "provider=fips,fips=yes";
 static const char FIPS_UNAPPROVED_PROPERTIES[] = "provider=fips,fips=no";
@@ -603,6 +604,7 @@ const OSSL_SUSE_FIPSINDICATOR_ALGORITHM
 
 static void fips_teardown(void *provctx)
 {
+    FIPS_entropy_cleanup();
     OSSL_LIB_CTX_free(PROV_LIBCTX_OF(provctx));
     ossl_prov_ctx_free(provctx);
 }
Index: openssl-3.1.4/util/libcrypto.num
===================================================================
--- openssl-3.1.4.orig/util/libcrypto.num
+++ openssl-3.1.4/util/libcrypto.num
@@ -5441,3 +5441,5 @@ X509_get_default_cert_path_env
 ossl_safe_getenv                        ?	3_0_0	EXIST::FUNCTION:
 ossl_ctx_legacy_digest_signatures_allowed ?	3_0_1	EXIST::FUNCTION:
 ossl_ctx_legacy_digest_signatures_allowed_set ?	3_0_1	EXIST::FUNCTION:
+FIPS_entropy_init                       ?	3_1_4   EXIST::FUNCTION:
+FIPS_entropy_cleanup                    ?	3_1_4   EXIST::FUNCTION:
Index: openssl-3.1.4/Configure
===================================================================
--- openssl-3.1.4.orig/Configure
+++ openssl-3.1.4/Configure
@@ -454,6 +454,7 @@ my @disablables = (
     "fuzz-libfuzzer",
     "gost",
     "idea",
+    "jitterentropy",
     "ktls",
     "legacy",
     "loadereng",
@@ -550,6 +551,7 @@ our %disabled = ( # "what"         => "c
                   "external-tests"      => "default",
                   "fuzz-afl"            => "default",
                   "fuzz-libfuzzer"      => "default",
+                  "jitterentropy"       => "default",
                   "ktls"                => "default",
                   "md2"                 => "default",
                   "msan"                => "default",
@@ -763,7 +765,7 @@ my %cmdvars = ();               # Stores
 my %unsupported_options = ();
 my %deprecated_options = ();
 # If you change this, update apps/version.c
-my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom);
+my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom jitterentropy);
 my @seed_sources = ();
 while (@argvcopy)
         {
@@ -1231,6 +1233,9 @@ if (scalar(@seed_sources) == 0) {
 if (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) {
     delete $disabled{'egd'};
 }
+if (scalar(grep { $_ eq 'jitterentropy' } @seed_sources) > 0) {
+    delete $disabled{'jitterentropy'};
+}
 if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
     die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1;
     warn <<_____ if scalar(@seed_sources) == 1;
Index: openssl-3.1.4/crypto/info.c
===================================================================
--- openssl-3.1.4.orig/crypto/info.c
+++ openssl-3.1.4/crypto/info.c
@@ -15,6 +15,9 @@
 #include "internal/e_os.h"
 #include "buildinf.h"
 
+# include <stdio.h>
+# include <jitterentropy.h>
+
 #if defined(__arm__) || defined(__arm) || defined(__aarch64__)
 # include "arm_arch.h"
 # define CPU_INFO_STR_LEN 128
@@ -128,6 +131,14 @@ DEFINE_RUN_ONCE_STATIC(init_info_strings
             OPENSSL_strlcat(seeds, ")", sizeof(seeds));                 \
         } while (0)
 
+        /* In FIPS mode, only jitterentropy is used for seeding and
+         * reseeding the primary DRBG.
+         */
+        if (EVP_default_properties_is_fips_enabled(NULL)) {
+            char jent_version_string[32];
+            sprintf(jent_version_string, "jitterentropy (%d)", jent_version());
+            add_seeds_string(jent_version_string);
+        } else {
 #ifdef OPENSSL_RAND_SEED_NONE
         add_seeds_string("none");
 #endif
@@ -156,6 +167,7 @@ DEFINE_RUN_ONCE_STATIC(init_info_strings
 #ifdef OPENSSL_RAND_SEED_OS
         add_seeds_string("os-specific");
 #endif
+        }
         seed_sources = seeds;
     }
     return 1;
Index: openssl-3.1.4/INSTALL.md
===================================================================
--- openssl-3.1.4.orig/INSTALL.md
+++ openssl-3.1.4/INSTALL.md
@@ -463,6 +463,12 @@ if provided by the CPU.
 Use librandom (not implemented yet).
 This source is ignored by the FIPS provider.
 
+### jitterentropy
+
+Use [jitterentropy-library](https://github.com/smuellerDD/jitterentropy-library)
+dynamically linked. In FIPS mode, only the jitter RNG is used to seed and reseed
+the primary DRBG.
+
 ### none
 
 Disable automatic seeding.  This is the default on some operating systems where
openSUSE Build Service is sponsored by