/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Cryptographic Pseudo Random Number Generator (CPRNG), based on
 * "Fast-key-erasure random-number generators" from D.J. Bernstein ([1]),
 * and public domain implementation in libpqcrypto's randombytes() ([2]).
 *
 * The CPRNG key is changed as soon as it's used to initialize the stream
 * cipher, so it never resides in memory at the same time as the keystream
 * it produced (a.k.a. the random bytes, which for efficiency are pooled).
 *
 * Likewise, the keystream is always cleared from the internal state before
 * being returned to the user, thus there is no way to recover the produced
 * random bytes afterward (e.g. from a memory/core dump after a crash).
 *
 * IOW, this CPRNG ensures forward secrecy, one may want to run it in a process
 * and/or environment protected from live memory eavesdropping, thus keep the
 * pooled/future random bytes secret by design, and use it as a replacement
 * for some blocking/inefficient system RNG. The random bytes could then be
 * serviced through a named pipe/socket, RPC, or any specific API. This is
 * outside the scope of this/below code, though.
 *
 * [1] https://blog.cr.yp.to/20170723-random.html
 * [2] https://libpqcrypto.org/
 */

#include "apu.h"

#include "apr_crypto.h"
#include "apr_crypto_internal.h"

#include "apr_strings.h"

#if APU_HAVE_CRYPTO
#if APU_HAVE_CRYPTO_PRNG

#include "apr_ring.h"
#include "apr_pools.h"
#include "apr_thread_mutex.h"
#include "apr_thread_proc.h"

#include <stdlib.h> /* for malloc() */

#if APU_HAVE_OPENSSL
/** Recommended prng driver for this platform */
#define APU_CRYPTO_PRNG_RECOMMENDED_DRIVER "openssl"
#endif

/* Be consistent with the .h (the seed is xor-ed with key on reseed). */
#if CPRNG_KEY_SIZE != APR_CRYPTO_PRNG_SEED_SIZE
#error apr_crypto_prng handles stream ciphers with 256bit keys only
#endif

#define CPRNG_BUF_SIZE_MIN (CPRNG_KEY_SIZE * (8 - 1))
#define CPRNG_BUF_SIZE_DEF (CPRNG_KEY_SIZE * (24 - 1))

APR_TYPEDEF_STRUCT(apr_crypto_t,
    apr_pool_t *pool;
    apr_crypto_driver_t *provider;
)

struct apr_crypto_prng_t {
    APR_RING_ENTRY(apr_crypto_prng_t) link;
    apr_pool_t *pool;
    apr_crypto_t *crypto;
    cprng_stream_ctx_t *ctx;
#if APR_HAS_THREADS
    apr_thread_mutex_t *mutex;
#endif
    unsigned char *key, *buf;
    apr_size_t len, pos;
    int flags;
    apr_crypto_cipher_e cipher;
};

static apr_crypto_prng_t *cprng_global = NULL;
static APR_RING_HEAD(apr_cprng_ring, apr_crypto_prng_t) *cprng_ring;

#if APR_HAS_THREADS
static apr_thread_mutex_t *cprng_ring_mutex;

static apr_threadkey_t *cprng_thread_key = NULL;

#define cprng_lock(g) \
    if ((g)->mutex) \
        apr_thread_mutex_lock((g)->mutex)

#define cprng_unlock(g) \
    if ((g)->mutex) \
        apr_thread_mutex_unlock((g)->mutex)

#define cprng_ring_lock() \
    if (cprng_ring_mutex) \
        apr_thread_mutex_lock(cprng_ring_mutex)

#define cprng_ring_unlock() \
    if (cprng_ring_mutex) \
        apr_thread_mutex_unlock(cprng_ring_mutex)

static void cprng_thread_destroy(void *cprng)
{
    apr_threadkey_private_set(NULL, cprng_thread_key);
    if (cprng) {
        apr_crypto_prng_destroy(cprng);
    }
    if (!cprng_global) {
        apr_threadkey_private_delete(cprng_thread_key);
        cprng_thread_key = NULL;
    }
}

#else  /* !APR_HAS_THREADS */
#define cprng_lock(g)
#define cprng_unlock(g)
#define cprng_ring_lock()
#define cprng_ring_unlock()
#endif /* !APR_HAS_THREADS */

APR_DECLARE(apr_status_t) apr_crypto_prng_init(apr_pool_t *pool, apr_crypto_t *crypto,
        apr_crypto_cipher_e cipher, apr_size_t bufsize, const unsigned char seed[], int flags)
{
    apr_status_t rv;

    if (cprng_global) {
        return APR_EREINIT;
    }

    cprng_ring = apr_palloc(pool, sizeof(*cprng_ring));
    if (!cprng_ring) {
        return APR_ENOMEM;
    }
    APR_RING_INIT(cprng_ring, apr_crypto_prng_t, link);

    if (flags & APR_CRYPTO_PRNG_PER_THREAD) {
#if !APR_HAS_THREADS
        return APR_ENOTIMPL;
#else
        rv = apr_threadkey_private_create(&cprng_thread_key,
                                          cprng_thread_destroy, pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
#endif
    }

#if APR_HAS_THREADS
    rv = apr_thread_mutex_create(&cprng_ring_mutex, APR_THREAD_MUTEX_DEFAULT,
                                 pool);
    if (rv != APR_SUCCESS) {
        if (flags & APR_CRYPTO_PRNG_PER_THREAD) {
            apr_threadkey_private_delete(cprng_thread_key);
            cprng_thread_key = NULL;
        }
        return rv;
    }

    /* Global CPRNG is locked (and obviously not per-thread) */
    flags = (flags | APR_CRYPTO_PRNG_LOCKED) & ~APR_CRYPTO_PRNG_PER_THREAD;
#endif

    rv = apr_crypto_prng_create(&cprng_global, crypto, cipher, bufsize, flags,
                                seed, pool);
    if (rv != APR_SUCCESS) {
        if (flags & APR_CRYPTO_PRNG_PER_THREAD) {
            apr_threadkey_private_delete(cprng_thread_key);
            cprng_thread_key = NULL;
        }
        return rv;
    }

    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_crypto_prng_term(void)
{
    if (!cprng_global) {
        return APR_EINIT;
    }

    apr_crypto_prng_destroy(cprng_global);
    cprng_global = NULL;

    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_crypto_random_bytes(void *buf, apr_size_t len)
{
    if (!cprng_global) {
        return APR_EINIT;
    }

    return apr_crypto_prng_bytes(cprng_global, buf, len);
}

#if APR_HAS_THREADS
APR_DECLARE(apr_status_t) apr_crypto_random_thread_bytes(void *buf,
                                                         apr_size_t len)
{
    apr_status_t rv;
    apr_crypto_prng_t *cprng;
    void *private = NULL;

    if (!cprng_thread_key || !cprng_global) {
        return APR_EINIT;
    }

    rv = apr_threadkey_private_get(&private, cprng_thread_key);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    cprng = private;
    if (!cprng) {
        rv = apr_crypto_prng_create(&cprng, cprng_global->crypto, cprng_global->cipher, 0,
                APR_CRYPTO_PRNG_PER_THREAD, NULL, NULL);
        if (rv != APR_SUCCESS) {
            return rv;
        }

        rv = apr_threadkey_private_set(cprng, cprng_thread_key);
        if (rv != APR_SUCCESS) {
            apr_crypto_prng_destroy(cprng);
            return rv;
        }
    }

    return apr_crypto_prng_bytes(cprng, buf, len);
}
#endif

static apr_status_t cprng_cleanup(void *arg)
{
    apr_crypto_prng_t *cprng = arg;

    if (cprng == cprng_global) {
        cprng_global = NULL;
#if APR_HAS_THREADS
        cprng_ring_mutex = NULL;
#endif
        cprng_ring = NULL;
    }
    else if (cprng_global && !(cprng->flags & APR_CRYPTO_PRNG_PER_THREAD)) {
        cprng_ring_lock();
        APR_RING_REMOVE(cprng, link);
        cprng_ring_unlock();
    }

    if (cprng->ctx) {
        cprng->crypto->provider->cprng_stream_ctx_free(cprng->ctx);
    }

    if (cprng->key) {
        apr_memzero_explicit(cprng->key, CPRNG_KEY_SIZE + cprng->len);
    }

    if (!cprng->pool) {
        free(cprng->key);
        free(cprng);
    }

    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_crypto_prng_create(apr_crypto_prng_t **pcprng,
        apr_crypto_t *crypto, apr_crypto_cipher_e cipher, apr_size_t bufsize, int flags,
        const unsigned char seed[], apr_pool_t *pool)
{
    apr_status_t rv;
    apr_crypto_prng_t *cprng;

    *pcprng = NULL;

    if (!cprng_global && pcprng != &cprng_global) {
        return APR_EINIT;
    }

    if (bufsize > APR_INT32_MAX - CPRNG_KEY_SIZE
            || (flags & APR_CRYPTO_PRNG_LOCKED && !pool)
            || (flags & ~APR_CRYPTO_PRNG_MASK)) {
        return APR_EINVAL;
    }

#if !APR_HAS_THREADS
    if (flags & (APR_CRYPTO_PRNG_LOCKED | APR_CRYPTO_PRNG_PER_THREAD)) {
        return APR_ENOTIMPL;
    }
#endif

    if (pool) {
        cprng = apr_pcalloc(pool, sizeof(*cprng));
    }
    else {
        cprng = calloc(1, sizeof(*cprng));
    }
    if (!cprng) {
        return APR_ENOMEM;
    }
    cprng->cipher = cipher;
    cprng->flags = flags;
    cprng->pool = pool;

    if (bufsize == 0) {
        bufsize = CPRNG_BUF_SIZE_DEF;
    }
    else if (bufsize < CPRNG_BUF_SIZE_MIN) {
        bufsize = CPRNG_BUF_SIZE_MIN;
    }
    else if (bufsize % CPRNG_KEY_SIZE) {
        bufsize += CPRNG_KEY_SIZE;
        bufsize -= bufsize % CPRNG_KEY_SIZE;
    }
    if (pool) {
        cprng->key = apr_palloc(pool, CPRNG_KEY_SIZE + bufsize);
    }
    else {
        cprng->key = malloc(CPRNG_KEY_SIZE + bufsize);
    }
    if (!cprng->key) {
        cprng_cleanup(cprng);
        return APR_ENOMEM;
    }
    cprng->buf = cprng->key + CPRNG_KEY_SIZE;
    cprng->len = bufsize;

    if (crypto) {
        cprng->crypto = crypto;
    }
    else if (cprng_global && cprng_global->crypto) {
        cprng->crypto = cprng_global->crypto;
    }
#ifdef APU_CRYPTO_PRNG_RECOMMENDED_DRIVER
    else {
        const apr_crypto_driver_t *driver = NULL;
        if (!pool) {
            return APR_EINVAL;
        }

        rv = apr_crypto_init(pool);
        if (rv != APR_SUCCESS) {
            cprng_cleanup(cprng);
            return rv;
        }

        rv = apr_crypto_get_driver(&driver, APU_CRYPTO_PRNG_RECOMMENDED_DRIVER,
                NULL, NULL, pool);
        if (rv != APR_SUCCESS) {
            cprng_cleanup(cprng);
            return rv;
        }

        rv = apr_crypto_make(&cprng->crypto, driver, NULL, pool);
        if (rv != APR_SUCCESS) {
            cprng_cleanup(cprng);
            return rv;
        }
    }
#else
    else {
        return APR_ENOTIMPL;
    }
#endif

    rv = cprng->crypto->provider->cprng_stream_ctx_make(&cprng->ctx,
            cprng->crypto, cprng->cipher, pool);
    if (rv != APR_SUCCESS) {
        cprng_cleanup(cprng);
        return rv;
    }

    if (seed) {
        memset(cprng->key, 0, CPRNG_KEY_SIZE);
    }
    rv = apr_crypto_prng_reseed(cprng, seed);
    if (rv != APR_SUCCESS) {
        cprng_cleanup(cprng);
        return rv;
    }

#if APR_HAS_THREADS
    if (flags & APR_CRYPTO_PRNG_LOCKED) {
        rv = apr_thread_mutex_create(&cprng->mutex, APR_THREAD_MUTEX_DEFAULT,
                                     pool);
        if (rv != APR_SUCCESS) {
            cprng_cleanup(cprng);
            return rv;
        }
    }
#endif

    if (cprng_global && !(flags & APR_CRYPTO_PRNG_PER_THREAD)) {
        cprng_ring_lock();
        APR_RING_INSERT_TAIL(cprng_ring, cprng, apr_crypto_prng_t, link);
        cprng_ring_unlock();
    }
    else {
        APR_RING_ELEM_INIT(cprng, link);
    }

    if (pool) {
        apr_pool_cleanup_register(pool, cprng, cprng_cleanup,
                                  apr_pool_cleanup_null);
    }

    *pcprng = cprng;
    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_crypto_prng_destroy(apr_crypto_prng_t *cprng)
{
    if (!cprng->pool) {
        return cprng_cleanup(cprng);
    }

    return apr_pool_cleanup_run(cprng->pool, cprng, cprng_cleanup);
}

static apr_status_t cprng_stream_bytes(apr_crypto_prng_t *cprng,
                                       void *to, apr_size_t len)
{
    apr_status_t rv;

    rv = cprng->crypto->provider->cprng_stream_ctx_bytes(&cprng->ctx,
            cprng->key, to, len, cprng->buf);
    if (rv != APR_SUCCESS && len) {
        apr_memzero_explicit(to, len);
    }
    return rv;
}

APR_DECLARE(apr_status_t) apr_crypto_prng_reseed(apr_crypto_prng_t *cprng,
                                                 const unsigned char seed[])
{
    apr_status_t rv = APR_SUCCESS;

    if (!cprng) {
        /* Fall through with global CPRNG. */
        cprng = cprng_global;
        if (!cprng) {
            return APR_EINIT;
        }
    }

    cprng_lock(cprng);

    cprng->pos = cprng->len;
    apr_memzero_explicit(cprng->buf, cprng->len);
    if (seed) {
        apr_size_t n = 0;
        do {
            cprng->key[n] ^= seed[n];
        } while (++n < CPRNG_KEY_SIZE);
    }
    else if (cprng_global && cprng_global != cprng) {
        /* Use the global CPRNG: no need for more than the initial entropy. */
        rv = apr_crypto_random_bytes(cprng->key, CPRNG_KEY_SIZE);
    }
    else {
        /* Use the system entropy, i.e. one of "/dev/[u]random", getrandom(),
         * arc4random()... This may block but still we really want to wait for
         * the system to gather enough entropy for these 32 initial bytes, much
         * more than we want non-random bytes, and that's once and for all!
         */
        rv = apr_generate_random_bytes(cprng->key, CPRNG_KEY_SIZE);
    }
    if (rv == APR_SUCCESS) {
        /* Init/set the stream with the new key, without buffering for now
         * so that the buffer and/or the next random bytes won't be generated
         * directly from this key but from the first stream bytes it generates,
         * i.e. the next key is always extracted from the stream cipher state
         * and cleared upon use.
         */
        rv = cprng_stream_bytes(cprng, NULL, 0);
    }

    cprng_unlock(cprng);

    return rv;
}

static apr_status_t cprng_bytes(apr_crypto_prng_t *cprng,
                                void *buf, apr_size_t len)
{
    unsigned char *ptr = buf;
    apr_status_t rv;
    apr_size_t n;

    while (len) {
        n = cprng->len - cprng->pos;
        if (n == 0) {
            n = cprng->len;
            if (len >= n) {
                do {
                    rv = cprng_stream_bytes(cprng, ptr, n);
                    if (rv != APR_SUCCESS) {
                        return rv;
                    }
                    ptr += n;
                    len -= n;
                } while (len >= n);
                if (!len) {
                    break;
                }
            }
            rv = cprng_stream_bytes(cprng, cprng->buf, n);
            if (rv != APR_SUCCESS) {
                return rv;
            }
            cprng->pos = 0;
        }
        if (n > len) {
            n = len;
        }

        /* Random bytes are consumed then zero-ed to ensure
         * both forward secrecy and cleared next mixed data.
         */
        memcpy(ptr, cprng->buf + cprng->pos, n);
        apr_memzero_explicit(cprng->buf + cprng->pos, n);
        cprng->pos += n;

        ptr += n;
        len -= n;
    }

    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_crypto_prng_bytes(apr_crypto_prng_t *cprng,
                                                void *buf, apr_size_t len)
{
    apr_status_t rv;

    if (!cprng) {
        /* Fall through with global CPRNG. */
        cprng = cprng_global;
        if (!cprng) {
            return APR_EINIT;
        }
    }

    cprng_lock(cprng);

    rv = cprng_bytes(cprng, buf, len);

    cprng_unlock(cprng);

    return rv;
}

APR_DECLARE(apr_status_t) apr_crypto_prng_rekey(apr_crypto_prng_t *cprng)
{
    apr_status_t rv;

    if (!cprng) {
        /* Fall through with global CPRNG. */
        cprng = cprng_global;
        if (!cprng) {
            return APR_EINIT;
        }
    }

    cprng_lock(cprng);

    /* Clear state and renew the key. */
    cprng->pos = cprng->len;
    apr_memzero_explicit(cprng->buf, cprng->len);
    rv = cprng_stream_bytes(cprng, NULL, 0);

    cprng_unlock(cprng);

    if (cprng == cprng_global) {
        /* Forward to all maintained CPRNGs. */
        cprng_ring_lock();
        for (cprng = APR_RING_FIRST(cprng_ring);
             cprng != APR_RING_SENTINEL(cprng_ring, apr_crypto_prng_t, link);
             cprng = APR_RING_NEXT(cprng, link)) {
            apr_status_t rt = apr_crypto_prng_rekey(cprng);
            if (rt != APR_SUCCESS && rv == APR_SUCCESS) {
                rv = rt;
            }
        }
        cprng_ring_unlock();
    }

    return rv;
}

#if APR_HAS_FORK
APR_DECLARE(apr_status_t) apr_crypto_prng_after_fork(apr_crypto_prng_t *cprng,
                                                     int flags)
{
    apr_status_t rv = APR_SUCCESS;
    int is_child = flags & APR_CRYPTO_FORK_INCHILD;

    if (!cprng) {
        /* Fall through with global CPRNG. */
        cprng = cprng_global;
        if (!cprng) {
            return APR_EINIT;
        }
    }

    cprng_lock(cprng);

    /* Make sure the parent and child processes never share the same state,
     * and that further fork()s from either process will not either.
     * This is done by rekeying (and clearing the buffers) in both processes,
     * and by rekeying a second time in the parent process to ensure both that
     * keys are different and that after apr_crypto_prng_after_fork() is called
     * the keys are unknown to each other processes.
     * The new key to be used by the parent process is generated in the same
     * pass as the rekey, and since cprng_stream_bytes() is designed to burn
     * and never reuse keys we are sure that this key is unique to the parent,
     * and that nothing is left over from the initial state in both processes.
     */
    cprng->pos = cprng->len;
    apr_memzero_explicit(cprng->buf, cprng->len);
    if (!is_child) {
        rv = cprng_stream_bytes(cprng, cprng->key, CPRNG_KEY_SIZE);
    }
    if (rv == APR_SUCCESS) {
        rv = cprng_stream_bytes(cprng, NULL, 0);
    }

    cprng_unlock(cprng);

    if (cprng == cprng_global) {
        /* Forward to all maintained CPRNGs. */
        cprng_ring_lock();
        for (cprng = APR_RING_FIRST(cprng_ring);
             cprng != APR_RING_SENTINEL(cprng_ring, apr_crypto_prng_t, link);
             cprng = APR_RING_NEXT(cprng, link)) {
            apr_status_t rt = apr_crypto_prng_after_fork(cprng, flags);
            if (rt != APR_SUCCESS && rv == APR_SUCCESS) {
                rv = rt;
            }
        }
        cprng_ring_unlock();
    }

    return rv;
}
#endif /* APR_HAS_FORK */

#endif /* APU_HAVE_CRYPTO_PRNG */
#endif /* APU_HAVE_CRYPTO */
