summaryrefslogtreecommitdiffstats
path: root/crypto/rand/drbg_lib.c
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2018-10-27 11:31:21 +0200
committerPauli <paul.dale@oracle.com>2018-11-01 09:02:12 +1000
commit54f3e855d48d08e9623a7ced715e263352c95274 (patch)
treed074f87192a16ffecc040d998f59a95ef0541aa9 /crypto/rand/drbg_lib.c
parentb6e660754c2e799cffe4906269fcace0e07c73bc (diff)
Avoid two memory allocations in each RAND_DRBG_bytes
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com> Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/7507)
Diffstat (limited to 'crypto/rand/drbg_lib.c')
-rw-r--r--crypto/rand/drbg_lib.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index c4ecf0c97e..8e372e593e 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -158,8 +158,10 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
}
/* If set is called multiple times - clear the old one */
- if (type != drbg->type && drbg->type != 0 && drbg->meth != NULL) {
+ if (drbg->type != 0 && (type != drbg->type || flags != drbg->flags)) {
drbg->meth->uninstantiate(drbg);
+ rand_pool_free(drbg->adin_pool);
+ drbg->adin_pool = NULL;
}
drbg->state = DRBG_UNINITIALISED;
@@ -168,6 +170,7 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
if (type == 0) {
/* Uninitialized; that's okay. */
+ drbg->meth = NULL;
return 1;
} else if (is_ctr(type)) {
ret = drbg_ctr_init(drbg);
@@ -315,6 +318,7 @@ void RAND_DRBG_free(RAND_DRBG *drbg)
if (drbg->meth != NULL)
drbg->meth->uninstantiate(drbg);
+ rand_pool_free(drbg->adin_pool);
CRYPTO_THREAD_lock_free(drbg->lock);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
@@ -722,9 +726,18 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
unsigned char *additional = NULL;
size_t additional_len;
size_t chunk;
- size_t ret;
+ size_t ret = 0;
- additional_len = rand_drbg_get_additional_data(&additional, drbg->max_adinlen);
+ if (drbg->adin_pool == NULL) {
+ if (drbg->type == 0)
+ goto err;
+ drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen);
+ if (drbg->adin_pool == NULL)
+ goto err;
+ }
+
+ additional_len = rand_drbg_get_additional_data(drbg->adin_pool,
+ &additional);
for ( ; outlen > 0; outlen -= chunk, out += chunk) {
chunk = outlen;
@@ -736,9 +749,9 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
}
ret = 1;
-err:
- if (additional_len != 0)
- OPENSSL_secure_clear_free(additional, additional_len);
+ err:
+ if (additional != NULL)
+ rand_drbg_cleanup_additional_data(drbg->adin_pool, additional);
return ret;
}