|
@@ -368,6 +368,7 @@ 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);
|
|
@@ -377,11 +378,14 @@ RAND_POOL *rand_pool_new(int entropy_requested, int secure,
|
|
|
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->max_len);
|
|
|
+ pool->buffer = OPENSSL_secure_zalloc(pool->alloc_len);
|
|
|
else
|
|
|
- pool->buffer = OPENSSL_zalloc(pool->max_len);
|
|
|
+ pool->buffer = OPENSSL_zalloc(pool->alloc_len);
|
|
|
|
|
|
if (pool->buffer == NULL) {
|
|
|
RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
|
|
@@ -424,7 +428,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;
|
|
@@ -446,9 +450,9 @@ void rand_pool_free(RAND_POOL *pool)
|
|
|
*/
|
|
|
if (!pool->attached) {
|
|
|
if (pool->secure)
|
|
|
- OPENSSL_secure_clear_free(pool->buffer, pool->max_len);
|
|
|
+ OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len);
|
|
|
else
|
|
|
- OPENSSL_clear_free(pool->buffer, pool->max_len);
|
|
|
+ OPENSSL_clear_free(pool->buffer, pool->alloc_len);
|
|
|
}
|
|
|
|
|
|
OPENSSL_free(pool);
|
|
@@ -581,6 +585,36 @@ size_t rand_pool_bytes_remaining(RAND_POOL *pool)
|
|
|
return pool->max_len - pool->len;
|
|
|
}
|
|
|
|
|
|
+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;
|
|
|
+
|
|
|
+ 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;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Add random bytes to the random pool.
|
|
|
*
|
|
@@ -604,6 +638,8 @@ int rand_pool_add(RAND_POOL *pool,
|
|
|
}
|
|
|
|
|
|
if (len > 0) {
|
|
|
+ if (!rand_pool_grow(pool, len))
|
|
|
+ return 0;
|
|
|
memcpy(pool->buffer + pool->len, buffer, len);
|
|
|
pool->len += len;
|
|
|
pool->entropy += entropy;
|
|
@@ -639,6 +675,8 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+ if (!rand_pool_grow(pool, len))
|
|
|
+ return NULL;
|
|
|
return pool->buffer + pool->len;
|
|
|
}
|
|
|
|