From: Yann Ylavic Date: Mon, 11 Jun 2018 23:43:16 +0000 (+0000) Subject: Make use of the new apr_crypto_rng API if available. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5c072450ac6e8bf730cd14e6cd5f879031abf5ec;p=apache Make use of the new apr_crypto_rng API if available. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1833368 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/core.c b/server/core.c index d69ca37350..0ea953a3fa 100644 --- a/server/core.c +++ b/server/core.c @@ -20,7 +20,14 @@ #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 */ } /*