api: Add GCRYCTL_AUTO_EXPAND_SECMEM.
authorWerner Koch <wk@gnupg.org>
Thu, 23 Nov 2017 18:15:41 +0000 (19:15 +0100)
committerWerner Koch <wk@gnupg.org>
Fri, 24 Nov 2017 09:10:18 +0000 (10:10 +0100)
* src/gcrypt.h.in (GCRYCTL_AUTO_EXPAND_SECMEM): New enum.
* src/global.c (_gcry_vcontrol): Implement that.
* src/secmem.c (auto_expand): New var.
(_gcry_secmem_set_auto_expand): New.
(_gcry_secmem_malloc_internal): Act upon AUTO_EXPAND.
--

GnuPG-bug-id: 3530
Signed-off-by: Werner Koch <wk@gnupg.org>
NEWS
doc/gcrypt.texi
src/gcrypt.h.in
src/global.c
src/secmem.c
src/secmem.h

diff --git a/NEWS b/NEWS
index 3b49350..8049d7d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ Noteworthy changes in version 1.9.0 (unreleased)  [C22/A3/R0]
  * Interface changes relative to the 1.8.0 release:
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    gcry_mpi_get_ui                 NEW function.
+   GCRYCTL_AUTO_EXPAND_SECMEM      NEW control code.
 
 
 Noteworthy changes in version 1.8.1 (2017-08-27)  [C22/A2/R1]
index dd24469..7831505 100644 (file)
@@ -425,7 +425,7 @@ and freed memory, you need to initialize Libgcrypt this way:
   /* Allocate a pool of 16k secure memory.  This makes the secure memory
      available and also drops privileges where needed.  Note that by
      using functions like gcry_xmalloc_secure and gcry_mpi_snew Libgcrypt
-     may extend the secure memory pool with memory which lacks the
+     may expand the secure memory pool with memory which lacks the
      property of not being swapped out to disk.   */
   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
 
@@ -672,7 +672,7 @@ This command disables the use of the mlock call for secure memory.
 Disabling the use of mlock may for example be done if an encrypted
 swap space is in use.  This command should be executed right after
 @code{gcry_check_version}.  Note that by using functions like
-gcry_xmalloc_secure and gcry_mpi_snew Libgcrypt may extend the secure
+gcry_xmalloc_secure and gcry_mpi_snew Libgcrypt may expand the secure
 memory pool with memory which lacks the property of not being swapped
 out to disk (but will still be zeroed out on free).
 
@@ -688,7 +688,7 @@ code should drop these extra privileges as soon as possible.  If this
 command has been used the caller is responsible for dropping the
 privileges.
 
-@item GCRYCTL_INIT_SECMEM; Arguments: int nbytes
+@item GCRYCTL_INIT_SECMEM; Arguments: unsigned int nbytes
 This command is used to allocate a pool of secure memory and thus
 enabling the use of secure memory.  It also drops all extra privileges
 the process has (i.e. if it is run as setuid (root)).  If the argument
@@ -696,6 +696,17 @@ the process has (i.e. if it is run as setuid (root)).  If the argument
 of secure memory allocated is currently 16384 bytes; you may thus use a
 value of 1 to request that default size.
 
+@item GCRYCTL_AUTO_EXPAND_SECMEM; Arguments: unsigned int chunksize
+This command enables on-the-fly expanding of the secure memory area.
+Note that by using functions like @code{gcry_xmalloc_secure} and
+@code{gcry_mpi_snew} will do this auto expanding anyway.  The argument
+to this option is the suggested size for new secure memory areas.  A
+larger size improves performance of all memory allocation and
+releasing functions.  The given chunksize is rounded up to the next
+32KiB.  The drawback of auto expanding is that memory might be swapped
+out to disk; this can be fixed by configuring the system to use an
+encrypted swap space.
+
 @item GCRYCTL_TERM_SECMEM; Arguments: none
 This command zeroises the secure memory and destroys the handler.  The
 secure memory pool may not be used anymore after running this command.
index b55657f..1eb3d7c 100644 (file)
@@ -332,7 +332,8 @@ enum gcry_ctl_cmds
     GCRYCTL_DRBG_REINIT = 74,
     GCRYCTL_SET_TAGLEN = 75,
     GCRYCTL_GET_TAGLEN = 76,
-    GCRYCTL_REINIT_SYSCALL_CLAMP = 77
+    GCRYCTL_REINIT_SYSCALL_CLAMP = 77,
+    GCRYCTL_AUTO_EXPAND_SECMEM = 78
   };
 
 /* Perform various operations defined by CMD. */
index ad9ab1d..6c2486c 100644 (file)
@@ -531,6 +531,10 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
                               & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING));
       break;
 
+    case GCRYCTL_AUTO_EXPAND_SECMEM:
+      _gcry_secmem_set_auto_expand (va_arg (arg_ptr, unsigned int));
+      break;
+
     case GCRYCTL_USE_SECURE_RNDPOOL:
       global_init ();
       _gcry_secure_random_alloc (); /* Put random number into secure memory. */
index f7ad1f6..79c135f 100644 (file)
@@ -91,7 +91,7 @@ typedef struct pooldesc_s
 static pooldesc_t mainpool;
 
 
-/* A couple of flags whith some being set early. */
+/* A couple of flags with some being set early.  */
 static int disable_secmem;
 static int show_warning;
 static int not_locked;
@@ -99,6 +99,8 @@ static int no_warning;
 static int suspend_warning;
 static int no_mlock;
 static int no_priv_drop;
+static unsigned int auto_expand;
+
 
 /* Lock protecting accesses to the memory pools.  */
 GPGRT_LOCK_DEFINE (secmem_lock);
@@ -458,6 +460,24 @@ init_pool (pooldesc_t *pool, size_t n)
   mb->flags = 0;
 }
 
+
+/* Enable overflow pool allocation in all cases.  CHUNKSIZE is a hint
+ * on how large to allocate overflow pools.  */
+void
+_gcry_secmem_set_auto_expand (unsigned int chunksize)
+{
+  /* Round up to a multiple of the STANDARD_POOL_SIZE.  */
+  chunksize = ((chunksize + (2*STANDARD_POOL_SIZE) - 1)
+               / STANDARD_POOL_SIZE ) * STANDARD_POOL_SIZE;
+  if (chunksize < STANDARD_POOL_SIZE) /* In case of overflow.  */
+    chunksize = STANDARD_POOL_SIZE;
+
+  SECMEM_LOCK;
+  auto_expand = chunksize;
+  SECMEM_UNLOCK;
+}
+
+
 void
 _gcry_secmem_set_flags (unsigned flags)
 {
@@ -617,7 +637,7 @@ _gcry_secmem_malloc_internal (size_t size, int xhint)
   /* If we are called from xmalloc style function resort to the
    * overflow pools to return memory.  We don't do this in FIPS mode,
    * though. */
-  if (xhint && !fips_mode ())
+  if ((xhint || auto_expand) && !fips_mode ())
     {
       for (pool = pool->next; pool; pool = pool->next)
         {
@@ -635,7 +655,7 @@ _gcry_secmem_malloc_internal (size_t size, int xhint)
       pool = calloc (1, sizeof *pool);
       if (!pool)
         return NULL;  /* Not enough memory for a new pool descriptor.  */
-      pool->size = STANDARD_POOL_SIZE;
+      pool->size = auto_expand? auto_expand : STANDARD_POOL_SIZE;
       pool->mem = malloc (pool->size);
       if (!pool->mem)
         return NULL; /* Not enough memory available for a new pool.  */
index 29dd64f..8ad6ef1 100644 (file)
@@ -27,6 +27,7 @@ void *_gcry_secmem_malloc (size_t size, int xhint) _GCRY_GCC_ATTR_MALLOC;
 void *_gcry_secmem_realloc (void *a, size_t newsize, int xhint);
 int  _gcry_secmem_free (void *a);
 void _gcry_secmem_dump_stats (int extended);
+void _gcry_secmem_set_auto_expand (unsigned int chunksize);
 void _gcry_secmem_set_flags (unsigned flags);
 unsigned _gcry_secmem_get_flags(void);
 int _gcry_private_is_secure (const void *p);