Allocate DRBG additional data pool from non-secure memory
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Sat, 20 Jul 2019 09:22:46 +0000 (11:22 +0200)
committerBernd Edlinger <bernd.edlinger@hotmail.de>
Mon, 22 Jul 2019 11:37:13 +0000 (13:37 +0200)
The additional data allocates 12K per DRBG instance in the
secure memory, which is not necessary. Also nonces are not
considered secret.

[extended tests]

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/9423)

crypto/include/internal/rand_int.h
crypto/rand/drbg_lib.c
crypto/rand/rand_crng_test.c
crypto/rand/rand_lcl.h
crypto/rand/rand_lib.c

index d964a1d4070a3050afb3d91750f04715716e310f..c5d0c20551bee1427e4e5515d38ca01f7b23eedb 100644 (file)
@@ -58,7 +58,8 @@ void rand_crngt_cleanup_entropy(RAND_DRBG *drbg,
 /*
  * RAND_POOL functions
  */
-RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len);
+RAND_POOL *rand_pool_new(int entropy_requested, int secure,
+                         size_t min_len, size_t max_len);
 RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len,
                             size_t entropy);
 void rand_pool_free(RAND_POOL *pool);
index c1b9b3b2510846520bdc2da316b4dec3102d6bcb..825e90d48e184686828cf0b2c4758e4c55c19948 100644 (file)
@@ -265,7 +265,7 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
         return 0;
 
     memset(&data, 0, sizeof(data));
-    pool = rand_pool_new(0, min_len, max_len);
+    pool = rand_pool_new(0, 0, min_len, max_len);
     if (pool == NULL)
         return 0;
 
@@ -295,7 +295,7 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
 void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
                              unsigned char *out, size_t outlen)
 {
-    OPENSSL_secure_clear_free(out, outlen);
+    OPENSSL_clear_free(out, outlen);
 }
 
 /*
@@ -909,7 +909,7 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
     if (drbg->adin_pool == NULL) {
         if (drbg->type == 0)
             goto err;
-        drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen);
+        drbg->adin_pool = rand_pool_new(0, 0, 0, drbg->max_adinlen);
         if (drbg->adin_pool == NULL)
             goto err;
     }
index 44e077e0ac0a3c33832b576619676278b0343d44..a014f936fa1924ac161f111556a975c23efb937c 100644 (file)
@@ -45,7 +45,7 @@ static void *rand_crng_ossl_ctx_new(OPENSSL_CTX *ctx)
         return NULL;
 
     if ((crngt_glob->crngt_pool
-         = rand_pool_new(0, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL) {
+         = rand_pool_new(0, 1, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL) {
         OPENSSL_free(crngt_glob);
         return NULL;
     }
@@ -110,7 +110,7 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
     if (crngt_glob == NULL)
         return 0;
 
-    if ((pool = rand_pool_new(entropy, min_len, max_len)) == NULL)
+    if ((pool = rand_pool_new(entropy, 1, min_len, max_len)) == NULL)
         return 0;
 
     while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
index 416237ace7f190e1c83aa30dc3d5804d5b6c3887..1a77c89a5526bb2f1acb657c937bcdea60aebc02 100644 (file)
@@ -180,6 +180,7 @@ struct rand_pool_st {
     size_t len; /* current number of random bytes contained in the pool */
 
     int attached;  /* true pool was attached to existing buffer */
+    int secure;    /* 1: allocated on the secure heap, 0: otherwise */
 
     size_t min_len; /* minimum number of random bytes requested */
     size_t max_len; /* maximum number of random bytes (allocated buffer size) */
index 7768ade8b7dfa42ab5a7931ffca0e9b7ae1d47c8..9c99cc9003dbe61153a6dff468ca654d15f94413 100644 (file)
@@ -149,7 +149,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
         pool = drbg->seed_pool;
         pool->entropy_requested = entropy;
     } else {
-        pool = rand_pool_new(entropy, min_len, max_len);
+        pool = rand_pool_new(entropy, drbg->secure, min_len, max_len);
         if (pool == NULL)
             return 0;
     }
@@ -203,8 +203,12 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
 void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
                                unsigned char *out, size_t outlen)
 {
-    if (drbg->seed_pool == NULL)
-        OPENSSL_secure_clear_free(out, outlen);
+    if (drbg->seed_pool == NULL) {
+        if (drbg->secure)
+            OPENSSL_secure_clear_free(out, outlen);
+        else
+            OPENSSL_clear_free(out, outlen);
+    }
 }
 
 /*
@@ -331,7 +335,7 @@ int RAND_poll(void)
         RAND_POOL *pool = NULL;
 
         /* fill random pool and seed the current legacy RNG */
-        pool = rand_pool_new(RAND_DRBG_STRENGTH,
+        pool = rand_pool_new(RAND_DRBG_STRENGTH, 1,
                              (RAND_DRBG_STRENGTH + 7) / 8,
                              RAND_POOL_MAX_LENGTH);
         if (pool == NULL)
@@ -360,7 +364,8 @@ int RAND_poll(void)
  * Allocate memory and initialize a new random pool
  */
 
-RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len)
+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));
 
@@ -373,13 +378,18 @@ RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t 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 (secure)
+        pool->buffer = OPENSSL_secure_zalloc(pool->max_len);
+    else
+        pool->buffer = OPENSSL_zalloc(pool->max_len);
+
     if (pool->buffer == NULL) {
         RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     pool->entropy_requested = entropy_requested;
+    pool->secure = secure;
 
     return pool;
 
@@ -434,8 +444,13 @@ void rand_pool_free(RAND_POOL *pool)
      * 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);
+    if (!pool->attached) {
+        if (pool->secure)
+            OPENSSL_secure_clear_free(pool->buffer, pool->max_len);
+        else
+            OPENSSL_clear_free(pool->buffer, pool->max_len);
+    }
+
     OPENSSL_free(pool);
 }