LIBS=../../libcrypto
-$COMMON=rand_lib.c rand_crng_test.c rand_unix.c rand_win.c \
- drbg_lib.c drbg_ctr.c drbg_hash.c drbg_hmac.c
+$COMMON=rand_pool.c rand_lib.c drbg_lib.c drbg_ctr.c drbg_hash.c drbg_hmac.c
+$CRYPTO=rand_unix.c rand_win.c randfile.c rand_err.c
+
IF[{- !$disabled{'egd'} -}]
- $COMMON=$COMMON rand_egd.c
+ $CYPTO=$CYPTO rand_egd.c
ENDIF
IF[{- $config{target} =~ /vxworks/i -}]
- $COMMON=$COMMON rand_vxworks.c
+ $CYPTO=$CYPTO rand_vxworks.c
ENDIF
IF[{- $config{target} =~ /vms/i -}]
- $COMMON=$COMMON rand_vms.c
+ $CYPTO=$CYPTO rand_vms.c
ENDIF
-SOURCE[../../libcrypto]=$COMMON randfile.c rand_err.c
+
+SOURCE[../../libcrypto]=$COMMON $CRYPTO
SOURCE[../../providers/libfips.a]=$COMMON
#include "rand_local.h"
#include "internal/thread_once.h"
#include "crypto/rand.h"
+#include "crypto/rand_pool.h"
#include "crypto/cryptlib.h"
/*
drbg->parent = parent;
if (parent == NULL) {
-#ifdef FIPS_MODULE
- drbg->get_entropy = rand_crngt_get_entropy;
- drbg->cleanup_entropy = rand_crngt_cleanup_entropy;
-#else
drbg->get_entropy = rand_drbg_get_entropy;
drbg->cleanup_entropy = rand_drbg_cleanup_entropy;
-#endif
#ifndef RAND_DRBG_GET_RANDOM_NONCE
drbg->get_nonce = rand_drbg_get_nonce;
drbg->cleanup_nonce = rand_drbg_cleanup_nonce;
}
#endif
-
+#if 0
/*
* Implements the get_entropy() callback (see RAND_DRBG_set_callbacks())
*
{
rand_pool_reattach(pool, out);
}
+#endif
#ifndef FIPS_MODULE
DEFINE_RUN_ONCE_STATIC(do_rand_init)
if (drbg == NULL)
return 0;
- rand_drbg_lock(drbg);
+#if 0
ret = rand_drbg_restart(drbg, NULL, 0, 0);
- rand_drbg_unlock(drbg);
+#endif
return ret;
RAND_POOL_MAX_LENGTH);
if (pool == NULL)
return 0;
-
+#if 0
if (rand_pool_acquire_entropy(pool) == 0)
goto err;
-
+#endif
if (meth->add == NULL
|| meth->add(rand_pool_buffer(pool),
rand_pool_length(pool),
return ret;
}
-#endif /* FIPS_MODULE */
-
-/*
- * 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) {
- RANDerr(RAND_F_RAND_POOL_NEW, 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) {
- RANDerr(RAND_F_RAND_POOL_NEW, 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) {
- RANDerr(RAND_F_RAND_POOL_ATTACH, 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) {
- RANDerr(RAND_F_RAND_POOL_GROW, 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) {
- RANDerr(RAND_F_RAND_POOL_GROW, 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) {
- RANDerr(RAND_F_RAND_POOL_BYTES_NEEDED, 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 */
- RANDerr(RAND_F_RAND_POOL_BYTES_NEEDED, 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) {
- RANDerr(RAND_F_RAND_POOL_ADD, RAND_R_ENTROPY_INPUT_TOO_LONG);
- return 0;
- }
-
- if (pool->buffer == NULL) {
- RANDerr(RAND_F_RAND_POOL_ADD, 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) {
- RANDerr(RAND_F_RAND_POOL_ADD, 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) {
- RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, RAND_R_RANDOM_POOL_OVERFLOW);
- return NULL;
- }
-
- if (pool->buffer == NULL) {
- RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, 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) {
- RANDerr(RAND_F_RAND_POOL_ADD_END, RAND_R_RANDOM_POOL_OVERFLOW);
- return 0;
- }
-
- if (len > 0) {
- pool->len += len;
- pool->entropy += entropy;
- }
-
- return 1;
-}
-
-#ifndef FIPS_MODULE
int RAND_set_rand_method(const RAND_METHOD *meth)
{
if (!RUN_ONCE(&rand_init, do_rand_init))
CRYPTO_THREAD_unlock(rand_meth_lock);
return 1;
}
-#endif
+#endif /* FIPS_MODULE */
const RAND_METHOD *RAND_get_rand_method(void)
{
# include <openssl/rand_drbg.h>
# include "internal/tsan_assist.h"
# include "crypto/rand.h"
+# include "crypto/rand_pool.h"
# include "internal/numbers.h"
-/* How many times to read the TSC as a randomness source. */
-# define TSC_READ_COUNT 4
-
/* Maximum reseed intervals */
# define MAX_RESEED_INTERVAL (1 << 24)
# define MAX_RESEED_TIME_INTERVAL (1 << 20) /* approx. 12 days */
/* Default reseed intervals */
# define MASTER_RESEED_INTERVAL (1 << 8)
# define SLAVE_RESEED_INTERVAL (1 << 16)
-# define MASTER_RESEED_TIME_INTERVAL (60*60) /* 1 hour */
-# define SLAVE_RESEED_TIME_INTERVAL (7*60) /* 7 minutes */
+# define MASTER_RESEED_TIME_INTERVAL (60 * 60) /* 1 hour */
+# define SLAVE_RESEED_TIME_INTERVAL (7 * 60) /* 7 minutes */
/*
* The number of bytes that constitutes an atomic lump of entropy with respect
*/
# define DRBG_MAX_LENGTH INT32_MAX
-/* The default nonce */
-#ifdef CHARSET_EBCDIC
-# define DRBG_DEFAULT_PERS_STRING { 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, \
- 0x4c, 0x20, 0x4e, 0x49, 0x53, 0x54, 0x20, 0x53, 0x50, 0x20, 0x38, 0x30, \
- 0x30, 0x2d, 0x39, 0x30, 0x41, 0x20, 0x44, 0x52, 0x42, 0x47, 0x00};
-#else
-# define DRBG_DEFAULT_PERS_STRING "OpenSSL NIST SP 800-90A DRBG"
-#endif
-
-/*
- * 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)
-
/* DRBG status values */
typedef enum drbg_status_e {
DRBG_UNINITIALISED,
DRBG_ERROR
} DRBG_STATUS;
-
/* instantiate */
typedef int (*RAND_DRBG_instantiate_fn)(RAND_DRBG *ctx,
const unsigned char *ent,
typedef int (*RAND_DRBG_uninstantiate_fn)(RAND_DRBG *ctx);
-/*
- * The DRBG methods
- */
-
-typedef struct rand_drbg_method_st {
- RAND_DRBG_instantiate_fn instantiate;
- RAND_DRBG_reseed_fn reseed;
- RAND_DRBG_generate_fn generate;
- RAND_DRBG_uninstantiate_fn uninstantiate;
-} RAND_DRBG_METHOD;
-
-/* 888 bits from SP800-90Ar1 10.1 table 2 */
-#define HASH_PRNG_MAX_SEEDLEN (888/8)
-
-typedef struct rand_drbg_hash_st {
- EVP_MD *md;
- EVP_MD_CTX *ctx;
- size_t blocklen;
- unsigned char V[HASH_PRNG_MAX_SEEDLEN];
- unsigned char C[HASH_PRNG_MAX_SEEDLEN];
- /* Temporary value storage: should always exceed max digest length */
- unsigned char vtmp[HASH_PRNG_MAX_SEEDLEN];
-} RAND_DRBG_HASH;
-
-typedef struct rand_drbg_hmac_st {
- EVP_MD *md;
- HMAC_CTX *ctx;
- size_t blocklen;
- unsigned char K[EVP_MAX_MD_SIZE];
- unsigned char V[EVP_MAX_MD_SIZE];
-} RAND_DRBG_HMAC;
-
-/*
- * The state of a DRBG AES-CTR.
- */
-typedef struct rand_drbg_ctr_st {
- EVP_CIPHER_CTX *ctx_ecb;
- EVP_CIPHER_CTX *ctx_ctr;
- EVP_CIPHER_CTX *ctx_df;
- EVP_CIPHER *cipher_ecb;
- EVP_CIPHER *cipher_ctr;
- size_t keylen;
- unsigned char K[32];
- unsigned char V[16];
- /* Temporary block storage used by ctr_df */
- unsigned char bltmp[16];
- size_t bltmp_pos;
- unsigned char KX[48];
-} RAND_DRBG_CTR;
-
-
-/*
- * The 'random pool' acts as a dumb container for collecting random
- * input from various entropy sources. The pool has no knowledge about
- * whether its randomness is fed into a legacy RAND_METHOD via RAND_add()
- * or into a new style RAND_DRBG. 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.
- */
-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 */
-};
-
/*
* The state of all types of DRBGs, even though we only have CTR mode
* right now.
RAND_DRBG *parent;
int secure; /* 1: allocated on the secure heap, 0: otherwise */
int type; /* the nid of the underlying algorithm */
- /*
- * Stores the return value of openssl_get_fork_id() as of when we last
- * reseeded. The DRBG reseeds automatically whenever drbg->fork_id !=
- * openssl_get_fork_id(). Used to provide fork-safety and reseed this
- * DRBG in the child process.
- */
- int fork_id;
unsigned short flags; /* various external flags */
- /*
- * The random_data is used by RAND_add()/drbg_add() to attach random
- * data to the global drbg, such that the rand_drbg_get_entropy() callback
- * can pull it during instantiation and reseeding. This is necessary to
- * reconcile the different philosophies of the RAND and the RAND_DRBG
- * with respect to how randomness is added to the RNG during reseeding
- * (see PR #4328).
- */
- struct rand_pool_st *seed_pool;
-
- /*
- * Auxiliary pool for additional data.
- */
- struct rand_pool_st *adin_pool;
-
- /*
- * The following parameters are setup by the per-type "init" function.
- *
- * The supported types and their init functions are:
- * (1) CTR_DRBG: drbg_ctr_init().
- * (2) HMAC_DRBG: drbg_hmac_init().
- * (3) HASH_DRBG: drbg_hash_init().
- *
- * The parameters are closely related to the ones described in
- * section '10.2.1 CTR_DRBG' of [NIST SP 800-90Ar1], with one
- * crucial difference: In the NIST standard, all counts are given
- * in bits, whereas in OpenSSL entropy counts are given in bits
- * and buffer lengths are given in bytes.
- *
- * Since this difference has lead to some confusion in the past,
- * (see [GitHub Issue #2443], formerly [rt.openssl.org #4055])
- * the 'len' suffix has been added to all buffer sizes for
- * clarification.
- */
-
- int strength;
- size_t max_request;
- size_t min_entropylen, max_entropylen;
- size_t min_noncelen, max_noncelen;
- size_t max_perslen, max_adinlen;
-
- /*
- * Counts the number of generate requests since the last reseed
- * (Starts at 1). This value is the reseed_counter as defined in
- * NIST SP 800-90Ar1
- */
- unsigned int reseed_gen_counter;
- /*
- * Maximum number of generate requests until a reseed is required.
- * This value is ignored if it is zero.
- */
- unsigned int reseed_interval;
- /* Stores the time when the last reseeding occurred */
- time_t reseed_time;
- /*
- * Specifies the maximum time interval (in seconds) between reseeds.
- * This value is ignored if it is zero.
- */
- time_t reseed_time_interval;
- /*
- * Counts the number of reseeds since instantiation.
- * This value is ignored if it is zero.
- *
- * This counter is used only for seed propagation from the <master> DRBG
- * to its two children, the <public> and <private> DRBG. This feature is
- * very special and its sole purpose is to ensure that any randomness which
- * is added by RAND_add() or RAND_seed() will have an immediate effect on
- * the output of RAND_bytes() resp. RAND_priv_bytes().
- */
- TSAN_QUALIFIER unsigned int reseed_prop_counter;
- unsigned int reseed_next_counter;
-
- size_t seedlen;
- DRBG_STATUS state;
-
-#ifndef FIPS_MODULE
/* Application data, mainly used in the KATs. */
CRYPTO_EX_DATA ex_data;
-#endif
-
- /* Implementation specific data */
- union {
- RAND_DRBG_CTR ctr;
- RAND_DRBG_HASH hash;
- RAND_DRBG_HMAC hmac;
- } data;
- /* Implementation specific methods */
- RAND_DRBG_METHOD *meth;
+ /* Implementation */
+ EVP_RAND_CTX *rand;
/* Callback functions. See comments in rand_lib.c */
RAND_DRBG_get_entropy_fn get_entropy;
int rand_drbg_restart(RAND_DRBG *drbg,
const unsigned char *buffer, size_t len, size_t entropy);
size_t rand_drbg_seedlen(RAND_DRBG *drbg);
-/* locking api */
-int rand_drbg_lock(RAND_DRBG *drbg);
-int rand_drbg_unlock(RAND_DRBG *drbg);
-int rand_drbg_enable_locking(RAND_DRBG *drbg);
-
-
-/* initializes the DRBG implementation */
-int drbg_ctr_init(RAND_DRBG *drbg);
-int drbg_hash_init(RAND_DRBG *drbg);
-int drbg_hmac_init(RAND_DRBG *drbg);
/*
* Entropy call back for the FIPS 140-2 section 4.9.2 Conditional Tests.
SOURCE[../../libfips.a]=drbg.c
SOURCE[../../libnonfips.a]=drbg.c
-# Missing: drbg_hmac.c crngt.c
-SOURCE[../../libimplementations.a]=test_rng.c drbg_hash.c
+# Missing: drbg_hmac.c
+SOURCE[../../libimplementations.a]=test_rng.c drbg_hash.c crngt.c
--- /dev/null
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates. 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
+ */
+
+/*
+ * Implementation of the FIPS 140-2 section 4.9.2 Conditional Tests.
+ */
+
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/core_numbers.h>
+#include <openssl/params.h>
+#include "prov/providercommon.h"
+#include "prov/provider_ctx.h"
+#include "internal/cryptlib.h"
+#include "prov/rand_pool.h"
+#include "drbg_local.h"
+#include "seeding/seeding.h"
+
+typedef struct crng_test_global_st {
+ unsigned char crngt_prev[EVP_MAX_MD_SIZE];
+ RAND_POOL *crngt_pool;
+} CRNG_TEST_GLOBAL;
+
+static int crngt_get_entropy(OPENSSL_CTX *ctx, RAND_POOL *pool,
+ unsigned char *buf, unsigned char *md,
+ unsigned int *md_size)
+{
+ int r;
+ size_t n;
+ unsigned char *p;
+ EVP_MD *fmd;
+
+ if (pool == NULL)
+ return 0;
+
+ n = prov_pool_acquire_entropy(pool);
+ if (n >= CRNGT_BUFSIZ) {
+ fmd = EVP_MD_fetch(ctx, "SHA256", "");
+ if (fmd == NULL)
+ return 0;
+ p = rand_pool_detach(pool);
+ r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, fmd, NULL);
+ if (r != 0)
+ memcpy(buf, p, CRNGT_BUFSIZ);
+ rand_pool_reattach(pool, p);
+ EVP_MD_free(fmd);
+ return r;
+ }
+ return 0;
+}
+
+static void rand_crng_ossl_ctx_free(void *vcrngt_glob)
+{
+ CRNG_TEST_GLOBAL *crngt_glob = vcrngt_glob;
+
+ rand_pool_free(crngt_glob->crngt_pool);
+ OPENSSL_free(crngt_glob);
+}
+
+static void *rand_crng_ossl_ctx_new(OPENSSL_CTX *ctx)
+{
+ unsigned char buf[CRNGT_BUFSIZ];
+ CRNG_TEST_GLOBAL *crngt_glob = OPENSSL_zalloc(sizeof(*crngt_glob));
+
+ if (crngt_glob == NULL)
+ return NULL;
+
+ if ((crngt_glob->crngt_pool
+ = rand_pool_new(0, 1, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL) {
+ OPENSSL_free(crngt_glob);
+ return NULL;
+ }
+ if (crngt_get_entropy(ctx, crngt_glob->crngt_pool, buf,
+ crngt_glob->crngt_prev, NULL)) {
+ OPENSSL_cleanse(buf, sizeof(buf));
+ return crngt_glob;
+ }
+ rand_pool_free(crngt_glob->crngt_pool);
+ OPENSSL_free(crngt_glob);
+ return NULL;
+}
+
+static const OPENSSL_CTX_METHOD rand_crng_ossl_ctx_method = {
+ rand_crng_ossl_ctx_new,
+ rand_crng_ossl_ctx_free,
+};
+
+size_t prov_crngt_get_entropy(PROV_DRBG *drbg,
+ unsigned char **pout,
+ int entropy, size_t min_len, size_t max_len,
+ int prediction_resistance)
+{
+ unsigned char buf[CRNGT_BUFSIZ], md[EVP_MAX_MD_SIZE];
+ unsigned int sz;
+ RAND_POOL *pool;
+ size_t q, r = 0, s, t = 0;
+ int attempts = 3;
+ OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(drbg->provctx);
+ CRNG_TEST_GLOBAL *crngt_glob
+ = openssl_ctx_get_data(libctx, OPENSSL_CTX_RAND_CRNGT_INDEX,
+ &rand_crng_ossl_ctx_method);
+
+ if (crngt_glob == NULL)
+ return 0;
+
+ if ((pool = rand_pool_new(entropy, 1, min_len, max_len)) == NULL)
+ return 0;
+
+ while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
+ s = q > sizeof(buf) ? sizeof(buf) : q;
+ if (!crngt_get_entropy(libctx, crngt_glob->crngt_pool, buf, md,
+ &sz)
+ || memcmp(crngt_glob->crngt_prev, md, sz) == 0
+ || !rand_pool_add(pool, buf, s, s * 8))
+ goto err;
+ memcpy(crngt_glob->crngt_prev, md, sz);
+ t += s;
+ attempts++;
+ }
+ r = t;
+ *pout = rand_pool_detach(pool);
+err:
+ OPENSSL_cleanse(buf, sizeof(buf));
+ rand_pool_free(pool);
+ return r;
+}
+
+void prov_crngt_cleanup_entropy(PROV_DRBG *drbg,
+ unsigned char *out, size_t outlen)
+{
+ OPENSSL_secure_clear_free(out, outlen);
+}
+++ /dev/null
-/*
- * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
- * Copyright (c) 2019, Oracle and/or its affiliates. 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
- */
-
-/*
- * Implementation of the FIPS 140-2 section 4.9.2 Conditional Tests.
- */
-
-#include <string.h>
-#include <openssl/evp.h>
-#include "crypto/rand.h"
-#include "internal/thread_once.h"
-#include "internal/cryptlib.h"
-#include "crypto/rand_pool.h"
-#include "drbg_local.h"
-#include "crypto/rand_pool.h"
-#include "seeding/seeding.h"
-
-typedef struct crng_test_global_st {
- unsigned char crngt_prev[EVP_MAX_MD_SIZE];
- RAND_POOL *crngt_pool;
-} CRNG_TEST_GLOBAL;
-
-static int crngt_get_entropy(OPENSSL_CTX *ctx, RAND_POOL *pool,
- unsigned char *buf, unsigned char *md,
- unsigned int *md_size)
-{
- int r;
- size_t n;
- unsigned char *p;
-
- if (pool == NULL)
- return 0;
-
- n = prov_pool_acquire_entropy(pool);
- if (n >= CRNGT_BUFSIZ) {
- EVP_MD *fmd = EVP_MD_fetch(ctx, "SHA256", "");
- if (fmd == NULL)
- return 0;
- p = rand_pool_detach(pool);
- r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, fmd, NULL);
- if (r != 0)
- memcpy(buf, p, CRNGT_BUFSIZ);
- rand_pool_reattach(pool, p);
- EVP_MD_free(fmd);
- return r;
- }
- return 0;
-}
-
-static void rand_crng_ossl_ctx_free(void *vcrngt_glob)
-{
- CRNG_TEST_GLOBAL *crngt_glob = vcrngt_glob;
-
- rand_pool_free(crngt_glob->crngt_pool);
- OPENSSL_free(crngt_glob);
-}
-
-static void *rand_crng_ossl_ctx_new(OPENSSL_CTX *ctx)
-{
- unsigned char buf[CRNGT_BUFSIZ];
- CRNG_TEST_GLOBAL *crngt_glob = OPENSSL_zalloc(sizeof(*crngt_glob));
-
- if (crngt_glob == NULL)
- return NULL;
-
- if ((crngt_glob->crngt_pool
- = rand_pool_new(0, 1, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL) {
- OPENSSL_free(crngt_glob);
- return NULL;
- }
- if (crngt_get_entropy(ctx, crngt_glob->crngt_pool, buf,
- crngt_glob->crngt_prev, NULL)) {
- OPENSSL_cleanse(buf, sizeof(buf));
- return crngt_glob;
- }
- rand_pool_free(crngt_glob->crngt_pool);
- OPENSSL_free(crngt_glob);
- return NULL;
-}
-
-static const OPENSSL_CTX_METHOD rand_crng_ossl_ctx_method = {
- rand_crng_ossl_ctx_new,
- rand_crng_ossl_ctx_free,
-};
-
-int rand_crngt_get_entropy_cb(OPENSSL_CTX *ctx,
- RAND_POOL *pool,
- unsigned char *buf,
- unsigned char *md,
- unsigned int *md_size)
-{
- int r;
- size_t n;
- unsigned char *p;
-
- if (pool == NULL)
- return 0;
-
- n = rand_pool_acquire_entropy(pool);
- if (n >= CRNGT_BUFSIZ) {
- EVP_MD *fmd = EVP_MD_fetch(ctx, "SHA256", "");
- if (fmd == NULL)
- return 0;
- p = rand_pool_detach(pool);
- r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, fmd, NULL);
- if (r != 0)
- memcpy(buf, p, CRNGT_BUFSIZ);
- rand_pool_reattach(pool, p);
- EVP_MD_free(fmd);
- return r;
- }
- return 0;
-}
-
-size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
- unsigned char **pout,
- int entropy, size_t min_len, size_t max_len,
- int prediction_resistance)
-{
- unsigned char buf[CRNGT_BUFSIZ], md[EVP_MAX_MD_SIZE];
- unsigned int sz;
- RAND_POOL *pool;
- size_t q, r = 0, s, t = 0;
- int attempts = 3;
- CRNG_TEST_GLOBAL *crngt_glob
- = openssl_ctx_get_data(drbg->libctx, OPENSSL_CTX_RAND_CRNGT_INDEX,
- &rand_crng_ossl_ctx_method);
-
- if (crngt_glob == NULL)
- return 0;
-
- if ((pool = rand_pool_new(entropy, 1, min_len, max_len)) == NULL)
- return 0;
-
- while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
- s = q > sizeof(buf) ? sizeof(buf) : q;
- if (!crngt_get_entropy(drbg->libctx, crngt_glob->crngt_pool, buf, md,
- &sz)
- || memcmp(crngt_glob->crngt_prev, md, sz) == 0
- || !rand_pool_add(pool, buf, s, s * 8))
- goto err;
- memcpy(crngt_glob->crngt_prev, md, sz);
- t += s;
- attempts++;
- }
- r = t;
- *pout = rand_pool_detach(pool);
-err:
- OPENSSL_cleanse(buf, sizeof(buf));
- rand_pool_free(pool);
- return r;
-}
-
-void rand_crngt_cleanup_entropy(RAND_DRBG *drbg,
- unsigned char *out, size_t outlen)
-{
- OPENSSL_secure_clear_free(out, outlen);
-}
-
-#if 0
-const OSSL_DISPATCH crngt_functions[] = {
- { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))crngt_new },
- { OSSL_FUNC_RAND_FREECTX, (void(*)(void))crngt_free },
- { OSSL_FUNC_RAND_INSTANTIATE, (void(*)(void))crngt_instantiate },
- { OSSL_FUNC_RAND_UNINSTANTIATE, (void(*)(void))crngt_uninstantiate },
- { OSSL_FUNC_RAND_GENERATE, (void(*)(void))crngt_generate },
- { OSSL_FUNC_RAND_RESEED, (void(*)(void))crngt_reseed },
- { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))drbg_enable_locking },
- { OSSL_FUNC_RAND_LOCK, (void(*)(void))drbg_lock },
- { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))drbg_unlock },
- { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
- (void(*)(void))crngt_settable_ctx_params },
- { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))crngt_set_ctx_params },
- { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
- (void(*)(void))crngt_gettable_ctx_params },
- { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))crngt_get_ctx_params },
- { 0, NULL }
-};
-#endif