return 0;
}
- if (drbg->pool != NULL) {
- pool = drbg->pool;
+ if (drbg->seed_pool != NULL) {
+ pool = drbg->seed_pool;
pool->entropy_requested = entropy;
} else {
pool = rand_pool_new(entropy, min_len, max_len);
prediction_resistance,
NULL, 0) != 0)
bytes = bytes_needed;
+ drbg->reseed_next_counter
+ = tsan_load(&drbg->parent->reseed_prop_counter);
rand_drbg_unlock(drbg->parent);
rand_pool_add_end(pool, bytes, 8 * bytes);
}
err:
- /* we need to reset drbg->pool in the error case */
- if (ret == 0 && drbg->pool != NULL)
- drbg->pool = NULL;
-
- rand_pool_free(pool);
+ if (drbg->seed_pool == NULL)
+ rand_pool_free(pool);
return ret;
}
void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
unsigned char *out, size_t outlen)
{
- if (drbg->pool == NULL)
+ if (drbg->seed_pool == NULL)
OPENSSL_secure_clear_free(out, outlen);
- else
- drbg->pool = NULL;
}
* On success it allocates a buffer at |*pout| and returns the length of
* the data. The buffer should get freed using OPENSSL_secure_clear_free().
*/
-size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len)
+size_t rand_drbg_get_additional_data(RAND_POOL *pool, unsigned char **pout)
{
size_t ret = 0;
- RAND_POOL *pool;
-
- pool = rand_pool_new(0, 0, max_len);
- if (pool == NULL)
- return 0;
if (rand_pool_add_additional_data(pool) == 0)
goto err;
*pout = rand_pool_detach(pool);
err:
- rand_pool_free(pool);
-
return ret;
}
-void rand_drbg_cleanup_additional_data(unsigned char *out, size_t outlen)
+void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out)
{
- OPENSSL_secure_clear_free(out, outlen);
+ rand_pool_reattach(pool, out);
}
void rand_fork(void)
/*
* 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().
+ * 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
return 0;
}
+ if (pool->buffer == NULL) {
+ RANDerr(RAND_F_RAND_POOL_ADD, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
if (len > 0) {
memcpy(pool->buffer + pool->len, buffer, len);
pool->len += len;
return NULL;
}
+ if (pool->buffer == NULL) {
+ RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
return pool->buffer + pool->len;
}