Latest update.

This commit is contained in:
2019-09-21 00:43:47 +09:00
parent 2e57f602ae
commit 62515c7d8d
1131 changed files with 47556 additions and 24957 deletions
+2 -2
View File
@@ -354,7 +354,7 @@ static int drbg_ctr_uninstantiate(RAND_DRBG *drbg)
{
EVP_CIPHER_CTX_free(drbg->data.ctr.ctx);
EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_df);
EVP_CIPHER_meth_free(drbg->data.ctr.cipher);
EVP_CIPHER_free(drbg->data.ctr.cipher);
OPENSSL_cleanse(&drbg->data.ctr, sizeof(drbg->data.ctr));
return 1;
}
@@ -392,7 +392,7 @@ int drbg_ctr_init(RAND_DRBG *drbg)
if (cipher == NULL)
return 0;
EVP_CIPHER_meth_free(ctr->cipher);
EVP_CIPHER_free(ctr->cipher);
ctr->cipher = cipher;
drbg->meth = &drbg_ctr_meth;
+3 -3
View File
@@ -290,7 +290,7 @@ static int drbg_hash_generate(RAND_DRBG *drbg,
static int drbg_hash_uninstantiate(RAND_DRBG *drbg)
{
EVP_MD_meth_free(drbg->data.hash.md);
EVP_MD_free(drbg->data.hash.md);
EVP_MD_CTX_free(drbg->data.hash.ctx);
OPENSSL_cleanse(&drbg->data.hash, sizeof(drbg->data.hash));
return 1;
@@ -346,12 +346,12 @@ int drbg_hash_init(RAND_DRBG *drbg)
if (hash->ctx == NULL) {
hash->ctx = EVP_MD_CTX_new();
if (hash->ctx == NULL) {
EVP_MD_meth_free(md);
EVP_MD_free(md);
return 0;
}
}
EVP_MD_meth_free(hash->md);
EVP_MD_free(hash->md);
hash->md = md;
/* These are taken from SP 800-90 10.1 Table 2 */
+3 -3
View File
@@ -184,7 +184,7 @@ static int drbg_hmac_generate(RAND_DRBG *drbg,
static int drbg_hmac_uninstantiate(RAND_DRBG *drbg)
{
EVP_MD_meth_free(drbg->data.hmac.md);
EVP_MD_free(drbg->data.hmac.md);
HMAC_CTX_free(drbg->data.hmac.ctx);
OPENSSL_cleanse(&drbg->data.hmac, sizeof(drbg->data.hmac));
return 1;
@@ -239,13 +239,13 @@ int drbg_hmac_init(RAND_DRBG *drbg)
if (hmac->ctx == NULL) {
hmac->ctx = HMAC_CTX_new();
if (hmac->ctx == NULL) {
EVP_MD_meth_free(md);
EVP_MD_free(md);
return 0;
}
}
/* These are taken from SP 800-90 10.1 Table 2 */
EVP_MD_meth_free(hmac->md);
EVP_MD_free(hmac->md);
hmac->md = md;
hmac->blocklen = EVP_MD_size(md);
/* See SP800-57 Part1 Rev4 5.6.1 Table 3 */
+19 -9
View File
@@ -191,6 +191,9 @@ static void drbg_ossl_ctx_free(void *vdgbl)
{
DRBG_GLOBAL *dgbl = vdgbl;
if (dgbl == NULL)
return;
RAND_DRBG_free(dgbl->master_drbg);
CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg);
CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg);
@@ -230,6 +233,9 @@ static void drbg_nonce_ossl_ctx_free(void *vdngbl)
{
DRBG_NONCE_GLOBAL *dngbl = vdngbl;
if (dngbl == NULL)
return;
CRYPTO_THREAD_lock_free(dngbl->rand_nonce_lock);
OPENSSL_free(dngbl);
@@ -265,7 +271,7 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
return 0;
memset(&data, 0, sizeof(data));
pool = rand_pool_new(0, min_len, max_len);
pool = rand_pool_new(0, 0, min_len, max_len);
if (pool == NULL)
return 0;
@@ -295,7 +301,7 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
unsigned char *out, size_t outlen)
{
OPENSSL_secure_clear_free(out, outlen);
OPENSSL_clear_free(out, outlen);
}
/*
@@ -409,7 +415,7 @@ static RAND_DRBG *rand_drbg_new(OPENSSL_CTX *ctx,
drbg->libctx = ctx;
drbg->secure = secure && CRYPTO_secure_allocated(drbg);
drbg->fork_count = rand_fork_count;
drbg->fork_id = openssl_get_fork_id();
drbg->parent = parent;
if (parent == NULL) {
@@ -535,9 +541,10 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
}
if (drbg->state != DRBG_UNINITIALISED) {
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
drbg->state == DRBG_ERROR ? RAND_R_IN_ERROR_STATE
: RAND_R_ALREADY_INSTANTIATED);
if (drbg->state == DRBG_ERROR)
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_IN_ERROR_STATE);
else
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ALREADY_INSTANTIATED);
goto end;
}
@@ -823,6 +830,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
int prediction_resistance,
const unsigned char *adin, size_t adinlen)
{
int fork_id;
int reseed_required = 0;
if (drbg->state != DRBG_READY) {
@@ -848,8 +856,10 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
return 0;
}
if (drbg->fork_count != rand_fork_count) {
drbg->fork_count = rand_fork_count;
fork_id = openssl_get_fork_id();
if (drbg->fork_id != fork_id) {
drbg->fork_id = fork_id;
reseed_required = 1;
}
@@ -909,7 +919,7 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
if (drbg->adin_pool == NULL) {
if (drbg->type == 0)
goto err;
drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen);
drbg->adin_pool = rand_pool_new(0, 0, 0, drbg->max_adinlen);
if (drbg->adin_pool == NULL)
goto err;
}
+3 -3
View File
@@ -45,7 +45,7 @@ static void *rand_crng_ossl_ctx_new(OPENSSL_CTX *ctx)
return NULL;
if ((crngt_glob->crngt_pool
= rand_pool_new(0, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL) {
= rand_pool_new(0, 1, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL) {
OPENSSL_free(crngt_glob);
return NULL;
}
@@ -87,7 +87,7 @@ int rand_crngt_get_entropy_cb(OPENSSL_CTX *ctx,
if (r != 0)
memcpy(buf, p, CRNGT_BUFSIZ);
rand_pool_reattach(pool, p);
EVP_MD_meth_free(fmd);
EVP_MD_free(fmd);
return r;
}
return 0;
@@ -110,7 +110,7 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
if (crngt_glob == NULL)
return 0;
if ((pool = rand_pool_new(entropy, min_len, max_len)) == NULL)
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) {
+1 -44
View File
@@ -13,47 +13,6 @@
#ifndef OPENSSL_NO_ERR
static const ERR_STRING_DATA RAND_str_functs[] = {
{ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_BYTES, 0), "drbg_bytes"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_CTR_INIT, 0), "drbg_ctr_init"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_GET_ENTROPY, 0), "drbg_get_entropy"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_SETUP, 0), "drbg_setup"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_GET_ENTROPY, 0), "get_entropy"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_BYTES, 0), "RAND_bytes"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_BYTES_EX, 0), "rand_bytes_ex"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_ENABLE_LOCKING, 0),
"rand_drbg_enable_locking"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GENERATE, 0),
"RAND_DRBG_generate"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GET_ENTROPY, 0),
"rand_drbg_get_entropy"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GET_NONCE, 0),
"rand_drbg_get_nonce"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_INSTANTIATE, 0),
"RAND_DRBG_instantiate"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_NEW, 0), "RAND_DRBG_new"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESEED, 0), "RAND_DRBG_reseed"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESTART, 0), "rand_drbg_restart"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET, 0), "RAND_DRBG_set"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET_DEFAULTS, 0),
"RAND_DRBG_set_defaults"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_UNINSTANTIATE, 0),
"RAND_DRBG_uninstantiate"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_LOAD_FILE, 0), "RAND_load_file"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ACQUIRE_ENTROPY, 0),
"rand_pool_acquire_entropy"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD, 0), "rand_pool_add"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD_BEGIN, 0),
"rand_pool_add_begin"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD_END, 0), "rand_pool_add_end"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ATTACH, 0), "rand_pool_attach"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_BYTES_NEEDED, 0),
"rand_pool_bytes_needed"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_NEW, 0), "rand_pool_new"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_WRITE_FILE, 0), "RAND_write_file"},
{0, NULL}
};
static const ERR_STRING_DATA RAND_str_reasons[] = {
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ADDITIONAL_INPUT_TOO_LONG),
"additional input too long"},
@@ -130,10 +89,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = {
int ERR_load_RAND_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) {
ERR_load_strings_const(RAND_str_functs);
if (ERR_reason_error_string(RAND_str_reasons[0].error) == NULL)
ERR_load_strings_const(RAND_str_reasons);
}
#endif
return 1;
}
+31 -18
View File
@@ -54,7 +54,13 @@
# 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
@@ -82,6 +88,24 @@
* 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 chosed 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 {
@@ -180,9 +204,11 @@ struct rand_pool_st {
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 */
};
@@ -199,12 +225,12 @@ struct rand_drbg_st {
int secure; /* 1: allocated on the secure heap, 0: otherwise */
int type; /* the nid of the underlying algorithm */
/*
* Stores the value of the rand_fork_count global as of when we last
* reseeded. The DRBG reseeds automatically whenever drbg->fork_count !=
* rand_fork_count. Used to provide fork-safety and reseed this DRBG in
* the child process.
* 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_count;
int fork_id;
unsigned short flags; /* various external flags */
/*
@@ -305,19 +331,6 @@ struct rand_drbg_st {
/* The global RAND method, and the global buffer and DRBG instance. */
extern RAND_METHOD rand_meth;
/*
* A "generation count" of forks. Incremented in the child process after a
* fork. Since rand_fork_count is increment-only, and only ever written to in
* the child process of the fork, which is guaranteed to be single-threaded, no
* locking is needed for normal (read) accesses; the rest of pthread fork
* processing is assumed to introduce the necessary memory barriers. Sibling
* children of a given parent will produce duplicate values, but this is not
* problematic because the reseeding process pulls input from the system CSPRNG
* and/or other global sources, so the siblings will end up generating
* different output streams.
*/
extern int rand_fork_count;
/* DRBG helpers */
int rand_drbg_restart(RAND_DRBG *drbg,
const unsigned char *buffer, size_t len, size_t entropy);
+120 -21
View File
@@ -30,8 +30,6 @@ static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT;
static int rand_inited = 0;
#endif /* FIPS_MODE */
int rand_fork_count;
#ifdef OPENSSL_RAND_SEED_RDTSC
/*
* IMPORTANT NOTE: It is not currently possible to use this code
@@ -69,8 +67,6 @@ size_t rand_acquire_entropy_from_tsc(RAND_POOL *pool)
size_t OPENSSL_ia32_rdseed_bytes(unsigned char *buf, size_t len);
size_t OPENSSL_ia32_rdrand_bytes(unsigned char *buf, size_t len);
extern unsigned int OPENSSL_ia32cap_P[];
/*
* Acquire entropy using Intel-specific cpu instructions
*
@@ -149,7 +145,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
pool = drbg->seed_pool;
pool->entropy_requested = entropy;
} else {
pool = rand_pool_new(entropy, min_len, max_len);
pool = rand_pool_new(entropy, drbg->secure, min_len, max_len);
if (pool == NULL)
return 0;
}
@@ -162,7 +158,9 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
size_t bytes = 0;
/*
* Get random from parent, include our state as additional input.
* Get random data from parent. Include our address as additional input,
* in order to provide some additional distinction between different
* DRBG child instances.
* Our lock is already held, but we need to lock our parent before
* generating bits from it. (Note: taking the lock will be a no-op
* if locking if drbg->parent->lock == NULL.)
@@ -171,7 +169,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
if (RAND_DRBG_generate(drbg->parent,
buffer, bytes_needed,
prediction_resistance,
NULL, 0) != 0)
(unsigned char *)&drbg, sizeof(drbg)) != 0)
bytes = bytes_needed;
drbg->reseed_next_counter
= tsan_load(&drbg->parent->reseed_prop_counter);
@@ -203,8 +201,12 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
unsigned char *out, size_t outlen)
{
if (drbg->seed_pool == NULL)
OPENSSL_secure_clear_free(out, outlen);
if (drbg->seed_pool == NULL) {
if (drbg->secure)
OPENSSL_secure_clear_free(out, outlen);
else
OPENSSL_clear_free(out, outlen);
}
}
/*
@@ -236,11 +238,6 @@ void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out)
rand_pool_reattach(pool, out);
}
void rand_fork(void)
{
rand_fork_count++;
}
#ifndef FIPS_MODE
DEFINE_RUN_ONCE_STATIC(do_rand_init)
{
@@ -331,7 +328,7 @@ int RAND_poll(void)
RAND_POOL *pool = NULL;
/* fill random pool and seed the current legacy RNG */
pool = rand_pool_new(RAND_DRBG_STRENGTH,
pool = rand_pool_new(RAND_DRBG_STRENGTH, 1,
(RAND_DRBG_STRENGTH + 7) / 8,
RAND_POOL_MAX_LENGTH);
if (pool == NULL)
@@ -360,9 +357,11 @@ int RAND_poll(void)
* Allocate memory and initialize a new random pool
*/
RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len)
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);
@@ -372,14 +371,22 @@ RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len)
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);
pool->buffer = OPENSSL_secure_zalloc(pool->max_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;
@@ -414,7 +421,7 @@ RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len,
pool->attached = 1;
pool->min_len = pool->max_len = pool->len;
pool->min_len = pool->max_len = pool->alloc_len = pool->len;
pool->entropy = entropy;
return pool;
@@ -434,8 +441,13 @@ void rand_pool_free(RAND_POOL *pool)
* to rand_pool_attach() as `const unsigned char*`.
* (see corresponding comment in rand_pool_attach()).
*/
if (!pool->attached)
OPENSSL_secure_clear_free(pool->buffer, pool->max_len);
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);
}
@@ -528,6 +540,42 @@ size_t rand_pool_entropy_needed(RAND_POOL *pool)
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.
@@ -557,6 +605,24 @@ size_t rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor)
/* 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;
}
@@ -589,6 +655,27 @@ int rand_pool_add(RAND_POOL *pool,
}
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;
@@ -624,6 +711,18 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
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;
}
@@ -638,7 +737,7 @@ 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)
{
if (len > pool->max_len - pool->len) {
if (len > pool->alloc_len - pool->len) {
RANDerr(RAND_F_RAND_POOL_ADD_END, RAND_R_RANDOM_POOL_OVERFLOW);
return 0;
}
+141 -26
View File
@@ -14,12 +14,17 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/rand.h>
#include <openssl/crypto.h>
#include "rand_lcl.h"
#include "internal/rand_int.h"
#include <stdio.h>
#include "internal/dso.h"
#if defined(__linux)
# include <asm/unistd.h>
#ifdef __linux
# include <sys/syscall.h>
# ifdef DEVRANDOM_WAIT
# include <sys/shm.h>
# include <sys/utsname.h>
# endif
#endif
#if defined(__FreeBSD__) && !defined(OPENSSL_SYS_UEFI)
# include <sys/types.h>
@@ -254,6 +259,17 @@ static ssize_t sysctl_random(char *buf, size_t buflen)
# endif
# if defined(OPENSSL_RAND_SEED_GETRANDOM)
# if defined(__linux) && !defined(__NR_getrandom)
# if defined(__arm__) && defined(__NR_SYSCALL_BASE)
# define __NR_getrandom (__NR_SYSCALL_BASE+384)
# elif defined(__i386__)
# define __NR_getrandom 355
# elif defined(__x86_64__) && !defined(__ILP32__)
# define __NR_getrandom 318
# endif
# endif
/*
* syscall_random(): Try to get random data using a system call
* returns the number of bytes returned in buf, or < 0 on error.
@@ -325,6 +341,96 @@ static struct random_device {
} random_devices[OSSL_NELEM(random_device_paths)];
static int keep_random_devices_open = 1;
# if defined(__linux) && defined(DEVRANDOM_WAIT)
static void *shm_addr;
# if !defined(FIPS_MODE)
static void cleanup_shm(void)
{
shmdt(shm_addr);
}
# endif
/*
* Ensure that the system randomness source has been adequately seeded.
* This is done by having the first start of libcrypto, wait until the device
* /dev/random becomes able to supply a byte of entropy. Subsequent starts
* of the library and later reseedings do not need to do this.
*/
static int wait_random_seeded(void)
{
static int seeded = OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID < 0;
static const int kernel_version[] = { DEVRANDOM_SAFE_KERNEL };
int kernel[2];
int shm_id, fd, r;
char c, *p;
struct utsname un;
fd_set fds;
if (!seeded) {
/* See if anything has created the global seeded indication */
if ((shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1, 0)) == -1) {
/*
* Check the kernel's version and fail if it is too recent.
*
* Linux kernels from 4.8 onwards do not guarantee that
* /dev/urandom is properly seeded when /dev/random becomes
* readable. However, such kernels support the getentropy(2)
* system call and this should always succeed which renders
* this alternative but essentially identical source moot.
*/
if (uname(&un) == 0) {
kernel[0] = atoi(un.release);
p = strchr(un.release, '.');
kernel[1] = p == NULL ? 0 : atoi(p + 1);
if (kernel[0] > kernel_version[0]
|| (kernel[0] == kernel_version[0]
&& kernel[1] >= kernel_version[1])) {
return 0;
}
}
/* Open /dev/random and wait for it to be readable */
if ((fd = open(DEVRANDOM_WAIT, O_RDONLY)) != -1) {
if (DEVRANDM_WAIT_USE_SELECT && fd < FD_SETSIZE) {
FD_ZERO(&fds);
FD_SET(fd, &fds);
while ((r = select(fd + 1, &fds, NULL, NULL, NULL)) < 0
&& errno == EINTR);
} else {
while ((r = read(fd, &c, 1)) < 0 && errno == EINTR);
}
close(fd);
if (r == 1) {
seeded = 1;
/* Create the shared memory indicator */
shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1,
IPC_CREAT | S_IRUSR | S_IRGRP | S_IROTH);
}
}
}
if (shm_id != -1) {
seeded = 1;
/*
* Map the shared memory to prevent its premature destruction.
* If this call fails, it isn't a big problem.
*/
shm_addr = shmat(shm_id, NULL, SHM_RDONLY);
# ifndef FIPS_MODE
/* TODO 3.0: The FIPS provider doesn't have OPENSSL_atexit */
if (shm_addr != (void *)-1)
OPENSSL_atexit(&cleanup_shm);
# endif
}
}
return seeded;
}
# else /* defined __linux */
static int wait_random_seeded(void)
{
return 1;
}
# endif
/*
* Verify that the file descriptor associated with the random source is
* still valid. The rationale for doing this is the fact that it is not
@@ -451,12 +557,12 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
# if defined(OPENSSL_RAND_SEED_NONE)
return rand_pool_entropy_available(pool);
# else
size_t bytes_needed;
size_t entropy_available = 0;
unsigned char *buffer;
size_t entropy_available;
# if defined(OPENSSL_RAND_SEED_GETRANDOM)
{
size_t bytes_needed;
unsigned char *buffer;
ssize_t bytes;
/* Maximum allowed number of consecutive unsuccessful attempts */
int attempts = 3;
@@ -486,13 +592,16 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
# endif
# if defined(OPENSSL_RAND_SEED_DEVRANDOM)
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
{
if (wait_random_seeded()) {
size_t bytes_needed;
unsigned char *buffer;
size_t i;
for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths); i++) {
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths);
i++) {
ssize_t bytes = 0;
/* Maximum allowed number of consecutive unsuccessful attempts */
/* Maximum number of consecutive unsuccessful attempts */
int attempts = 3;
const int fd = get_random_device(i);
@@ -506,7 +615,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
if (bytes > 0) {
rand_pool_add_end(pool, bytes, 8 * bytes);
bytes_needed -= bytes;
attempts = 3; /* reset counter after successful attempt */
attempts = 3; /* reset counter on successful attempt */
} else if (bytes < 0 && errno != EINTR) {
break;
}
@@ -514,7 +623,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
if (bytes < 0 || !keep_random_devices_open)
close_random_device(i);
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
bytes_needed = rand_pool_bytes_needed(pool, 1);
}
entropy_available = rand_pool_entropy_available(pool);
if (entropy_available > 0)
@@ -535,26 +644,29 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
# endif
# if defined(OPENSSL_RAND_SEED_EGD)
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
if (bytes_needed > 0) {
{
static const char *paths[] = { DEVRANDOM_EGD, NULL };
size_t bytes_needed;
unsigned char *buffer;
int i;
for (i = 0; paths[i] != NULL; i++) {
buffer = rand_pool_add_begin(pool, bytes_needed);
if (buffer != NULL) {
size_t bytes = 0;
int num = RAND_query_egd_bytes(paths[i],
buffer, (int)bytes_needed);
if (num == (int)bytes_needed)
bytes = bytes_needed;
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
for (i = 0; bytes_needed > 0 && paths[i] != NULL; i++) {
size_t bytes = 0;
int num;
rand_pool_add_end(pool, bytes, 8 * bytes);
entropy_available = rand_pool_entropy_available(pool);
}
if (entropy_available > 0)
return entropy_available;
buffer = rand_pool_add_begin(pool, bytes_needed);
num = RAND_query_egd_bytes(paths[i],
buffer, (int)bytes_needed);
if (num == (int)bytes_needed)
bytes = bytes_needed;
rand_pool_add_end(pool, bytes, 8 * bytes);
bytes_needed = rand_pool_bytes_needed(pool, 1);
}
entropy_available = rand_pool_entropy_available(pool);
if (entropy_available > 0)
return entropy_available;
}
# endif
@@ -592,6 +704,7 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
int rand_pool_add_additional_data(RAND_POOL *pool)
{
struct {
int fork_id;
CRYPTO_THREAD_ID tid;
uint64_t time;
} data;
@@ -601,9 +714,11 @@ int rand_pool_add_additional_data(RAND_POOL *pool)
/*
* Add some noise from the thread id and a high resolution timer.
* The fork_id adds some extra fork-safety.
* The thread id adds a little randomness if the drbg is accessed
* concurrently (which is the case for the <master> drbg).
*/
data.fork_id = openssl_get_fork_id();
data.tid = CRYPTO_THREAD_get_current_id();
data.time = get_timer_bits();
+2 -1
View File
@@ -19,7 +19,8 @@
# include <windows.h>
/* On Windows Vista or higher use BCrypt instead of the legacy CryptoAPI */
# if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
# if defined(_MSC_VER) && _MSC_VER > 1500 /* 1500 = Visual Studio 2008 */ \
&& defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
# define USE_BCRYPTGENRANDOM
# endif