/*
 * 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
 */

#ifndef OSSL_PROVIDER_RAND_POOL_H
# define OSSL_PROVIDER_RAND_POOL_H

# include <stdio.h>
# include <openssl/rand_drbg.h>

/*
 * Maximum allocation size for RANDOM_POOL buffers
 *
 * The max_len value for the buffer provided to the rand_drbg_get_entropy()
 * callback is currently 2^31 bytes (2 gigabytes), if a derivation function
 * is used. Since this is much too large to be allocated, the rand_pool_new()
 * function chooses more modest values as default pool length, bounded
 * by RAND_POOL_MIN_LENGTH and RAND_POOL_MAX_LENGTH
 *
 * The choice of the RAND_POOL_FACTOR is large enough such that the
 * RAND_POOL can store a random input which has a lousy entropy rate of
 * 8/256 (= 0.03125) bits per byte. This input will be sent through the
 * derivation function which 'compresses' the low quality input into a
 * high quality output.
 *
 * The factor 1.5 below is the pessimistic estimate for the extra amount
 * of entropy required when no get_nonce() callback is defined.
 */
# define RAND_POOL_FACTOR        256
# define RAND_POOL_MAX_LENGTH    (RAND_POOL_FACTOR * \
                                  3 * (RAND_DRBG_STRENGTH / 16))
/*
 *                             = (RAND_POOL_FACTOR * \
 *                                1.5 * (RAND_DRBG_STRENGTH / 8))
 */

/*
 * Initial allocation minimum.
 *
 * There is a distinction between the secure and normal allocation minimums.
 * Ideally, the secure allocation size should be a power of two.  The normal
 * allocation size doesn't have any such restriction.
 *
 * The secure value is based on 128 bits of secure material, which is 16 bytes.
 * Typically, the DRBGs will set a minimum larger than this so optimal
 * allocation ought to take place (for full quality seed material).
 *
 * The normal value has been chosen by noticing that the rand_drbg_get_nonce
 * function is usually the largest of the built in allocation (twenty four
 * bytes and then appending another sixteen bytes).  This means the buffer ends
 * with 40 bytes.  The value of forty eight is comfortably above this which
 * allows some slack in the platform specific values used.
 */
# define RAND_POOL_MIN_ALLOCATION(secure) ((secure) ? 16 : 48)

/*
 * The 'random pool' acts as a dumb container for collecting random
 * input from various entropy sources. It is the callers duty to 1) initialize
 * the random pool, 2) pass it to the polling callbacks, 3) seed the RNG, and
 * 4) cleanup the random pool again.
 *
 * The random pool contains no locking mechanism because its scope and
 * lifetime is intended to be restricted to a single stack frame.
 */
typedef struct rand_pool_st {
    unsigned char *buffer;  /* points to the beginning of the random pool */
    size_t len; /* current number of random bytes contained in the pool */

    int attached;  /* true pool was attached to existing buffer */
    int secure;    /* 1: allocated on the secure heap, 0: otherwise */

    size_t min_len; /* minimum number of random bytes requested */
    size_t max_len; /* maximum number of random bytes (allocated buffer size) */
    size_t alloc_len; /* current number of bytes allocated */
    size_t entropy; /* current entropy count in bits */
    size_t entropy_requested; /* requested entropy count in bits */
} RAND_POOL;

RAND_POOL *rand_pool_new(int entropy_requested, int secure,
                         size_t min_len, size_t max_len);
RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len,
                            size_t entropy);
void rand_pool_free(RAND_POOL *pool);

const unsigned char *rand_pool_buffer(RAND_POOL *pool);
unsigned char *rand_pool_detach(RAND_POOL *pool);
void rand_pool_reattach(RAND_POOL *pool, unsigned char *buffer);

size_t rand_pool_entropy(RAND_POOL *pool);
size_t rand_pool_length(RAND_POOL *pool);

size_t rand_pool_entropy_available(RAND_POOL *pool);
size_t rand_pool_entropy_needed(RAND_POOL *pool);
/* |entropy_factor| expresses how many bits of data contain 1 bit of entropy */
size_t rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor);
size_t rand_pool_bytes_remaining(RAND_POOL *pool);

int rand_pool_add(RAND_POOL *pool,
                  const unsigned char *buffer, size_t len, size_t entropy);
unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len);
int rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy);

#endif /* OSSL_PROVIDER_RAND_POOL_H */
