summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2017-11-23 19:15:41 +0100
committerWerner Koch <wk@gnupg.org>2017-11-24 10:10:18 +0100
commit1f6b2f6099ebcfd785e2d2ae0aeca810394dbbac (patch)
tree3682f438908521e87b1bdf5c6bc5b2add2dc85ab
parent0abd1031bc0d889f21ddbf4ced8764d2191075fe (diff)
downloadlibgcrypt-1f6b2f6099ebcfd785e2d2ae0aeca810394dbbac.tar.gz
api: Add GCRYCTL_AUTO_EXPAND_SECMEM.
* 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>
-rw-r--r--NEWS1
-rw-r--r--doc/gcrypt.texi17
-rw-r--r--src/gcrypt.h.in3
-rw-r--r--src/global.c4
-rw-r--r--src/secmem.c26
-rw-r--r--src/secmem.h1
6 files changed, 45 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 3b49350b..8049d7d1 100644
--- 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]
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index dd244691..78315052 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -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.
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index b55657f5..1eb3d7c0 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -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. */
diff --git a/src/global.c b/src/global.c
index ad9ab1df..6c2486c4 100644
--- a/src/global.c
+++ b/src/global.c
@@ -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. */
diff --git a/src/secmem.c b/src/secmem.c
index f7ad1f66..79c135ff 100644
--- a/src/secmem.c
+++ b/src/secmem.c
@@ -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. */
diff --git a/src/secmem.h b/src/secmem.h
index 29dd64fc..8ad6ef1a 100644
--- a/src/secmem.h
+++ b/src/secmem.h
@@ -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);