/*
 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdio.h>
#include <time.h>
#include "internal/cryptlib.h"
#include <openssl/opensslconf.h>
#include "crypto/rand.h"
#include <openssl/engine.h>
#include "internal/thread_once.h"
#include "crypto/rand_pool.h"

/*
 * Allocate memory and initialize a new random pool
 */
RAND_POOL *rand_pool_new(int entropy_requested, int secure,
                         size_t min_len, size_t max_len)
{
    RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool));
    size_t min_alloc_size = RAND_POOL_MIN_ALLOCATION(secure);

    if (pool == NULL) {
        ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    pool->min_len = min_len;
    pool->max_len = (max_len > RAND_POOL_MAX_LENGTH) ?
        RAND_POOL_MAX_LENGTH : max_len;
    pool->alloc_len = min_len < min_alloc_size ? min_alloc_size : min_len;
    if (pool->alloc_len > pool->max_len)
        pool->alloc_len = pool->max_len;

    if (secure)
        pool->buffer = OPENSSL_secure_zalloc(pool->alloc_len);
    else
        pool->buffer = OPENSSL_zalloc(pool->alloc_len);

    if (pool->buffer == NULL) {
        ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    pool->entropy_requested = entropy_requested;
    pool->secure = secure;
    return pool;

err:
    OPENSSL_free(pool);
    return NULL;
}

/*
 * Attach new random pool to the given buffer
 *
 * This function is intended to be used only for feeding random data
 * provided by RAND_add() and RAND_seed() into the <master> DRBG.
 */
RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len,
                            size_t entropy)
{
    RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool));

    if (pool == NULL) {
        ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    /*
     * The const needs to be cast away, but attached buffers will not be
     * modified (in contrary to allocated buffers which are zeroed and
     * freed in the end).
     */
    pool->buffer = (unsigned char *) buffer;
    pool->len = len;

    pool->attached = 1;

    pool->min_len = pool->max_len = pool->alloc_len = pool->len;
    pool->entropy = entropy;

    return pool;
}

/*
 * Free |pool|, securely erasing its buffer.
 */
void rand_pool_free(RAND_POOL *pool)
{
    if (pool == NULL)
        return;

    /*
     * Although it would be advisable from a cryptographical viewpoint,
     * we are not allowed to clear attached buffers, since they are passed
     * to rand_pool_attach() as `const unsigned char*`.
     * (see corresponding comment in rand_pool_attach()).
     */
    if (!pool->attached) {
        if (pool->secure)
            OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len);
        else
            OPENSSL_clear_free(pool->buffer, pool->alloc_len);
    }

    OPENSSL_free(pool);
}

/*
 * Return the |pool|'s buffer to the caller (readonly).
 */
const unsigned char *rand_pool_buffer(RAND_POOL *pool)
{
    return pool->buffer;
}

/*
 * Return the |pool|'s entropy to the caller.
 */
size_t rand_pool_entropy(RAND_POOL *pool)
{
    return pool->entropy;
}

/*
 * Return the |pool|'s buffer length to the caller.
 */
size_t rand_pool_length(RAND_POOL *pool)
{
    return pool->len;
}

/*
 * Detach the |pool| buffer and return it to the caller.
 * It's the responsibility of the caller to free the buffer
 * using OPENSSL_secure_clear_free() or to re-attach it
 * again to the pool using rand_pool_reattach().
 */
unsigned char *rand_pool_detach(RAND_POOL *pool)
{
    unsigned char *ret = pool->buffer;
    pool->buffer = NULL;
    pool->entropy = 0;
    return ret;
}

/*
 * Re-attach the |pool| buffer. It is only allowed to pass
 * the |buffer| which was previously detached from the same pool.
 */
void rand_pool_reattach(RAND_POOL *pool, unsigned char *buffer)
{
    pool->buffer = buffer;
    OPENSSL_cleanse(pool->buffer, pool->len);
    pool->len = 0;
}

/*
 * If |entropy_factor| bits contain 1 bit of entropy, how many bytes does one
 * need to obtain at least |bits| bits of entropy?
 */
#define ENTROPY_TO_BYTES(bits, entropy_factor) \
    (((bits) * (entropy_factor) + 7) / 8)


/*
 * Checks whether the |pool|'s entropy is available to the caller.
 * This is the case when entropy count and buffer length are high enough.
 * Returns
 *
 *  |entropy|  if the entropy count and buffer size is large enough
 *      0      otherwise
 */
size_t rand_pool_entropy_available(RAND_POOL *pool)
{
    if (pool->entropy < pool->entropy_requested)
        return 0;

    if (pool->len < pool->min_len)
        return 0;

    return pool->entropy;
}

/*
 * Returns the (remaining) amount of entropy needed to fill
 * the random pool.
 */

size_t rand_pool_entropy_needed(RAND_POOL *pool)
{
    if (pool->entropy < pool->entropy_requested)
        return pool->entropy_requested - pool->entropy;

    return 0;
}

/* Increase the allocation size -- not usable for an attached pool */
static int rand_pool_grow(RAND_POOL *pool, size_t len)
{
    if (len > pool->alloc_len - pool->len) {
        unsigned char *p;
        const size_t limit = pool->max_len / 2;
        size_t newlen = pool->alloc_len;

        if (pool->attached || len > pool->max_len - pool->len) {
            ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
            return 0;
        }

        do
            newlen = newlen < limit ? newlen * 2 : pool->max_len;
        while (len > newlen - pool->len);

        if (pool->secure)
            p = OPENSSL_secure_zalloc(newlen);
        else
            p = OPENSSL_zalloc(newlen);
        if (p == NULL) {
            ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE);
            return 0;
        }
        memcpy(p, pool->buffer, pool->len);
        if (pool->secure)
            OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len);
        else
            OPENSSL_clear_free(pool->buffer, pool->alloc_len);
        pool->buffer = p;
        pool->alloc_len = newlen;
    }
    return 1;
}

/*
 * Returns the number of bytes needed to fill the pool, assuming
 * the input has 1 / |entropy_factor| entropy bits per data bit.
 * In case of an error, 0 is returned.
 */

size_t rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor)
{
    size_t bytes_needed;
    size_t entropy_needed = rand_pool_entropy_needed(pool);

    if (entropy_factor < 1) {
        ERR_raise(ERR_LIB_RAND, RAND_R_ARGUMENT_OUT_OF_RANGE);
        return 0;
    }

    bytes_needed = ENTROPY_TO_BYTES(entropy_needed, entropy_factor);

    if (bytes_needed > pool->max_len - pool->len) {
        /* not enough space left */
        ERR_raise(ERR_LIB_RAND, RAND_R_RANDOM_POOL_OVERFLOW);
        return 0;
    }

    if (pool->len < pool->min_len &&
        bytes_needed < pool->min_len - pool->len)
        /* to meet the min_len requirement */
        bytes_needed = pool->min_len - pool->len;

    /*
     * Make sure the buffer is large enough for the requested amount
     * of data. This guarantees that existing code patterns where
     * rand_pool_add_begin, rand_pool_add_end or rand_pool_add
     * are used to collect entropy data without any error handling
     * whatsoever, continue to be valid.
     * Furthermore if the allocation here fails once, make sure that
     * we don't fall back to a less secure or even blocking random source,
     * as that could happen by the existing code patterns.
     * This is not a concern for additional data, therefore that
     * is not needed if rand_pool_grow fails in other places.
     */
    if (!rand_pool_grow(pool, bytes_needed)) {
        /* persistent error for this pool */
        pool->max_len = pool->len = 0;
        return 0;
    }

    return bytes_needed;
}

/* Returns the remaining number of bytes available */
size_t rand_pool_bytes_remaining(RAND_POOL *pool)
{
    return pool->max_len - pool->len;
}

/*
 * Add random bytes to the random pool.
 *
 * It is expected that the |buffer| contains |len| bytes of
 * random input which contains at least |entropy| bits of
 * randomness.
 *
 * Returns 1 if the added amount is adequate, otherwise 0
 */
int rand_pool_add(RAND_POOL *pool,
                  const unsigned char *buffer, size_t len, size_t entropy)
{
    if (len > pool->max_len - pool->len) {
        ERR_raise(ERR_LIB_RAND, RAND_R_ENTROPY_INPUT_TOO_LONG);
        return 0;
    }

    if (pool->buffer == NULL) {
        ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    if (len > 0) {
        /*
         * This is to protect us from accidentally passing the buffer
         * returned from rand_pool_add_begin.
         * The check for alloc_len makes sure we do not compare the
         * address of the end of the allocated memory to something
         * different, since that comparison would have an
         * indeterminate result.
         */
        if (pool->alloc_len > pool->len && pool->buffer + pool->len == buffer) {
            ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
            return 0;
        }
        /*
         * We have that only for cases when a pool is used to collect
         * additional data.
         * For entropy data, as long as the allocation request stays within
         * the limits given by rand_pool_bytes_needed this rand_pool_grow
         * below is guaranteed to succeed, thus no allocation happens.
         */
        if (!rand_pool_grow(pool, len))
            return 0;
        memcpy(pool->buffer + pool->len, buffer, len);
        pool->len += len;
        pool->entropy += entropy;
    }

    return 1;
}

/*
 * Start to add random bytes to the random pool in-place.
 *
 * Reserves the next |len| bytes for adding random bytes in-place
 * and returns a pointer to the buffer.
 * The caller is allowed to copy up to |len| bytes into the buffer.
 * If |len| == 0 this is considered a no-op and a NULL pointer
 * is returned without producing an error message.
 *
 * After updating the buffer, rand_pool_add_end() needs to be called
 * to finish the update operation (see next comment).
 */
unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
{
    if (len == 0)
        return NULL;

    if (len > pool->max_len - pool->len) {
        ERR_raise(ERR_LIB_RAND, RAND_R_RANDOM_POOL_OVERFLOW);
        return NULL;
    }

    if (pool->buffer == NULL) {
        ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
        return NULL;
    }

    /*
     * As long as the allocation request stays within the limits given
     * by rand_pool_bytes_needed this rand_pool_grow below is guaranteed
     * to succeed, thus no allocation happens.
     * We have that only for cases when a pool is used to collect
     * additional data. Then the buffer might need to grow here,
     * and of course the caller is responsible to check the return
     * value of this function.
     */
    if (!rand_pool_grow(pool, len))
        return NULL;

    return pool->buffer + pool->len;
}

/*
 * Finish to add random bytes to the random pool in-place.
 *
 * Finishes an in-place update of the random pool started by
 * rand_pool_add_begin() (see previous comment).
 * It is expected that |len| bytes of random input have been added
 * to the buffer which contain at least |entropy| bits of randomness.
 * It is allowed to add less bytes than originally reserved.
 */
int rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy)
{
    if (len > pool->alloc_len - pool->len) {
        ERR_raise(ERR_LIB_RAND, RAND_R_RANDOM_POOL_OVERFLOW);
        return 0;
    }

    if (len > 0) {
        pool->len += len;
        pool->entropy += entropy;
    }

    return 1;
}
