[openssl] OpenSSL_1_1_1-stable update

Dr. Paul Dale pauli at openssl.org
Wed Jul 24 22:30:40 UTC 2019


The branch OpenSSL_1_1_1-stable has been updated
       via  b4b42d441d350b48449ea93aaa035152123f70ae (commit)
      from  e8d866dcb170dbe22dcda418cd5df655f67dbc0b (commit)


- Log -----------------------------------------------------------------
commit b4b42d441d350b48449ea93aaa035152123f70ae
Author: Pauli <paul.dale at oracle.com>
Date:   Tue Jul 23 18:07:19 2019 +1000

    Make rand_pool buffers more dynamic in their sizing.
    
    The rand pool support allocates maximal sized buffers -- this is typically
    12288 bytes in size.  These pools are allocated in secure memory which is a
    scarse resource.  They are also allocated per DRBG of which there are up to two
    per thread.
    
    This change allocates 64 byte pools and grows them dynamically if required.
    64 is chosen to be sufficiently large so that pools do not normally need to
    grow.
    
    Reviewed-by: Bernd Edlinger <bernd.edlinger at hotmail.de>
    (Merged from https://github.com/openssl/openssl/pull/9428)
    
    (cherry picked from commit a6a66e4511eec0f4ecc2943117a42b3723eb2222)

-----------------------------------------------------------------------

Summary of changes:
 CHANGES                   |  3 +++
 crypto/err/openssl.txt    |  1 +
 crypto/rand/rand_err.c    |  3 ++-
 crypto/rand/rand_lcl.h    | 19 +++++++++++++++++++
 crypto/rand/rand_lib.c    | 48 ++++++++++++++++++++++++++++++++++++++++++-----
 include/openssl/randerr.h |  5 ++---
 6 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/CHANGES b/CHANGES
index 47ea8e0..de9c7c1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -15,6 +15,9 @@
      private key for those. This avoids leaking bit 0 of the private key.
      [Bernd Edlinger]
 
+  *) Significantly reduce secure memory usage by the randomness pools.
+     [Paul Dale]
+
   *) Revert the DEVRANDOM_WAIT feature for Linux systems
 
      The DEVRANDOM_WAIT feature added a select() call to wait for the
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 907eeaa..722a087 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -1025,6 +1025,7 @@ RAND_F_RAND_POOL_ADD_BEGIN:113:rand_pool_add_begin
 RAND_F_RAND_POOL_ADD_END:114:rand_pool_add_end
 RAND_F_RAND_POOL_ATTACH:124:rand_pool_attach
 RAND_F_RAND_POOL_BYTES_NEEDED:115:rand_pool_bytes_needed
+RAND_F_RAND_POOL_GROW:125:rand_pool_grow
 RAND_F_RAND_POOL_NEW:116:rand_pool_new
 RAND_F_RAND_WRITE_FILE:112:RAND_write_file
 RSA_F_CHECK_PADDING_MD:140:check_padding_md
diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c
index 6a87045..ae4d855 100644
--- a/crypto/rand/rand_err.c
+++ b/crypto/rand/rand_err.c
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -47,6 +47,7 @@ static const ERR_STRING_DATA RAND_str_functs[] = {
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ATTACH, 0), "rand_pool_attach"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_BYTES_NEEDED, 0),
      "rand_pool_bytes_needed"},
+    {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_GROW, 0), "rand_pool_grow"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_NEW, 0), "rand_pool_new"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_WRITE_FILE, 0), "RAND_write_file"},
     {0, NULL}
diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h
index a48e08a..148da84 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -72,6 +72,24 @@
  *                                1.5 * (RAND_DRBG_STRENGTH / 8))
  */
 
+/*
+ * Initial allocation minimum.
+ *
+ * There is a distinction between the secure and normal allocation minimums.
+ * Ideally, the secure allocation size should be a power of two.  The normal
+ * allocation size doesn't have any such restriction.
+ *
+ * The secure value is based on 128 bits of secure material, which is 16 bytes.
+ * Typically, the DRBGs will set a minimum larger than this so optimal
+ * allocation ought to take place (for full quality seed material).
+ *
+ * The normal value has been chosed by noticing that the rand_drbg_get_nonce
+ * function is usually the largest of the built in allocation (twenty four
+ * bytes and then appending another sixteen bytes).  This means the buffer ends
+ * with 40 bytes.  The value of forty eight is comfortably above this which
+ * allows some slack in the platform specific values used.
+ */
+# define RAND_POOL_MIN_ALLOCATION(secure) ((secure) ? 16 : 48)
 
 /* DRBG status values */
 typedef enum drbg_status_e {
@@ -154,6 +172,7 @@ struct rand_pool_st {
 
     size_t min_len; /* minimum number of random bytes requested */
     size_t max_len; /* maximum number of random bytes (allocated buffer size) */
+    size_t alloc_len; /* current number of bytes allocated */
     size_t entropy; /* current entropy count in bits */
     size_t entropy_requested; /* requested entropy count in bits */
 };
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index f658634..48da2b9 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -437,6 +437,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);
@@ -446,11 +447,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);
@@ -493,7 +497,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;
@@ -515,9 +519,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);
@@ -650,6 +654,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.
  *
@@ -673,6 +707,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;
@@ -708,6 +744,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;
 }
 
diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h
index d9aa9b3..70d1a17 100644
--- a/include/openssl/randerr.h
+++ b/include/openssl/randerr.h
@@ -11,9 +11,7 @@
 #ifndef HEADER_RANDERR_H
 # define HEADER_RANDERR_H
 
-# ifndef HEADER_SYMHACKS_H
-#  include <openssl/symhacks.h>
-# endif
+# include <openssl/symhacks.h>
 
 # ifdef  __cplusplus
 extern "C"
@@ -46,6 +44,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_F_RAND_POOL_ADD_END                         114
 # define RAND_F_RAND_POOL_ATTACH                          124
 # define RAND_F_RAND_POOL_BYTES_NEEDED                    115
+# define RAND_F_RAND_POOL_GROW                            125
 # define RAND_F_RAND_POOL_NEW                             116
 # define RAND_F_RAND_WRITE_FILE                           112
 


More information about the openssl-commits mailing list