]> granicus.if.org Git - apache/commitdiff
Make use of the new apr_crypto_rng API if available.
authorYann Ylavic <ylavic@apache.org>
Mon, 11 Jun 2018 23:43:16 +0000 (23:43 +0000)
committerYann Ylavic <ylavic@apache.org>
Mon, 11 Jun 2018 23:43:16 +0000 (23:43 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1833368 13f79535-47bb-0310-9956-ffa450edef68

server/core.c

index d69ca37350dc08556f541f0d80921e7ceb176e53..0ea953a3fae37fb381174026cebd19787a77f5c6 100644 (file)
 #include "apr_fnmatch.h"
 #include "apr_hash.h"
 #include "apr_thread_proc.h"    /* for RLIMIT stuff */
+
+#include "apr_crypto.h"
+#if defined(APU_HAVE_CRYPTO_PRNG) && APU_HAVE_CRYPTO_PRNG
+#define USE_APR_CRYPTO_PRNG 1
+#else
+#define USE_APR_CRYPTO_PRNG 0
 #include "apr_random.h"
+#endif
 
 #define APR_WANT_IOVEC
 #define APR_WANT_STRFUNC
@@ -5436,13 +5443,21 @@ AP_DECLARE(int) ap_state_query(int query)
     }
 }
 
+#if !USE_APR_CRYPTO_PRNG
 static apr_random_t *rng = NULL;
 #if APR_HAS_THREADS
 static apr_thread_mutex_t *rng_mutex = NULL;
 #endif
+#endif /* !USE_APR_CRYPTO_PRNG */
 
 static void core_child_init(apr_pool_t *pchild, server_rec *s)
 {
+    /* The MPMs use plain fork() and not apr_proc_fork(), so we have to
+     * take care of the random generator manually in the child.
+     */
+#if USE_APR_CRYPTO_PRNG
+    apr_crypto_prng_after_fork();
+#else
     apr_proc_t proc;
 #if APR_HAS_THREADS
     int threaded_mpm;
@@ -5451,12 +5466,10 @@ static void core_child_init(apr_pool_t *pchild, server_rec *s)
     {
         apr_thread_mutex_create(&rng_mutex, APR_THREAD_MUTEX_DEFAULT, pchild);
     }
-#endif
-    /* The MPMs use plain fork() and not apr_proc_fork(), so we have to call
-     * apr_random_after_fork() manually in the child
-     */
     proc.pid = getpid();
     apr_random_after_fork(&proc);
+#endif
+#endif /* USE_APR_CRYPTO_PRNG */
 }
 
 static void core_optional_fn_retrieve(void)
@@ -5466,6 +5479,7 @@ static void core_optional_fn_retrieve(void)
 
 AP_CORE_DECLARE(void) ap_random_parent_after_fork(void)
 {
+#if !USE_APR_CRYPTO_PRNG
     /*
      * To ensure that the RNG state in the parent changes after the fork, we
      * pull some data from the RNG and discard it. This ensures that the RNG
@@ -5477,30 +5491,47 @@ AP_CORE_DECLARE(void) ap_random_parent_after_fork(void)
      */
     apr_uint16_t data;
     apr_random_insecure_bytes(rng, &data, sizeof(data));
+#endif /* !USE_APR_CRYPTO_PRNG */
 }
 
 AP_CORE_DECLARE(void) ap_init_rng(apr_pool_t *p)
 {
-    unsigned char seed[8];
     apr_status_t rv;
-    rng = apr_random_standard_new(p);
-    do {
-        rv = apr_generate_random_bytes(seed, sizeof(seed));
-        if (rv != APR_SUCCESS)
-            goto error;
-        apr_random_add_entropy(rng, seed, sizeof(seed));
-        rv = apr_random_insecure_ready(rng);
-    } while (rv == APR_ENOTENOUGHENTROPY);
-    if (rv == APR_SUCCESS)
-        return;
-error:
-    ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(00141)
-                 "Could not initialize random number generator");
-    exit(1);
+
+#if USE_APR_CRYPTO_PRNG
+    {
+        int flags = 0;
+#if APR_HAS_THREADS
+        flags = APR_CRYPTO_PRNG_PER_THREAD;
+#endif
+        rv = apr_crypto_prng_init(p, 0, NULL, flags);
+    }
+#else /* USE_APR_CRYPTO_PRNG */
+    {
+        unsigned char seed[8];
+        rng = apr_random_standard_new(p);
+        do {
+            rv = apr_generate_random_bytes(seed, sizeof(seed));
+            if (rv != APR_SUCCESS)
+                break;
+            apr_random_add_entropy(rng, seed, sizeof(seed));
+            rv = apr_random_insecure_ready(rng);
+        } while (rv == APR_ENOTENOUGHENTROPY);
+    }
+#endif /* USE_APR_CRYPTO_PRNG */
+
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(00141)
+                     "Could not initialize random number generator");
+        exit(1);
+    }
 }
 
 AP_DECLARE(void) ap_random_insecure_bytes(void *buf, apr_size_t size)
 {
+#if USE_APR_CRYPTO_PRNG
+    apr_crypto_random_bytes(buf, size);
+#else
 #if APR_HAS_THREADS
     if (rng_mutex)
         apr_thread_mutex_lock(rng_mutex);
@@ -5514,6 +5545,7 @@ AP_DECLARE(void) ap_random_insecure_bytes(void *buf, apr_size_t size)
     if (rng_mutex)
         apr_thread_mutex_unlock(rng_mutex);
 #endif
+#endif /* USE_APR_CRYPTO_PRNG */
 }
 
 /*