Latest update

This commit is contained in:
2018-10-17 15:13:06 +09:00
parent aa5d30d379
commit 95369e3f0a
31 changed files with 256 additions and 140 deletions
+6 -6
View File
@@ -401,10 +401,10 @@ int drbg_ctr_init(RAND_DRBG *drbg)
if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
/* df initialisation */
static const unsigned char df_key[32] = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};
if (ctr->ctx_df == NULL)
@@ -416,9 +416,9 @@ int drbg_ctr_init(RAND_DRBG *drbg)
return 0;
drbg->min_entropylen = ctr->keylen;
drbg->max_entropylen = DRBG_MINMAX_FACTOR * drbg->min_entropylen;
drbg->max_entropylen = DRBG_MAX_LENGTH;
drbg->min_noncelen = drbg->min_entropylen / 2;
drbg->max_noncelen = DRBG_MINMAX_FACTOR * drbg->min_noncelen;
drbg->max_noncelen = DRBG_MAX_LENGTH;
drbg->max_perslen = DRBG_MAX_LENGTH;
drbg->max_adinlen = DRBG_MAX_LENGTH;
} else {
+2 -2
View File
@@ -332,10 +332,10 @@ int drbg_hash_init(RAND_DRBG *drbg)
drbg->seedlen = HASH_PRNG_SMALL_SEEDLEN;
drbg->min_entropylen = drbg->strength / 8;
drbg->max_entropylen = DRBG_MINMAX_FACTOR * drbg->min_entropylen;
drbg->max_entropylen = DRBG_MAX_LENGTH;
drbg->min_noncelen = drbg->min_entropylen / 2;
drbg->max_noncelen = DRBG_MINMAX_FACTOR * drbg->min_noncelen;
drbg->max_noncelen = DRBG_MAX_LENGTH;
drbg->max_perslen = DRBG_MAX_LENGTH;
drbg->max_adinlen = DRBG_MAX_LENGTH;
+2 -2
View File
@@ -223,10 +223,10 @@ int drbg_hmac_init(RAND_DRBG *drbg)
drbg->seedlen = hmac->blocklen;
drbg->min_entropylen = drbg->strength / 8;
drbg->max_entropylen = DRBG_MINMAX_FACTOR * drbg->min_entropylen;
drbg->max_entropylen = DRBG_MAX_LENGTH;
drbg->min_noncelen = drbg->min_entropylen / 2;
drbg->max_noncelen = DRBG_MINMAX_FACTOR * drbg->min_noncelen;
drbg->max_noncelen = DRBG_MAX_LENGTH;
drbg->max_perslen = DRBG_MAX_LENGTH;
drbg->max_adinlen = DRBG_MAX_LENGTH;
+17 -12
View File
@@ -286,7 +286,7 @@ static RAND_DRBG *rand_drbg_new(int secure,
return drbg;
err:
err:
if (drbg->secure)
OPENSSL_secure_free(drbg);
else
@@ -378,7 +378,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
entropylen = drbg->get_entropy(drbg, &entropy, min_entropy,
min_entropylen, max_entropylen, 0);
if (entropylen < min_entropylen
|| entropylen > max_entropylen) {
|| entropylen > max_entropylen) {
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_RETRIEVING_ENTROPY);
goto end;
}
@@ -408,10 +408,10 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
}
end:
end:
if (entropy != NULL && drbg->cleanup_entropy != NULL)
drbg->cleanup_entropy(drbg, entropy, entropylen);
if (nonce != NULL && drbg->cleanup_nonce!= NULL )
if (nonce != NULL && drbg->cleanup_nonce != NULL)
drbg->cleanup_nonce(drbg, nonce, noncelen);
if (drbg->pool != NULL) {
if (drbg->state == DRBG_READY) {
@@ -504,7 +504,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
drbg->max_entropylen,
prediction_resistance);
if (entropylen < drbg->min_entropylen
|| entropylen > drbg->max_entropylen) {
|| entropylen > drbg->max_entropylen) {
RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ERROR_RETRIEVING_ENTROPY);
goto end;
}
@@ -522,7 +522,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
}
end:
end:
if (entropy != NULL && drbg->cleanup_entropy != NULL)
drbg->cleanup_entropy(drbg, entropy, entropylen);
if (drbg->state == DRBG_READY)
@@ -556,8 +556,10 @@ int rand_drbg_restart(RAND_DRBG *drbg,
if (drbg->pool != NULL) {
RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR);
drbg->state = DRBG_ERROR;
rand_pool_free(drbg->pool);
drbg->pool = NULL;
return 0;
}
if (buffer != NULL) {
@@ -565,24 +567,25 @@ int rand_drbg_restart(RAND_DRBG *drbg,
if (drbg->max_entropylen < len) {
RANDerr(RAND_F_RAND_DRBG_RESTART,
RAND_R_ENTROPY_INPUT_TOO_LONG);
drbg->state = DRBG_ERROR;
return 0;
}
if (entropy > 8 * len) {
RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_ENTROPY_OUT_OF_RANGE);
drbg->state = DRBG_ERROR;
return 0;
}
/* will be picked up by the rand_drbg_get_entropy() callback */
drbg->pool = rand_pool_new(entropy, len, len);
drbg->pool = rand_pool_attach(buffer, len, entropy);
if (drbg->pool == NULL)
return 0;
rand_pool_add(drbg->pool, buffer, len, entropy);
} else {
if (drbg->max_adinlen < len) {
RANDerr(RAND_F_RAND_DRBG_RESTART,
RAND_R_ADDITIONAL_INPUT_TOO_LONG);
drbg->state = DRBG_ERROR;
return 0;
}
adin = buffer;
@@ -1040,14 +1043,16 @@ static int drbg_add(const void *buf, int num, double randomness)
if (num < 0 || randomness < 0.0)
return 0;
if (randomness > (double)drbg->max_entropylen) {
if (randomness > (double)RAND_DRBG_STRENGTH) {
/*
* The purpose of this check is to bound |randomness| by a
* relatively small value in order to prevent an integer
* overflow when multiplying by 8 in the rand_drbg_restart()
* call below.
* call below. Note that randomness is measured in bytes,
* not bits, so this value corresponds to eight times the
* security strength.
*/
return 0;
randomness = (double)RAND_DRBG_STRENGTH;
}
rand_drbg_lock(drbg);
+1
View File
@@ -44,6 +44,7 @@ static const ERR_STRING_DATA RAND_str_functs[] = {
{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"},
+36 -10
View File
@@ -32,18 +32,42 @@
/* Max size of additional input and personalization string. */
# define DRBG_MAX_LENGTH 4096
/*
* Maximum input size for the DRBG (entropy, nonce, personalization string)
*
* NIST SP800 90Ar1 allows a maximum of (1 << 35) bits i.e., (1 << 32) bytes.
*
* We lower it to 'only' INT32_MAX bytes, which is equivalent to 2 gigabytes.
*/
# define DRBG_MAX_LENGTH INT32_MAX
/*
* The quotient between max_{entropy,nonce}len and min_{entropy,nonce}len
* Maximum allocation size for RANDOM_POOL buffers
*
* The current factor is large enough that the RAND_POOL can store a
* random input which has a lousy entropy rate of 0.0625 bits per byte.
* This input will be sent through the derivation function which 'compresses'
* the low quality input into a high quality output.
* 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))
*/
# define DRBG_MINMAX_FACTOR 128
/* DRBG status values */
@@ -142,10 +166,12 @@ 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 */
size_t min_len; /* minimum number of random bytes requested */
size_t max_len; /* maximum number of random bytes (allocated buffer size) */
size_t entropy; /* current entropy count in bits */
size_t requested_entropy; /* requested entropy count in bits */
size_t entropy_requested; /* requested entropy count in bits */
};
/*
@@ -167,7 +193,7 @@ struct rand_drbg_st {
unsigned short flags; /* various external flags */
/*
* The random pool is used by RAND_add()/drbg_add() to attach random
* 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
+58 -21
View File
@@ -146,17 +146,11 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
return 0;
}
pool = rand_pool_new(entropy, min_len, max_len);
if (pool == NULL)
return 0;
if (drbg->pool) {
rand_pool_add(pool,
rand_pool_buffer(drbg->pool),
rand_pool_length(drbg->pool),
rand_pool_entropy(drbg->pool));
rand_pool_free(drbg->pool);
drbg->pool = NULL;
if (drbg->pool != NULL) {
pool = drbg->pool;
pool->entropy_requested = entropy;
} else {
pool = rand_pool_new(entropy, min_len, max_len);
}
if (drbg->parent) {
@@ -217,7 +211,10 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
unsigned char *out, size_t outlen)
{
OPENSSL_secure_clear_free(out, outlen);
if (drbg->pool == NULL)
OPENSSL_secure_clear_free(out, outlen);
else
drbg->pool = NULL;
}
@@ -405,7 +402,7 @@ int RAND_poll(void)
/* fill random pool and seed the current legacy RNG */
pool = rand_pool_new(RAND_DRBG_STRENGTH,
RAND_DRBG_STRENGTH / 8,
DRBG_MINMAX_FACTOR * (RAND_DRBG_STRENGTH / 8));
RAND_POOL_MAX_LENGTH);
if (pool == NULL)
return 0;
@@ -430,17 +427,18 @@ err:
* Allocate memory and initialize a new random pool
*/
RAND_POOL *rand_pool_new(int entropy, size_t min_len, size_t max_len)
RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len)
{
RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool));
if (pool == NULL) {
RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
goto err;
return NULL;
}
pool->min_len = min_len;
pool->max_len = max_len;
pool->max_len = (max_len > RAND_POOL_MAX_LENGTH) ?
RAND_POOL_MAX_LENGTH : max_len;
pool->buffer = OPENSSL_secure_zalloc(pool->max_len);
if (pool->buffer == NULL) {
@@ -448,7 +446,7 @@ RAND_POOL *rand_pool_new(int entropy, size_t min_len, size_t max_len)
goto err;
}
pool->requested_entropy = entropy;
pool->entropy_requested = entropy_requested;
return pool;
@@ -457,6 +455,38 @@ err:
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->len;
pool->entropy = entropy;
return pool;
}
/*
* Free |pool|, securely erasing its buffer.
*/
@@ -465,7 +495,14 @@ void rand_pool_free(RAND_POOL *pool)
if (pool == NULL)
return;
OPENSSL_secure_clear_free(pool->buffer, pool->max_len);
/*
* 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)
OPENSSL_secure_clear_free(pool->buffer, pool->max_len);
OPENSSL_free(pool);
}
@@ -524,7 +561,7 @@ unsigned char *rand_pool_detach(RAND_POOL *pool)
*/
size_t rand_pool_entropy_available(RAND_POOL *pool)
{
if (pool->entropy < pool->requested_entropy)
if (pool->entropy < pool->entropy_requested)
return 0;
if (pool->len < pool->min_len)
@@ -540,8 +577,8 @@ size_t rand_pool_entropy_available(RAND_POOL *pool)
size_t rand_pool_entropy_needed(RAND_POOL *pool)
{
if (pool->entropy < pool->requested_entropy)
return pool->requested_entropy - pool->entropy;
if (pool->entropy < pool->entropy_requested)
return pool->entropy_requested - pool->entropy;
return 0;
}
+23 -16
View File
@@ -77,6 +77,17 @@ static uint64_t get_timer_bits(void);
# endif
#endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */
#if defined(OPENSSL_RAND_SEED_NONE)
/* none means none. this simplifies the following logic */
# undef OPENSSL_RAND_SEED_OS
# undef OPENSSL_RAND_SEED_GETRANDOM
# undef OPENSSL_RAND_SEED_LIBRANDOM
# undef OPENSSL_RAND_SEED_DEVRANDOM
# undef OPENSSL_RAND_SEED_RDTSC
# undef OPENSSL_RAND_SEED_RDCPU
# undef OPENSSL_RAND_SEED_EGD
#endif
#if (defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)) && \
!defined(OPENSSL_RAND_SEED_NONE)
# error "UEFI and VXWorks only support seeding NONE"
@@ -86,8 +97,6 @@ static uint64_t get_timer_bits(void);
|| defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VXWORKS) \
|| defined(OPENSSL_SYS_UEFI))
static ssize_t syscall_random(void *buf, size_t buflen);
# if defined(OPENSSL_SYS_VOS)
# ifndef OPENSSL_RAND_SEED_OS
@@ -244,6 +253,7 @@ static ssize_t sysctl_random(char *buf, size_t buflen)
}
# endif
# if defined(OPENSSL_RAND_SEED_GETRANDOM)
/*
* syscall_random(): Try to get random data using a system call
* returns the number of bytes returned in buf, or < 0 on error.
@@ -254,7 +264,7 @@ static ssize_t syscall_random(void *buf, size_t buflen)
* Note: 'buflen' equals the size of the buffer which is used by the
* get_entropy() callback of the RAND_DRBG. It is roughly bounded by
*
* 2 * DRBG_MINMAX_FACTOR * (RAND_DRBG_STRENGTH / 8) = 2^13
* 2 * RAND_POOL_FACTOR * (RAND_DRBG_STRENGTH / 8) = 2^14
*
* which is way below the OSSL_SSIZE_MAX limit. Therefore sign conversion
* between size_t and ssize_t is safe even without a range check.
@@ -302,8 +312,9 @@ static ssize_t syscall_random(void *buf, size_t buflen)
return -1;
# endif
}
# endif /* defined(OPENSSL_RAND_SEED_GETRANDOM) */
#if !defined(OPENSSL_RAND_SEED_NONE) && defined(OPENSSL_RAND_SEED_DEVRANDOM)
# if defined(OPENSSL_RAND_SEED_DEVRANDOM)
static const char *random_device_paths[] = { DEVRANDOM };
static struct random_device {
int fd;
@@ -410,9 +421,7 @@ void rand_pool_keep_random_devices_open(int keep)
keep_random_devices_open = keep;
}
# else /* defined(OPENSSL_RAND_SEED_NONE)
* || !defined(OPENSSL_RAND_SEED_DEVRANDOM)
*/
# else /* !defined(OPENSSL_RAND_SEED_DEVRANDOM) */
int rand_pool_init(void)
{
@@ -427,9 +436,7 @@ void rand_pool_keep_random_devices_open(int keep)
{
}
# endif /* !defined(OPENSSL_RAND_SEED_NONE)
* && defined(OPENSSL_RAND_SEED_DEVRANDOM)
*/
# endif /* defined(OPENSSL_RAND_SEED_DEVRANDOM) */
/*
* Try the various seeding methods in turn, exit when successful.
@@ -450,14 +457,14 @@ void rand_pool_keep_random_devices_open(int keep)
*/
size_t rand_pool_acquire_entropy(RAND_POOL *pool)
{
# ifdef OPENSSL_RAND_SEED_NONE
# 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;
# ifdef OPENSSL_RAND_SEED_GETRANDOM
# if defined(OPENSSL_RAND_SEED_GETRANDOM)
{
ssize_t bytes;
/* Maximum allowed number of consecutive unsuccessful attempts */
@@ -487,7 +494,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
}
# endif
# ifdef OPENSSL_RAND_SEED_DEVRANDOM
# if defined(OPENSSL_RAND_SEED_DEVRANDOM)
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
{
size_t i;
@@ -524,19 +531,19 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
}
# endif
# ifdef OPENSSL_RAND_SEED_RDTSC
# if defined(OPENSSL_RAND_SEED_RDTSC)
entropy_available = rand_acquire_entropy_from_tsc(pool);
if (entropy_available > 0)
return entropy_available;
# endif
# ifdef OPENSSL_RAND_SEED_RDCPU
# if defined(OPENSSL_RAND_SEED_RDCPU)
entropy_available = rand_acquire_entropy_from_cpu(pool);
if (entropy_available > 0)
return entropy_available;
# endif
# ifdef OPENSSL_RAND_SEED_EGD
# 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 };
+2 -2
View File
@@ -67,7 +67,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
if (buffer != NULL) {
size_t bytes = 0;
if (BCryptGenRandom(NULL, buffer, bytes_needed,
BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS)
BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS)
bytes = bytes_needed;
rand_pool_add_end(pool, bytes, 8 * bytes);
@@ -82,7 +82,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
size_t bytes = 0;
/* poll the CryptoAPI PRNG */
if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) {
CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) {
if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0)
bytes = bytes_needed;