summaryrefslogtreecommitdiff
path: root/threadproc
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2018-06-27 22:17:42 +0000
committerYann Ylavic <ylavic@apache.org>2018-06-27 22:17:42 +0000
commit4851f1e00de6ad39ec09c9e8c7403d32a47ba032 (patch)
tree3d0907483faff8f2ffb7e713b2bd64186f3c0b13 /threadproc
parent8d59b8cdfa16eeab2bce884bb9b1f7cec5acceac (diff)
downloadapr-4851f1e00de6ad39ec09c9e8c7403d32a47ba032.tar.gz
apr_crypto: follow up to r1833359: improve CPRNGs fork()ing.
Rework apr_crypto_prng_after_fork() which now handles rekeying of all the CPRNGs created within apr_crypto, by maintaining them in a global APR_RING, with the notable exception of per-thread ones (never forked). For each maintained CPRNG, apr_crypto_prng_after_fork() will now first rekey both the parent and child processes (determined by the 'in_child' argument provided by the caller), and for the parent only rekey a second time so that the initial states finally differ for both processes. Once these new keys are committed to their respective CPRNGs, thanks to and in continuity with the forward secrecy construct of apr_crypto_prng, there will be no in memory key material or stream that one process can inherit or infer from the other. The user can also rekey a CPRNG explicitely by calling the new function apr_crypto_prng_rekey(), and this is done by apr_fork() implicitely before forking any child, thus for the parent process. This safe guard ensures both the clearing of the pooled random bytes (buffered keystream) and the renewal of key material (cheap and preventive against _atfork() handlers or alike). Rekeying is done by using each CPRNG's keystream directly, there isn't anymore the use of a PID (or SHA256 thereof) for children processes nor any extra reads from the system RNG. All the apr_crypto_prng API is now self contained and can work entirely with a single stream cipher as primitive (Chacha20 or AES256-CTR, in that order of availability) and the initial entropy of 32 bytes gathered from the system. IOW, there is only one call issued to the system RNG for the global CPRNG's initial key, and if more CPRNGs are created their own initial key is produced by the global CPRNG. The KAT arrays in the tests suite needed adjustment too because the initial seed (if provided, like the zeros-input for the KAT) is no more used directly as the first key. Instead the first 32 bytes of the keystream generated from the seed are, and the seed (like any just used key) is then cleared immediatly from internal memory. Finally some private APR_CRYPTO_PRNG_* macros (in .c file only) are renamed to CPRNG_* to shorten colomns and avoid multilines in several cases. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1834551 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'threadproc')
-rw-r--r--threadproc/unix/proc.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/threadproc/unix/proc.c b/threadproc/unix/proc.c
index f7d02d204..950405c09 100644
--- a/threadproc/unix/proc.c
+++ b/threadproc/unix/proc.c
@@ -223,22 +223,35 @@ APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *pool)
memset(proc, 0, sizeof(apr_proc_t));
+ /* Rekey PRNG(s) to clear buffer(s) and make sure that the
+ * state(s) change between fork()s in any case.
+ */
+#if APU_HAVE_CRYPTO_PRNG
+ apr_crypto_prng_rekey(NULL);
+#endif
+
if ((pid = fork()) < 0) {
return errno;
}
else if (pid == 0) {
proc->pid = getpid();
- apr_random_after_fork(proc);
+ /* Do the work needed for children PRNG(s). */
#if APU_HAVE_CRYPTO_PRNG
- apr_crypto_prng_after_fork(proc);
+ apr_crypto_prng_after_fork(NULL, 1);
#endif
+ apr_random_after_fork(proc);
return APR_INCHILD;
}
proc->pid = pid;
+ /* Do the work needed for parent PRNG(s). */
+#if APU_HAVE_CRYPTO_PRNG
+ apr_crypto_prng_after_fork(NULL, 0);
+#endif
+
return APR_INPARENT;
}