Latest update

This commit is contained in:
2018-11-01 00:59:10 +09:00
parent 95369e3f0a
commit 35dea6db7e
107 changed files with 4513 additions and 1163 deletions
+102 -39
View File
@@ -374,6 +374,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
max_entropylen += drbg->max_noncelen;
}
drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
if (drbg->reseed_next_counter) {
drbg->reseed_next_counter++;
if(!drbg->reseed_next_counter)
drbg->reseed_next_counter = 1;
}
if (drbg->get_entropy != NULL)
entropylen = drbg->get_entropy(drbg, &entropy, min_entropy,
min_entropylen, max_entropylen, 0);
@@ -401,27 +408,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
drbg->state = DRBG_READY;
drbg->reseed_gen_counter = 1;
drbg->reseed_time = time(NULL);
if (drbg->reseed_prop_counter > 0) {
if (drbg->parent == NULL)
drbg->reseed_prop_counter++;
else
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
}
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
end:
if (entropy != NULL && drbg->cleanup_entropy != NULL)
drbg->cleanup_entropy(drbg, entropy, entropylen);
if (nonce != NULL && drbg->cleanup_nonce != NULL)
drbg->cleanup_nonce(drbg, nonce, noncelen);
if (drbg->pool != NULL) {
if (drbg->state == DRBG_READY) {
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED);
drbg->state = DRBG_ERROR;
}
rand_pool_free(drbg->pool);
drbg->pool = NULL;
}
if (drbg->state == DRBG_READY)
return 1;
return 0;
@@ -498,6 +491,14 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
}
drbg->state = DRBG_ERROR;
drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
if (drbg->reseed_next_counter) {
drbg->reseed_next_counter++;
if(!drbg->reseed_next_counter)
drbg->reseed_next_counter = 1;
}
if (drbg->get_entropy != NULL)
entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
drbg->min_entropylen,
@@ -515,12 +516,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
drbg->state = DRBG_READY;
drbg->reseed_gen_counter = 1;
drbg->reseed_time = time(NULL);
if (drbg->reseed_prop_counter > 0) {
if (drbg->parent == NULL)
drbg->reseed_prop_counter++;
else
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
}
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
end:
if (entropy != NULL && drbg->cleanup_entropy != NULL)
@@ -625,14 +621,8 @@ int rand_drbg_restart(RAND_DRBG *drbg,
}
}
/* check whether a given entropy pool was cleared properly during reseed */
if (drbg->pool != NULL) {
drbg->state = DRBG_ERROR;
RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR);
rand_pool_free(drbg->pool);
drbg->pool = NULL;
return 0;
}
rand_pool_free(drbg->pool);
drbg->pool = NULL;
return drbg->state == DRBG_READY;
}
@@ -691,8 +681,11 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|| now - drbg->reseed_time >= drbg->reseed_time_interval)
reseed_required = 1;
}
if (drbg->reseed_prop_counter > 0 && drbg->parent != NULL) {
if (drbg->reseed_prop_counter != drbg->parent->reseed_prop_counter)
if (drbg->parent != NULL) {
unsigned int reseed_counter = tsan_load(&drbg->reseed_prop_counter);
if (reseed_counter > 0
&& tsan_load(&drbg->parent->reseed_prop_counter)
!= reseed_counter)
reseed_required = 1;
}
@@ -764,7 +757,8 @@ int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
RAND_DRBG_get_nonce_fn get_nonce,
RAND_DRBG_cleanup_nonce_fn cleanup_nonce)
{
if (drbg->state != DRBG_UNINITIALISED)
if (drbg->state != DRBG_UNINITIALISED
|| drbg->parent != NULL)
return 0;
drbg->get_entropy = get_entropy;
drbg->cleanup_entropy = cleanup_entropy;
@@ -942,7 +936,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type)
goto err;
/* enable seed propagation */
drbg->reseed_prop_counter = 1;
tsan_store(&drbg->reseed_prop_counter, 1);
/*
* Ignore instantiation error to support just-in-time instantiation.
@@ -1031,11 +1025,53 @@ static int drbg_bytes(unsigned char *out, int count)
return ret;
}
/*
* Calculates the minimum length of a full entropy buffer
* which is necessary to seed (i.e. instantiate) the DRBG
* successfully.
*
* NOTE: There is a copy of this function in drbgtest.c.
* If you change anything here, you need to update
* the copy accordingly.
*/
static size_t rand_drbg_seedlen(RAND_DRBG *drbg)
{
/*
* If no os entropy source is available then RAND_seed(buffer, bufsize)
* is expected to succeed if and only if the buffer length satisfies
* the following requirements, which follow from the calculations
* in RAND_DRBG_instantiate().
*/
size_t min_entropy = drbg->strength;
size_t min_entropylen = drbg->min_entropylen;
/*
* Extra entropy for the random nonce in the absence of a
* get_nonce callback, see comment in RAND_DRBG_instantiate().
*/
if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) {
min_entropy += drbg->strength / 2;
min_entropylen += drbg->min_noncelen;
}
/*
* Convert entropy requirement from bits to bytes
* (dividing by 8 without rounding upwards, because
* all entropy requirements are divisible by 8).
*/
min_entropy >>= 3;
/* Return a value that satisfies both requirements */
return min_entropy > min_entropylen ? min_entropy : min_entropylen;
}
/* Implements the default OpenSSL RAND_add() method */
static int drbg_add(const void *buf, int num, double randomness)
{
int ret = 0;
RAND_DRBG *drbg = RAND_DRBG_get0_master();
size_t buflen;
size_t seedlen;
if (drbg == NULL)
return 0;
@@ -1043,7 +1079,37 @@ static int drbg_add(const void *buf, int num, double randomness)
if (num < 0 || randomness < 0.0)
return 0;
if (randomness > (double)RAND_DRBG_STRENGTH) {
rand_drbg_lock(drbg);
seedlen = rand_drbg_seedlen(drbg);
buflen = (size_t)num;
if (buflen < seedlen || randomness < (double) seedlen) {
#if defined(OPENSSL_RAND_SEED_NONE)
/*
* If no os entropy source is available, a reseeding will fail
* inevitably. So we use a trick to mix the buffer contents into
* the DRBG state without forcing a reseeding: we generate a
* dummy random byte, using the buffer content as additional data.
* Note: This won't work with RAND_DRBG_FLAG_CTR_NO_DF.
*/
unsigned char dummy[1];
ret = RAND_DRBG_generate(drbg, dummy, sizeof(dummy), 0, buf, buflen);
rand_drbg_unlock(drbg);
return ret;
#else
/*
* If an os entropy source is avaible then we declare the buffer content
* as additional data by setting randomness to zero and trigger a regular
* reseeding.
*/
randomness = 0.0;
#endif
}
if (randomness > (double)seedlen) {
/*
* The purpose of this check is to bound |randomness| by a
* relatively small value in order to prevent an integer
@@ -1052,13 +1118,10 @@ static int drbg_add(const void *buf, int num, double randomness)
* not bits, so this value corresponds to eight times the
* security strength.
*/
randomness = (double)RAND_DRBG_STRENGTH;
randomness = (double)seedlen;
}
rand_drbg_lock(drbg);
ret = rand_drbg_restart(drbg, buf,
(size_t)(unsigned int)num,
(size_t)(8*randomness));
ret = rand_drbg_restart(drbg, buf, buflen, (size_t)(8 * randomness));
rand_drbg_unlock(drbg);
return ret;