[git] GPG-ERROR - branch, gniibe/secmem, created. libgpg-error-1.32-14-gc6b7bbe

by NIIBE Yutaka cvs at cvs.gnupg.org
Thu Sep 6 03:18:38 CEST 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Error codes used by GnuPG et al.".

The branch, gniibe/secmem has been created
        at  c6b7bbe9136854bfb4f7d7a0f384dd41d9f6945d (commit)

- Log -----------------------------------------------------------------
commit c6b7bbe9136854bfb4f7d7a0f384dd41d9f6945d
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Sep 6 10:03:22 2018 +0900

    secmem: Export symbols and the interface.
    
    * src/Makefile.am (libgpg_error_la_SOURCES): Add secmem.c and secmem.h.
    * src/gpg-error.def.in: Add secmem symbols.
    * src/gpg-error.vers: Likewise.
    * src/gpg-error.h.in: Add secmem functions and macros.
    * src/secmem.h: Move internal prototypes to ...
    * src/gpgrt-int.h: ... here.
    * src/visibility.c: Add external functions.
    * src/visibility.h: Declare secmem functions.

diff --git a/src/Makefile.am b/src/Makefile.am
index fcfbb83..294bc27 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -187,6 +187,7 @@ libgpg_error_la_SOURCES = gettext.h $(arch_sources) \
 	estream.c estream-printf.c estream-printf.h \
 	strsource.c strerror.c code-to-errno.c code-from-errno.c \
 	visibility.c visibility.h \
+	secmem.c secmem.h \
 	sysutils.c \
 	syscall-clamp.c \
 	logging.c \
diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in
index 67bb12e..f4f3668 100644
--- a/src/gpg-error.def.in
+++ b/src/gpg-error.def.in
@@ -218,5 +218,15 @@ EXPORTS
  gpgrt_b64enc_write           @167
  gpgrt_b64enc_finish          @168
 
+ gpgrt_secmem_init            @169
+ gpgrt_secmem_term            @170
+ gpgrt_secmem_malloc          @171
+ gpgrt_secmem_realloc         @172
+ gpgrt_secmem_free            @173
+ gpgrt_secmem_dump_stats      @174
+ gpgrt_secmem_set_auto_expand @175
+ gpgrt_secmem_set_flags       @176
+ gpgrt_secmem_get_flags       @177
+ gpgrt_private_is_secure      @178
 
 ;; end of file with public symbols for Windows.
diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in
index 8bcafcc..46d4ea7 100644
--- a/src/gpg-error.h.in
+++ b/src/gpg-error.h.in
@@ -1270,7 +1270,28 @@ const char *gpgrt_strusage (int level);
 void gpgrt_set_strusage (const char *(*f)(int));
 void gpgrt_set_usage_outfnc (int (*f)(int, const char *));
 void gpgrt_set_fixed_string_mapper (const char *(*f)(const char*));
+

+/*
+ * secmem functions.
+ */
 
+/* Flags for _gpgrt_secmem_{set,get}_flags.  */
+#define GPGRT_SECMEM_FLAG_NO_WARNING      (1 << 0)
+#define GPGRT_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
+#define GPGRT_SECMEM_FLAG_NOT_LOCKED      (1 << 2)
+#define GPGRT_SECMEM_FLAG_NO_MLOCK        (1 << 3)
+#define GPGRT_SECMEM_FLAG_NO_PRIV_DROP    (1 << 4)
+
+void gpgrt_secmem_init (size_t npool);
+void gpgrt_secmem_term (void);
+void *gpgrt_secmem_malloc (size_t size, int xhint) GPGRT_ATTR_MALLOC;
+void *gpgrt_secmem_realloc (void *a, size_t newsize, int xhint);
+int  gpgrt_secmem_free (void *a);
+void gpgrt_secmem_dump_stats (int extended);
+void gpgrt_secmem_set_auto_expand (unsigned int chunksize);
+void gpgrt_secmem_set_flags (unsigned flags);
+unsigned gpgrt_secmem_get_flags (void);
+int gpgrt_private_is_secure (const void *p);
 
 
 #ifdef __cplusplus
diff --git a/src/gpg-error.vers b/src/gpg-error.vers
index 201b784..4e58300 100644
--- a/src/gpg-error.vers
+++ b/src/gpg-error.vers
@@ -190,6 +190,16 @@ GPG_ERROR_1.0 {
     gpgrt_b64enc_write;
     gpgrt_b64enc_finish;
 
+    gpgrt_secmem_init;
+    gpgrt_secmem_term;
+    gpgrt_secmem_malloc;
+    gpgrt_secmem_realloc;
+    gpgrt_secmem_free;
+    gpgrt_secmem_dump_stats;
+    gpgrt_secmem_set_auto_expand;
+    gpgrt_secmem_set_flags;
+    gpgrt_secmem_get_flags;
+    gpgrt_private_is_secure;
 
   local:
     *;
diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h
index 34e494c..2cc3a4c 100644
--- a/src/gpgrt-int.h
+++ b/src/gpgrt-int.h
@@ -742,6 +742,19 @@ void _gpgrt_set_usage_outfnc (int (*fnc)(int, const char *));
 void _gpgrt_set_fixed_string_mapper (const char *(*f)(const char*));
 
 
+/*
+ * Local prototypes for secmem.
+ */
+void _gpgrt_secmem_init (size_t npool);
+void _gpgrt_secmem_term (void);
+void *_gpgrt_secmem_malloc (size_t size, int xhint) GPGRT_ATTR_MALLOC;
+void *_gpgrt_secmem_realloc (void *a, size_t newsize, int xhint);
+int  _gpgrt_secmem_free (void *a);
+void _gpgrt_secmem_dump_stats (int extended);
+void _gpgrt_secmem_set_auto_expand (unsigned int chunksize);
+void _gpgrt_secmem_set_flags (unsigned flags);
+unsigned _gpgrt_secmem_get_flags (void);
+int _gpgrt_private_is_secure (const void *p);
 

 /*
  * Internal platform abstraction functions (sysutils.c)
diff --git a/src/secmem.h b/src/secmem.h
index cdab761..31b2b9b 100644
--- a/src/secmem.h
+++ b/src/secmem.h
@@ -23,24 +23,6 @@
 #ifndef G10_SECMEM_H
 #define G10_SECMEM_H 1
 
-void _gpgrt_secmem_init (size_t npool);
-void _gpgrt_secmem_term (void);
-void *_gpgrt_secmem_malloc (size_t size, int xhint) GPGRT_ATTR_MALLOC;
-void *_gpgrt_secmem_realloc (void *a, size_t newsize, int xhint);
-int  _gpgrt_secmem_free (void *a);
-void _gpgrt_secmem_dump_stats (int extended);
-void _gpgrt_secmem_set_auto_expand (unsigned int chunksize);
-void _gpgrt_secmem_set_flags (unsigned flags);
-unsigned _gpgrt_secmem_get_flags(void);
-int _gpgrt_private_is_secure (const void *p);
-
-/* Flags for _gpgrt_secmem_{set,get}_flags.  */
-#define GPGRT_SECMEM_FLAG_NO_WARNING      (1 << 0)
-#define GPGRT_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
-#define GPGRT_SECMEM_FLAG_NOT_LOCKED      (1 << 2)
-#define GPGRT_SECMEM_FLAG_NO_MLOCK        (1 << 3)
-#define GPGRT_SECMEM_FLAG_NO_PRIV_DROP    (1 << 4)
-
 #if __GNUC__ >= 3
 #define LIKELY( expr )    __builtin_expect( !!(expr), 1 )
 #define UNLIKELY( expr )  __builtin_expect( !!(expr), 0 )
diff --git a/src/visibility.c b/src/visibility.c
index 6f8bb24..e11dc98 100644
--- a/src/visibility.c
+++ b/src/visibility.c
@@ -1122,6 +1122,65 @@ gpgrt_set_fixed_string_mapper (const char *(*f)(const char*))
 }
 
 
+void
+gpgrt_secmem_init (size_t n)
+{
+  _gpgrt_secmem_init (n);
+}
+
+void
+gpgrt_secmem_term (void)
+{
+  _gpgrt_secmem_term ();
+}
+
+void *
+gpgrt_secmem_malloc (size_t size, int xhint)
+{
+  return _gpgrt_secmem_malloc (size, xhint);
+}
+
+void *
+gpgrt_secmem_realloc (void *a, size_t newsize, int xhint)
+{
+  return _gpgrt_secmem_realloc (a, newsize, xhint);
+}
+
+int
+gpgrt_secmem_free (void *a)
+{
+  return _gpgrt_secmem_free (a);
+}
+
+void
+gpgrt_secmem_dump_stats (int extended)
+{
+  _gpgrt_secmem_dump_stats (extended);
+}
+
+void
+gpgrt_secmem_set_auto_expand (unsigned int chunksize)
+{
+  _gpgrt_secmem_set_auto_expand (chunksize);
+}
+
+void
+gpgrt_secmem_set_flags (unsigned flags)
+{
+  _gpgrt_secmem_set_flags (flags);
+}
+
+unsigned
+gpgrt_secmem_get_flags (void)
+{
+  return _gpgrt_secmem_get_flags ();
+}
+
+int
+gpgrt_private_is_secure (const void *p)
+{
+  return _gpgrt_private_is_secure (p);
+}
 

 /* For consistency reasons we use function wrappers also for Windows
  * specific function despite that they are technically not needed.  */
diff --git a/src/visibility.h b/src/visibility.h
index cfa32e5..47ade34 100644
--- a/src/visibility.h
+++ b/src/visibility.h
@@ -209,6 +209,17 @@ MARK_VISIBLE (gpgrt_set_strusage)
 MARK_VISIBLE (gpgrt_set_fixed_string_mapper);
 MARK_VISIBLE (gpgrt_set_usage_outfnc);
 
+MARK_VISIBLE (gpgrt_secmem_init);
+MARK_VISIBLE (gpgrt_secmem_term);
+MARK_VISIBLE (gpgrt_secmem_malloc);
+MARK_VISIBLE (gpgrt_secmem_realloc);
+MARK_VISIBLE (gpgrt_secmem_free);
+MARK_VISIBLE (gpgrt_secmem_dump_stats);
+MARK_VISIBLE (gpgrt_secmem_set_auto_expand);
+MARK_VISIBLE (gpgrt_secmem_set_flags);
+MARK_VISIBLE (gpgrt_secmem_get_flags);
+MARK_VISIBLE (gpgrt_private_is_secure);
+
 #undef MARK_VISIBLE
 
 #else /*!_GPGRT_INCL_BY_VISIBILITY_C*/
@@ -379,6 +390,17 @@ MARK_VISIBLE (gpgrt_set_usage_outfnc);
 #define gpgrt_set_usage_outfnc        _gpgrt_USE_UNDERSCORED_FUNCTION
 #define gpgrt_set_fixed_string_mapper _gpgrt_USE_UNDERSCORED_FUNCTION
 
+#define gpgrt_secmem_init             _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_secmem_term             _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_secmem_malloc           _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_secmem_realloc          _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_secmem_free             _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_secmem_dump_stats       _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_secmem_set_auto_expand  _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_secmem_set_flags        _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_secmem_get_flags        _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_private_is_secure       _gpgrt_USE_UNDERSCORED_FUNCTION
+
 /* Windows specific functions.  */
 #define gpgrt_w32_reg_query_string  _gpgrt_USE_UNDERSCORED_FUNCTION
 

commit c03cc0015612a1f626fe79faeeea7a5e28a68935
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Sep 6 09:30:40 2018 +0900

    Copy definitions from libgcrypt/src/g10lib.h.
    
    * src/secmem.c (PROPERLY_ALIGNED_TYPE): Move to ...
    * src/semem.h (PROPERLY_ALIGNED_TYPE): ... here.
    
    * src/semem.h (LIKELY, UNLIKELY): Copy definitions
    from libgcrypt/src/g10lib.h.
    (wipememory2, wipememory)
    (fast_wipememory2_unaligned_head, fast_wipememory2): Likewise.
    (FASTWIPE_T, FASTWIPE_MULT): Use uint64_t and ULL of C99.

diff --git a/src/secmem.c b/src/secmem.c
index dd1d3cc..7645093 100644
--- a/src/secmem.c
+++ b/src/secmem.c
@@ -44,17 +44,6 @@
 #include "gpgrt-int.h"
 #include "secmem.h"
 
-typedef union
-{
-  int a;
-  short b;
-  char c[1];
-  long d;
-  uint64_t e;
-  float f;
-  double g;
-} PROPERLY_ALIGNED_TYPE;
-
 #if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS)
 #define MAP_ANONYMOUS MAP_ANON
 #endif
diff --git a/src/secmem.h b/src/secmem.h
index 8f0a938..cdab761 100644
--- a/src/secmem.h
+++ b/src/secmem.h
@@ -41,4 +41,78 @@ int _gpgrt_private_is_secure (const void *p);
 #define GPGRT_SECMEM_FLAG_NO_MLOCK        (1 << 3)
 #define GPGRT_SECMEM_FLAG_NO_PRIV_DROP    (1 << 4)
 
+#if __GNUC__ >= 3
+#define LIKELY( expr )    __builtin_expect( !!(expr), 1 )
+#define UNLIKELY( expr )  __builtin_expect( !!(expr), 0 )
+#else
+#define LIKELY( expr )    (!!(expr))
+#define UNLIKELY( expr )  (!!(expr))
+#endif
+
+typedef union
+{
+  int a;
+  short b;
+  char c[1];
+  long d;
+  uint64_t e;
+  float f;
+  double g;
+} PROPERLY_ALIGNED_TYPE;
+
+/* To avoid that a compiler optimizes certain memset calls away, these
+   macros may be used instead. */
+#define wipememory2(_ptr,_set,_len) do { \
+              volatile char *_vptr=(volatile char *)(_ptr); \
+              size_t _vlen=(_len); \
+              unsigned char _vset=(_set); \
+              fast_wipememory2(_vptr,_vset,_vlen); \
+              while(_vlen) { *_vptr=(_vset); _vptr++; _vlen--; } \
+                  } while(0)
+#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+
+#define FASTWIPE_T uint64_t
+#define FASTWIPE_MULT (0x0101010101010101ULL)
+
+/* Following architectures can handle unaligned accesses fast.  */
+#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
+    defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
+    defined(HAVE_GCC_ATTRIBUTE_MAY_ALIAS) && \
+    (defined(__i386__) || defined(__x86_64__) || \
+     defined(__powerpc__) || defined(__powerpc64__) || \
+     (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \
+     defined(__aarch64__))
+#define fast_wipememory2_unaligned_head(_ptr,_set,_len) /*do nothing*/
+typedef struct fast_wipememory_s
+{
+  FASTWIPE_T a;
+} __attribute__((packed, aligned(1), may_alias)) fast_wipememory_t;
+#else
+#define fast_wipememory2_unaligned_head(_vptr,_vset,_vlen) do { \
+              while(UNLIKELY((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1)) && _vlen) \
+                { *_vptr=(_vset); _vptr++; _vlen--; } \
+                  } while(0)
+typedef struct fast_wipememory_s
+{
+  FASTWIPE_T a;
+} fast_wipememory_t;
+#endif
+
+/* fast_wipememory2 may leave tail bytes unhandled, in which case tail bytes
+   are handled by wipememory2. */
+#define fast_wipememory2(_vptr,_vset,_vlen) do { \
+              FASTWIPE_T _vset_long = _vset; \
+              fast_wipememory2_unaligned_head(_vptr,_vset,_vlen); \
+              if (_vlen < sizeof(FASTWIPE_T)) \
+                break; \
+              _vset_long *= FASTWIPE_MULT; \
+              do { \
+                volatile fast_wipememory_t *_vptr_long = \
+                  (volatile void *)_vptr; \
+                _vptr_long->a = _vset_long; \
+                _vlen -= sizeof(FASTWIPE_T); \
+                _vptr += sizeof(FASTWIPE_T); \
+              } while (_vlen >= sizeof(FASTWIPE_T)); \
+                  } while (0)
+
 #endif /* G10_SECMEM_H */

commit 74dfa426d682906adb2679ad8e4a4824d3cd27e4
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Sep 6 09:22:24 2018 +0900

    Remove fips_mode support originally available in libgcrypt.
    
    * _gpgrt_secmem_malloc_internal: Remove fips_mode() call and its
    handling.

diff --git a/src/secmem.c b/src/secmem.c
index ad82dfb..dd1d3cc 100644
--- a/src/secmem.c
+++ b/src/secmem.c
@@ -619,12 +619,6 @@ _gpgrt_secmem_malloc_internal (size_t size, int xhint)
           return NULL;
         }
     }
-  if (not_locked && fips_mode ())
-    {
-      _gpgrt_log_info (_("secure memory pool is not locked while in FIPS mode\n"));
-      _gpg_err_set_errno (ENOMEM);
-      return NULL;
-    }
   if (show_warning && !suspend_warning)
     {
       show_warning = 0;
@@ -642,9 +636,8 @@ _gpgrt_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 || auto_expand) && !fips_mode ())
+   * overflow pools to return memory.  */
+  if ((xhint || auto_expand))
     {
       for (pool = pool->next; pool; pool = pool->next)
         {

commit 26bf6d0ab3f4b2a502d063ea3c02ebf57561097a
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Sep 6 09:15:49 2018 +0900

    secmem.c migration into gpgrt.
    
    * src/secmem.c: Include gpgrt-int.h instead of g10lib.h.
    (PROPERLY_ALIGNED_TYPE): Define here with uint64_t.  Originally in
    libgcrypt/src/types.h.
    (SECMEM_LOCK, SECMEM_UNLOCK): Use _gpgrt_* functions, instead.
    (*): Use _gpg_err_set_errno instead (underscore version).
    (*): Use _gpgrt_log_* functions instead (underscore version).

diff --git a/src/secmem.c b/src/secmem.c
index da5bd57..ad82dfb 100644
--- a/src/secmem.c
+++ b/src/secmem.c
@@ -30,6 +30,7 @@
 #include <stdarg.h>
 #include <unistd.h>
 #include <stddef.h>
+#include <stdint.h>
 
 #if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
 #include <sys/mman.h>
@@ -40,9 +41,20 @@
 #endif
 #endif
 
-#include "g10lib.h"
+#include "gpgrt-int.h"
 #include "secmem.h"
 
+typedef union
+{
+  int a;
+  short b;
+  char c[1];
+  long d;
+  uint64_t e;
+  float f;
+  double g;
+} PROPERLY_ALIGNED_TYPE;
+
 #if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS)
 #define MAP_ANONYMOUS MAP_ANON
 #endif
@@ -109,8 +121,8 @@ static unsigned int auto_expand;
 GPGRT_LOCK_DEFINE (secmem_lock);
 
 /* Convenient macros.  */
-#define SECMEM_LOCK   gpgrt_lock_lock   (&secmem_lock)
-#define SECMEM_UNLOCK gpgrt_lock_unlock (&secmem_lock)
+#define SECMEM_LOCK   _gpgrt_lock_lock   (&secmem_lock)
+#define SECMEM_UNLOCK _gpgrt_lock_unlock (&secmem_lock)
 
 /* The size of the memblock structure; this does not include the
    memory that is available to the user.  */
@@ -241,7 +253,7 @@ mb_get_new (pooldesc_t *pool, memblock_t *block, size_t size)
 
   if (! ptr_into_pool_p (pool, mb))
     {
-      gpg_err_set_errno (ENOMEM);
+      _gpg_err_set_errno (ENOMEM);
       mb = NULL;
     }
 
@@ -253,7 +265,7 @@ static void
 print_warn (void)
 {
   if (!no_warning)
-    log_info (_("Warning: using insecure memory!\n"));
+    _gpgrt_log_info (_("Warning: using insecure memory!\n"));
 }
 
 
@@ -298,7 +310,7 @@ lock_pool_pages (void *p, size_t n)
             && err != ENOMEM
 #endif
 	  )
-	log_error ("can't lock memory: %s\n", strerror (err));
+	_gpgrt_log_error ("can't lock memory: %s\n", strerror (err));
       show_warning = 1;
       not_locked = 1;
     }
@@ -340,7 +352,7 @@ lock_pool_pages (void *p, size_t n)
           /* Check that we really dropped the privs.
            * Note: setuid(0) should always fail */
           if (setuid (uid) || getuid () != geteuid () || !setuid (0))
-            log_fatal ("failed to reset uid: %s\n", strerror (errno));
+            _gpgrt_log_fatal ("failed to reset uid: %s\n", strerror (errno));
         }
     }
 
@@ -357,7 +369,7 @@ lock_pool_pages (void *p, size_t n)
             && err != ENOMEM
 #endif
 	  )
-	log_error ("can't lock memory: %s\n", strerror (err));
+	_gpgrt_log_error ("can't lock memory: %s\n", strerror (err));
       show_warning = 1;
       not_locked = 1;
     }
@@ -384,7 +396,7 @@ lock_pool_pages (void *p, size_t n)
   (void)p;
   (void)n;
   if (!no_mlock)
-    log_info ("Please note that you don't have secure memory on this system\n");
+    _gpgrt_log_info ("Please note that you don't have secure memory on this system\n");
 #endif
 }
 
@@ -397,7 +409,7 @@ init_pool (pooldesc_t *pool, size_t n)
   pool->size = n;
 
   if (disable_secmem)
-    log_bug ("secure memory is disabled");
+    _gpgrt_log_bug ("secure memory is disabled");
 
 
 #if HAVE_MMAP
@@ -425,7 +437,7 @@ init_pool (pooldesc_t *pool, size_t n)
       fd = open ("/dev/zero", O_RDWR);
       if (fd == -1)
         {
-          log_error ("can't open /dev/zero: %s\n", strerror (errno));
+          _gpgrt_log_error ("can't open /dev/zero: %s\n", strerror (errno));
           pool->mem = (void *) -1;
         }
       else
@@ -437,8 +449,8 @@ init_pool (pooldesc_t *pool, size_t n)
     }
 # endif
     if (pool->mem == (void *) -1)
-      log_info ("can't mmap pool of %u bytes: %s - using malloc\n",
-                (unsigned) pool->size, strerror (errno));
+      _gpgrt_log_info ("can't mmap pool of %u bytes: %s - using malloc\n",
+                       (unsigned) pool->size, strerror (errno));
     else
       {
         pool->is_mmapped = 1;
@@ -451,8 +463,8 @@ init_pool (pooldesc_t *pool, size_t n)
     {
       pool->mem = malloc (pool->size);
       if (!pool->mem)
-	log_fatal ("can't allocate memory pool of %u bytes\n",
-		   (unsigned) pool->size);
+	_gpgrt_log_fatal ("can't allocate memory pool of %u bytes\n",
+                          (unsigned) pool->size);
       else
 	pool->okay = 1;
     }
@@ -552,7 +564,7 @@ _gpgrt_secmem_init_internal (size_t n)
       if (uid != geteuid ())
 	{
 	  if (setuid (uid) || getuid () != geteuid () || !setuid (0))
-	    log_fatal ("failed to drop setuid\n");
+	    _gpgrt_log_fatal ("failed to drop setuid\n");
 	}
 #endif
     }
@@ -566,7 +578,7 @@ _gpgrt_secmem_init_internal (size_t n)
 	  lock_pool_pages (pool->mem, n);
 	}
       else
-	log_error ("Oops, secure memory pool already initialized\n");
+	_gpgrt_log_error ("Oops, secure memory pool already initialized\n");
     }
 }
 
@@ -601,16 +613,16 @@ _gpgrt_secmem_malloc_internal (size_t size, int xhint)
       _gpgrt_secmem_init_internal (STANDARD_POOL_SIZE);
       if (!pool->okay)
         {
-          log_info (_("operation is not possible without "
-                      "initialized secure memory\n"));
-          gpg_err_set_errno (ENOMEM);
+          _gpgrt_log_info (_("operation is not possible without "
+                             "initialized secure memory\n"));
+          _gpg_err_set_errno (ENOMEM);
           return NULL;
         }
     }
   if (not_locked && fips_mode ())
     {
-      log_info (_("secure memory pool is not locked while in FIPS mode\n"));
-      gpg_err_set_errno (ENOMEM);
+      _gpgrt_log_info (_("secure memory pool is not locked while in FIPS mode\n"));
+      _gpg_err_set_errno (ENOMEM);
       return NULL;
     }
   if (show_warning && !suspend_warning)
@@ -872,21 +884,21 @@ _gpgrt_secmem_dump_stats (int extended)
       if (!extended)
         {
           if (pool->okay)
-            log_info ("%-13s %u/%lu bytes in %u blocks\n",
-                      pool == &mainpool? "secmem usage:":"",
-                      pool->cur_alloced, (unsigned long)pool->size,
-                      pool->cur_blocks);
+            _gpgrt_log_info ("%-13s %u/%lu bytes in %u blocks\n",
+                             pool == &mainpool? "secmem usage:":"",
+                             pool->cur_alloced, (unsigned long)pool->size,
+                             pool->cur_blocks);
         }
       else
         {
           for (i = 0, mb = (memblock_t *) pool->mem;
                ptr_into_pool_p (pool, mb);
                mb = mb_get_next (pool, mb), i++)
-            log_info ("SECMEM: pool %d %s block %i size %i\n",
-                      poolno,
-                      (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free",
-                      i,
-                      mb->size);
+            _gpgrt_log_info ("SECMEM: pool %d %s block %i size %i\n",
+                             poolno,
+                             (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free",
+                             i,
+                             mb->size);
         }
     }
   SECMEM_UNLOCK;

commit 6930b723a1941b4dece6caa754a89add362418b3
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Sep 6 08:53:07 2018 +0900

    Remove _gpgrt_secmem_module_init.

diff --git a/src/secmem.c b/src/secmem.c
index 8b5d803..da5bd57 100644
--- a/src/secmem.c
+++ b/src/secmem.c
@@ -587,14 +587,6 @@ _gpgrt_secmem_init (size_t n)
 }
 
 
-gpgrt_err_code_t
-_gpgrt_secmem_module_init ()
-{
-  /* Not anymore needed.  */
-  return 0;
-}
-
-
 static void *
 _gpgrt_secmem_malloc_internal (size_t size, int xhint)
 {

commit 25e0253fdaa8d47795ed7f5895202413afd90b28
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Sep 6 08:52:14 2018 +0900

    Change gcry -> gpgrt_.

diff --git a/src/secmem.c b/src/secmem.c
index 532fbde..8b5d803 100644
--- a/src/secmem.c
+++ b/src/secmem.c
@@ -467,7 +467,7 @@ init_pool (pooldesc_t *pool, size_t n)
 /* 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)
+_gpgrt_secmem_set_auto_expand (unsigned int chunksize)
 {
   /* Round up to a multiple of the STANDARD_POOL_SIZE.  */
   chunksize = ((chunksize + (2*STANDARD_POOL_SIZE) - 1)
@@ -482,17 +482,17 @@ _gcry_secmem_set_auto_expand (unsigned int chunksize)
 
 
 void
-_gcry_secmem_set_flags (unsigned flags)
+_gpgrt_secmem_set_flags (unsigned flags)
 {
   int was_susp;
 
   SECMEM_LOCK;
 
   was_susp = suspend_warning;
-  no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING;
-  suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING;
-  no_mlock      = flags & GCRY_SECMEM_FLAG_NO_MLOCK;
-  no_priv_drop = flags & GCRY_SECMEM_FLAG_NO_PRIV_DROP;
+  no_warning = flags & GPGRT_SECMEM_FLAG_NO_WARNING;
+  suspend_warning = flags & GPGRT_SECMEM_FLAG_SUSPEND_WARNING;
+  no_mlock      = flags & GPGRT_SECMEM_FLAG_NO_MLOCK;
+  no_priv_drop = flags & GPGRT_SECMEM_FLAG_NO_PRIV_DROP;
 
   /* and now issue the warning if it is not longer suspended */
   if (was_susp && !suspend_warning && show_warning)
@@ -505,17 +505,17 @@ _gcry_secmem_set_flags (unsigned flags)
 }
 
 unsigned int
-_gcry_secmem_get_flags (void)
+_gpgrt_secmem_get_flags (void)
 {
   unsigned flags;
 
   SECMEM_LOCK;
 
-  flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0;
-  flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0;
-  flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0;
-  flags |= no_mlock ? GCRY_SECMEM_FLAG_NO_MLOCK : 0;
-  flags |= no_priv_drop ? GCRY_SECMEM_FLAG_NO_PRIV_DROP : 0;
+  flags = no_warning ? GPGRT_SECMEM_FLAG_NO_WARNING : 0;
+  flags |= suspend_warning ? GPGRT_SECMEM_FLAG_SUSPEND_WARNING : 0;
+  flags |= not_locked ? GPGRT_SECMEM_FLAG_NOT_LOCKED : 0;
+  flags |= no_mlock ? GPGRT_SECMEM_FLAG_NO_MLOCK : 0;
+  flags |= no_priv_drop ? GPGRT_SECMEM_FLAG_NO_PRIV_DROP : 0;
 
   SECMEM_UNLOCK;
 
@@ -526,7 +526,7 @@ _gcry_secmem_get_flags (void)
 /* This function initializes the main memory pool MAINPOOL.  Itis
  * expected to be called with the secmem lock held.  */
 static void
-_gcry_secmem_init_internal (size_t n)
+_gpgrt_secmem_init_internal (size_t n)
 {
   pooldesc_t *pool;
 
@@ -577,18 +577,18 @@ _gcry_secmem_init_internal (size_t n)
    order to prevent page-outs of the data.  Furthermore allocated
    secure memory will be wiped out when released.  */
 void
-_gcry_secmem_init (size_t n)
+_gpgrt_secmem_init (size_t n)
 {
   SECMEM_LOCK;
 
-  _gcry_secmem_init_internal (n);
+  _gpgrt_secmem_init_internal (n);
 
   SECMEM_UNLOCK;
 }
 
 
-gcry_err_code_t
-_gcry_secmem_module_init ()
+gpgrt_err_code_t
+_gpgrt_secmem_module_init ()
 {
   /* Not anymore needed.  */
   return 0;
@@ -596,7 +596,7 @@ _gcry_secmem_module_init ()
 
 
 static void *
-_gcry_secmem_malloc_internal (size_t size, int xhint)
+_gpgrt_secmem_malloc_internal (size_t size, int xhint)
 {
   pooldesc_t *pool;
   memblock_t *mb;
@@ -606,7 +606,7 @@ _gcry_secmem_malloc_internal (size_t size, int xhint)
   if (!pool->okay)
     {
       /* Try to initialize the pool if the user forgot about it.  */
-      _gcry_secmem_init_internal (STANDARD_POOL_SIZE);
+      _gpgrt_secmem_init_internal (STANDARD_POOL_SIZE);
       if (!pool->okay)
         {
           log_info (_("operation is not possible without "
@@ -669,7 +669,7 @@ _gcry_secmem_malloc_internal (size_t size, int xhint)
 
       pool->okay = 1;
 
-      /* Take care: in _gcry_private_is_secure we do not lock and thus
+      /* Take care: in _gpgrt_private_is_secure we do not lock and thus
        * we assume that the second assignment below is atomic.  */
       pool->next = mainpool.next;
       mainpool.next = pool;
@@ -695,19 +695,19 @@ _gcry_secmem_malloc_internal (size_t size, int xhint)
 /* Allocate a block from the secmem of SIZE.  With XHINT set assume
  * that the caller is a xmalloc style function.  */
 void *
-_gcry_secmem_malloc (size_t size, int xhint)
+_gpgrt_secmem_malloc (size_t size, int xhint)
 {
   void *p;
 
   SECMEM_LOCK;
-  p = _gcry_secmem_malloc_internal (size, xhint);
+  p = _gpgrt_secmem_malloc_internal (size, xhint);
   SECMEM_UNLOCK;
 
   return p;
 }
 
 static int
-_gcry_secmem_free_internal (void *a)
+_gpgrt_secmem_free_internal (void *a)
 {
   pooldesc_t *pool;
   memblock_t *mb;
@@ -746,7 +746,7 @@ _gcry_secmem_free_internal (void *a)
 /* Wipe out and release memory.  Returns true if this function
  * actually released A.  */
 int
-_gcry_secmem_free (void *a)
+_gpgrt_secmem_free (void *a)
 {
   int mine;
 
@@ -754,14 +754,14 @@ _gcry_secmem_free (void *a)
     return 1; /* Tell caller that we handled it.  */
 
   SECMEM_LOCK;
-  mine = _gcry_secmem_free_internal (a);
+  mine = _gpgrt_secmem_free_internal (a);
   SECMEM_UNLOCK;
   return mine;
 }
 
 
 static void *
-_gcry_secmem_realloc_internal (void *p, size_t newsize, int xhint)
+_gpgrt_secmem_realloc_internal (void *p, size_t newsize, int xhint)
 {
   memblock_t *mb;
   size_t size;
@@ -777,12 +777,12 @@ _gcry_secmem_realloc_internal (void *p, size_t newsize, int xhint)
     }
   else
     {
-      a = _gcry_secmem_malloc_internal (newsize, xhint);
+      a = _gpgrt_secmem_malloc_internal (newsize, xhint);
       if (a)
 	{
 	  memcpy (a, p, size);
 	  memset ((char *) a + size, 0, newsize - size);
-	  _gcry_secmem_free_internal (p);
+	  _gpgrt_secmem_free_internal (p);
 	}
     }
 
@@ -793,12 +793,12 @@ _gcry_secmem_realloc_internal (void *p, size_t newsize, int xhint)
 /* Realloc memory.  With XHINT set assume that the caller is a xmalloc
  * style function.  */
 void *
-_gcry_secmem_realloc (void *p, size_t newsize, int xhint)
+_gpgrt_secmem_realloc (void *p, size_t newsize, int xhint)
 {
   void *a;
 
   SECMEM_LOCK;
-  a = _gcry_secmem_realloc_internal (p, newsize, xhint);
+  a = _gpgrt_secmem_realloc_internal (p, newsize, xhint);
   SECMEM_UNLOCK;
 
   return a;
@@ -807,12 +807,12 @@ _gcry_secmem_realloc (void *p, size_t newsize, int xhint)
 
 /* Return true if P points into the secure memory areas.  */
 int
-_gcry_private_is_secure (const void *p)
+_gpgrt_private_is_secure (const void *p)
 {
   pooldesc_t *pool;
 
   /* We do no lock here because once a pool is allocatred it will not
-   * be removed anymore (except for gcry_secmem_term).  Further,
+   * be removed anymore (except for gpgrt_secmem_term).  Further,
    * adding a new pool to the list should be atomic.  */
   for (pool = &mainpool; pool; pool = pool->next)
     if (pool->okay && ptr_into_pool_p (pool, p))
@@ -831,7 +831,7 @@ _gcry_private_is_secure (const void *p)
  *	     there is no chance to get the secure memory cleaned.
  */
 void
-_gcry_secmem_term ()
+_gpgrt_secmem_term ()
 {
   pooldesc_t *pool, *next;
 
@@ -867,7 +867,7 @@ _gcry_secmem_term ()
 /* Print stats of the secmem allocator.  With EXTENDED passwed as true
  * a detiled listing is returned (used for testing).  */
 void
-_gcry_secmem_dump_stats (int extended)
+_gpgrt_secmem_dump_stats (int extended)
 {
   pooldesc_t *pool;
   memblock_t *mb;
diff --git a/src/secmem.h b/src/secmem.h
index 3a0af2a..8f0a938 100644
--- a/src/secmem.h
+++ b/src/secmem.h
@@ -23,22 +23,22 @@
 #ifndef G10_SECMEM_H
 #define G10_SECMEM_H 1
 
-void _gcry_secmem_init (size_t npool);
-void _gcry_secmem_term (void);
-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);
+void _gpgrt_secmem_init (size_t npool);
+void _gpgrt_secmem_term (void);
+void *_gpgrt_secmem_malloc (size_t size, int xhint) GPGRT_ATTR_MALLOC;
+void *_gpgrt_secmem_realloc (void *a, size_t newsize, int xhint);
+int  _gpgrt_secmem_free (void *a);
+void _gpgrt_secmem_dump_stats (int extended);
+void _gpgrt_secmem_set_auto_expand (unsigned int chunksize);
+void _gpgrt_secmem_set_flags (unsigned flags);
+unsigned _gpgrt_secmem_get_flags(void);
+int _gpgrt_private_is_secure (const void *p);
 
-/* Flags for _gcry_secmem_{set,get}_flags.  */
-#define GCRY_SECMEM_FLAG_NO_WARNING      (1 << 0)
-#define GCRY_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
-#define GCRY_SECMEM_FLAG_NOT_LOCKED      (1 << 2)
-#define GCRY_SECMEM_FLAG_NO_MLOCK        (1 << 3)
-#define GCRY_SECMEM_FLAG_NO_PRIV_DROP    (1 << 4)
+/* Flags for _gpgrt_secmem_{set,get}_flags.  */
+#define GPGRT_SECMEM_FLAG_NO_WARNING      (1 << 0)
+#define GPGRT_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
+#define GPGRT_SECMEM_FLAG_NOT_LOCKED      (1 << 2)
+#define GPGRT_SECMEM_FLAG_NO_MLOCK        (1 << 3)
+#define GPGRT_SECMEM_FLAG_NO_PRIV_DROP    (1 << 4)
 
 #endif /* G10_SECMEM_H */

commit ed813b1dfb33f8c441b72a47ec0d8938f529c0f8
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Sep 6 08:49:54 2018 +0900

    Fix copyright notices.

diff --git a/src/secmem.c b/src/secmem.c
index 79c135f..532fbde 100644
--- a/src/secmem.c
+++ b/src/secmem.c
@@ -3,20 +3,23 @@
  *               2003, 2007 Free Software Foundation, Inc.
  * Copyright (C) 2013, 2016 g10 Code GmbH
  *
- * This file is part of Libgcrypt.
+ * This file is part of Libgpg-error.
  *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
+ * Libgpg-error is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
+ * Libgpg-error is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * License along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ *
+ * This file was originally a part of libgcrypt.
  */
 
 #include <config.h>
diff --git a/src/secmem.h b/src/secmem.h
index 8ad6ef1..3a0af2a 100644
--- a/src/secmem.h
+++ b/src/secmem.h
@@ -1,21 +1,23 @@
 /* secmem.h -  internal definitions for secmem
  *	Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
  *
- * This file is part of Libgcrypt.
+ * This file is part of Libgpg-error.
  *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
+ * Libgpg-error is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
+ * Libgpg-error is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * License along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ *
+ * This file was originally a part of libgcrypt.
  */
 
 #ifndef G10_SECMEM_H

commit ed924cebb5115212f6315f16630b6b7f1460e98b
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Sep 6 08:43:51 2018 +0900

    Add src/secmem.{c,h} from libgcrypt master.

diff --git a/src/secmem.c b/src/secmem.c
new file mode 100644
index 0000000..79c135f
--- /dev/null
+++ b/src/secmem.c
@@ -0,0 +1,898 @@
+/* secmem.c  -	memory allocation from a secure heap
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2016 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stddef.h>
+
+#if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#ifdef USE_CAPABILITIES
+#include <sys/capability.h>
+#endif
+#endif
+
+#include "g10lib.h"
+#include "secmem.h"
+
+#if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#define MINIMUM_POOL_SIZE 16384
+#define STANDARD_POOL_SIZE 32768
+#define DEFAULT_PAGE_SIZE 4096
+
+typedef struct memblock
+{
+  unsigned size;		/* Size of the memory available to the
+				   user.  */
+  int flags;			/* See below.  */
+  PROPERLY_ALIGNED_TYPE aligned;
+} memblock_t;
+
+/* This flag specifies that the memory block is in use.  */
+#define MB_FLAG_ACTIVE (1 << 0)
+
+/* An object describing a memory pool.  */
+typedef struct pooldesc_s
+{
+  /* A link to the next pool.  This is used to connect the overflow
+   * pools.  */
+  struct pooldesc_s *next;
+
+  /* A memory buffer used as allocation pool.  */
+  void *mem;
+
+  /* The allocated size of MEM. */
+  size_t size;
+
+  /* Flag indicating that this memory pool is ready for use.  May be
+   * checked in an atexit function.  */
+  volatile int okay;
+
+  /* Flag indicating whether MEM is mmapped.  */
+  volatile int is_mmapped;
+
+  /* The number of allocated bytes and the number of used blocks in
+   * this pool.  */
+  unsigned int cur_alloced, cur_blocks;
+} pooldesc_t;
+
+
+/* The pool of secure memory.  This is the head of a linked list with
+ * the first element being the standard mlock-ed pool and the
+ * following elements being the overflow pools. */
+static pooldesc_t mainpool;
+
+
+/* A couple of flags with some being set early.  */
+static int disable_secmem;
+static int show_warning;
+static int not_locked;
+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);
+
+/* Convenient macros.  */
+#define SECMEM_LOCK   gpgrt_lock_lock   (&secmem_lock)
+#define SECMEM_UNLOCK gpgrt_lock_unlock (&secmem_lock)
+
+/* The size of the memblock structure; this does not include the
+   memory that is available to the user.  */
+#define BLOCK_HEAD_SIZE \
+  offsetof (memblock_t, aligned)
+
+/* Convert an address into the according memory block structure.  */
+#define ADDR_TO_BLOCK(addr) \
+  (memblock_t *) (void *) ((char *) addr - BLOCK_HEAD_SIZE)
+
+/* Check whether P points into POOL.  */
+static inline int
+ptr_into_pool_p (pooldesc_t *pool, const void *p)
+{
+  /* We need to convert pointers to addresses.  This is required by
+     C-99 6.5.8 to avoid undefined behaviour.  See also
+     http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html
+  */
+  uintptr_t p_addr    = (uintptr_t)p;
+  uintptr_t pool_addr = (uintptr_t)pool->mem;
+
+  return p_addr >= pool_addr && p_addr <  pool_addr + pool->size;
+}
+
+/* Update the stats.  */
+static void
+stats_update (pooldesc_t *pool, size_t add, size_t sub)
+{
+  if (add)
+    {
+      pool->cur_alloced += add;
+      pool->cur_blocks++;
+    }
+  if (sub)
+    {
+      pool->cur_alloced -= sub;
+      pool->cur_blocks--;
+    }
+}
+
+/* Return the block following MB or NULL, if MB is the last block.  */
+static memblock_t *
+mb_get_next (pooldesc_t *pool, memblock_t *mb)
+{
+  memblock_t *mb_next;
+
+  mb_next = (memblock_t *) (void *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size);
+
+  if (! ptr_into_pool_p (pool, mb_next))
+    mb_next = NULL;
+
+  return mb_next;
+}
+
+/* Return the block preceding MB or NULL, if MB is the first
+   block.  */
+static memblock_t *
+mb_get_prev (pooldesc_t *pool, memblock_t *mb)
+{
+  memblock_t *mb_prev, *mb_next;
+
+  if (mb == pool->mem)
+    mb_prev = NULL;
+  else
+    {
+      mb_prev = (memblock_t *) pool->mem;
+      while (1)
+	{
+	  mb_next = mb_get_next (pool, mb_prev);
+	  if (mb_next == mb)
+	    break;
+	  else
+	    mb_prev = mb_next;
+	}
+    }
+
+  return mb_prev;
+}
+
+/* If the preceding block of MB and/or the following block of MB
+   exist and are not active, merge them to form a bigger block.  */
+static void
+mb_merge (pooldesc_t *pool, memblock_t *mb)
+{
+  memblock_t *mb_prev, *mb_next;
+
+  mb_prev = mb_get_prev (pool, mb);
+  mb_next = mb_get_next (pool, mb);
+
+  if (mb_prev && (! (mb_prev->flags & MB_FLAG_ACTIVE)))
+    {
+      mb_prev->size += BLOCK_HEAD_SIZE + mb->size;
+      mb = mb_prev;
+    }
+  if (mb_next && (! (mb_next->flags & MB_FLAG_ACTIVE)))
+    mb->size += BLOCK_HEAD_SIZE + mb_next->size;
+}
+
+/* Return a new block, which can hold SIZE bytes.  */
+static memblock_t *
+mb_get_new (pooldesc_t *pool, memblock_t *block, size_t size)
+{
+  memblock_t *mb, *mb_split;
+
+  for (mb = block; ptr_into_pool_p (pool, mb); mb = mb_get_next (pool, mb))
+    if (! (mb->flags & MB_FLAG_ACTIVE) && mb->size >= size)
+      {
+	/* Found a free block.  */
+	mb->flags |= MB_FLAG_ACTIVE;
+
+	if (mb->size - size > BLOCK_HEAD_SIZE)
+	  {
+	    /* Split block.  */
+
+	    mb_split = (memblock_t *) (void *) (((char *) mb) + BLOCK_HEAD_SIZE
+						+ size);
+	    mb_split->size = mb->size - size - BLOCK_HEAD_SIZE;
+	    mb_split->flags = 0;
+
+	    mb->size = size;
+
+	    mb_merge (pool, mb_split);
+
+	  }
+
+	break;
+      }
+
+  if (! ptr_into_pool_p (pool, mb))
+    {
+      gpg_err_set_errno (ENOMEM);
+      mb = NULL;
+    }
+
+  return mb;
+}
+
+/* Print a warning message.  */
+static void
+print_warn (void)
+{
+  if (!no_warning)
+    log_info (_("Warning: using insecure memory!\n"));
+}
+
+
+/* Lock the memory pages of pool P of size N into core and drop
+ * privileges.  */
+static void
+lock_pool_pages (void *p, size_t n)
+{
+#if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
+  int err;
+
+  {
+    cap_t cap;
+
+    if (!no_priv_drop)
+      {
+        cap = cap_from_text ("cap_ipc_lock+ep");
+        cap_set_proc (cap);
+        cap_free (cap);
+      }
+    err = no_mlock? 0 : mlock (p, n);
+    if (err && errno)
+      err = errno;
+    if (!no_priv_drop)
+      {
+        cap = cap_from_text ("cap_ipc_lock+p");
+        cap_set_proc (cap);
+        cap_free(cap);
+      }
+  }
+
+  if (err)
+    {
+      if (err != EPERM
+#ifdef EAGAIN	/* BSD and also Linux may return EAGAIN */
+	  && err != EAGAIN
+#endif
+#ifdef ENOSYS	/* Some SCOs return this (function not implemented) */
+	  && err != ENOSYS
+#endif
+#ifdef ENOMEM  /* Linux might return this. */
+            && err != ENOMEM
+#endif
+	  )
+	log_error ("can't lock memory: %s\n", strerror (err));
+      show_warning = 1;
+      not_locked = 1;
+    }
+
+#elif defined(HAVE_MLOCK)
+  uid_t uid;
+  int err;
+
+  uid = getuid ();
+
+#ifdef HAVE_BROKEN_MLOCK
+  /* Under HP/UX mlock segfaults if called by non-root.  Note, we have
+     noch checked whether mlock does really work under AIX where we
+     also detected a broken nlock.  Note further, that using plock ()
+     is not a good idea under AIX. */
+  if (uid)
+    {
+      errno = EPERM;
+      err = errno;
+    }
+  else
+    {
+      err = no_mlock? 0 : mlock (p, n);
+      if (err && errno)
+	err = errno;
+    }
+#else /* !HAVE_BROKEN_MLOCK */
+  err = no_mlock? 0 : mlock (p, n);
+  if (err && errno)
+    err = errno;
+#endif /* !HAVE_BROKEN_MLOCK */
+
+  /* Test whether we are running setuid(0).  */
+  if (uid && ! geteuid ())
+    {
+      /* Yes, we are.  */
+      if (!no_priv_drop)
+        {
+          /* Check that we really dropped the privs.
+           * Note: setuid(0) should always fail */
+          if (setuid (uid) || getuid () != geteuid () || !setuid (0))
+            log_fatal ("failed to reset uid: %s\n", strerror (errno));
+        }
+    }
+
+  if (err)
+    {
+      if (err != EPERM
+#ifdef EAGAIN	/* BSD and also Linux may return this. */
+	  && err != EAGAIN
+#endif
+#ifdef ENOSYS	/* Some SCOs return this (function not implemented). */
+	  && err != ENOSYS
+#endif
+#ifdef ENOMEM  /* Linux might return this. */
+            && err != ENOMEM
+#endif
+	  )
+	log_error ("can't lock memory: %s\n", strerror (err));
+      show_warning = 1;
+      not_locked = 1;
+    }
+
+#elif defined ( __QNX__ )
+  /* QNX does not page at all, so the whole secure memory stuff does
+   * not make much sense.  However it is still of use because it
+   * wipes out the memory on a free().
+   * Therefore it is sufficient to suppress the warning.  */
+  (void)p;
+  (void)n;
+#elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__)
+    /* It does not make sense to print such a warning, given the fact that
+     * this whole Windows !@#$% and their user base are inherently insecure. */
+  (void)p;
+  (void)n;
+#elif defined (__riscos__)
+    /* No virtual memory on RISC OS, so no pages are swapped to disc,
+     * besides we don't have mmap, so we don't use it! ;-)
+     * But don't complain, as explained above.  */
+  (void)p;
+  (void)n;
+#else
+  (void)p;
+  (void)n;
+  if (!no_mlock)
+    log_info ("Please note that you don't have secure memory on this system\n");
+#endif
+}
+
+/* Initialize POOL.  */
+static void
+init_pool (pooldesc_t *pool, size_t n)
+{
+  memblock_t *mb;
+
+  pool->size = n;
+
+  if (disable_secmem)
+    log_bug ("secure memory is disabled");
+
+
+#if HAVE_MMAP
+  {
+    size_t pgsize;
+    long int pgsize_val;
+
+# if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+    pgsize_val = sysconf (_SC_PAGESIZE);
+# elif defined(HAVE_GETPAGESIZE)
+    pgsize_val = getpagesize ();
+# else
+    pgsize_val = -1;
+# endif
+    pgsize = (pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE;
+
+    pool->size = (pool->size + pgsize - 1) & ~(pgsize - 1);
+# ifdef MAP_ANONYMOUS
+    pool->mem = mmap (0, pool->size, PROT_READ | PROT_WRITE,
+                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+# else /* map /dev/zero instead */
+    {
+      int fd;
+
+      fd = open ("/dev/zero", O_RDWR);
+      if (fd == -1)
+        {
+          log_error ("can't open /dev/zero: %s\n", strerror (errno));
+          pool->mem = (void *) -1;
+        }
+      else
+        {
+          pool->mem = mmap (0, pool->size,
+                           (PROT_READ | PROT_WRITE), MAP_PRIVATE, fd, 0);
+          close (fd);
+        }
+    }
+# endif
+    if (pool->mem == (void *) -1)
+      log_info ("can't mmap pool of %u bytes: %s - using malloc\n",
+                (unsigned) pool->size, strerror (errno));
+    else
+      {
+        pool->is_mmapped = 1;
+        pool->okay = 1;
+      }
+  }
+#endif /*HAVE_MMAP*/
+
+  if (!pool->okay)
+    {
+      pool->mem = malloc (pool->size);
+      if (!pool->mem)
+	log_fatal ("can't allocate memory pool of %u bytes\n",
+		   (unsigned) pool->size);
+      else
+	pool->okay = 1;
+    }
+
+  /* Initialize first memory block.  */
+  mb = (memblock_t *) pool->mem;
+  mb->size = pool->size - BLOCK_HEAD_SIZE;
+  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)
+{
+  int was_susp;
+
+  SECMEM_LOCK;
+
+  was_susp = suspend_warning;
+  no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING;
+  suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING;
+  no_mlock      = flags & GCRY_SECMEM_FLAG_NO_MLOCK;
+  no_priv_drop = flags & GCRY_SECMEM_FLAG_NO_PRIV_DROP;
+
+  /* and now issue the warning if it is not longer suspended */
+  if (was_susp && !suspend_warning && show_warning)
+    {
+      show_warning = 0;
+      print_warn ();
+    }
+
+  SECMEM_UNLOCK;
+}
+
+unsigned int
+_gcry_secmem_get_flags (void)
+{
+  unsigned flags;
+
+  SECMEM_LOCK;
+
+  flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0;
+  flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0;
+  flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0;
+  flags |= no_mlock ? GCRY_SECMEM_FLAG_NO_MLOCK : 0;
+  flags |= no_priv_drop ? GCRY_SECMEM_FLAG_NO_PRIV_DROP : 0;
+
+  SECMEM_UNLOCK;
+
+  return flags;
+}
+
+
+/* This function initializes the main memory pool MAINPOOL.  Itis
+ * expected to be called with the secmem lock held.  */
+static void
+_gcry_secmem_init_internal (size_t n)
+{
+  pooldesc_t *pool;
+
+  pool = &mainpool;
+  if (!n)
+    {
+#ifdef USE_CAPABILITIES
+      /* drop all capabilities */
+      if (!no_priv_drop)
+        {
+          cap_t cap;
+
+          cap = cap_from_text ("all-eip");
+          cap_set_proc (cap);
+          cap_free (cap);
+        }
+
+#elif !defined(HAVE_DOSISH_SYSTEM)
+      uid_t uid;
+
+      disable_secmem = 1;
+      uid = getuid ();
+      if (uid != geteuid ())
+	{
+	  if (setuid (uid) || getuid () != geteuid () || !setuid (0))
+	    log_fatal ("failed to drop setuid\n");
+	}
+#endif
+    }
+  else
+    {
+      if (n < MINIMUM_POOL_SIZE)
+	n = MINIMUM_POOL_SIZE;
+      if (! pool->okay)
+	{
+	  init_pool (pool, n);
+	  lock_pool_pages (pool->mem, n);
+	}
+      else
+	log_error ("Oops, secure memory pool already initialized\n");
+    }
+}
+
+
+
+/* Initialize the secure memory system.  If running with the necessary
+   privileges, the secure memory pool will be locked into the core in
+   order to prevent page-outs of the data.  Furthermore allocated
+   secure memory will be wiped out when released.  */
+void
+_gcry_secmem_init (size_t n)
+{
+  SECMEM_LOCK;
+
+  _gcry_secmem_init_internal (n);
+
+  SECMEM_UNLOCK;
+}
+
+
+gcry_err_code_t
+_gcry_secmem_module_init ()
+{
+  /* Not anymore needed.  */
+  return 0;
+}
+
+
+static void *
+_gcry_secmem_malloc_internal (size_t size, int xhint)
+{
+  pooldesc_t *pool;
+  memblock_t *mb;
+
+  pool = &mainpool;
+
+  if (!pool->okay)
+    {
+      /* Try to initialize the pool if the user forgot about it.  */
+      _gcry_secmem_init_internal (STANDARD_POOL_SIZE);
+      if (!pool->okay)
+        {
+          log_info (_("operation is not possible without "
+                      "initialized secure memory\n"));
+          gpg_err_set_errno (ENOMEM);
+          return NULL;
+        }
+    }
+  if (not_locked && fips_mode ())
+    {
+      log_info (_("secure memory pool is not locked while in FIPS mode\n"));
+      gpg_err_set_errno (ENOMEM);
+      return NULL;
+    }
+  if (show_warning && !suspend_warning)
+    {
+      show_warning = 0;
+      print_warn ();
+    }
+
+  /* Blocks are always a multiple of 32. */
+  size = ((size + 31) / 32) * 32;
+
+  mb = mb_get_new (pool, (memblock_t *) pool->mem, size);
+  if (mb)
+    {
+      stats_update (pool, mb->size, 0);
+      return &mb->aligned.c;
+    }
+
+  /* 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 || auto_expand) && !fips_mode ())
+    {
+      for (pool = pool->next; pool; pool = pool->next)
+        {
+          mb = mb_get_new (pool, (memblock_t *) pool->mem, size);
+          if (mb)
+            {
+              stats_update (pool, mb->size, 0);
+              return &mb->aligned.c;
+            }
+        }
+      /* Allocate a new overflow pool.  We put a new pool right after
+       * the mainpool so that the next allocation will happen in that
+       * pool and not in one of the older pools.  When this new pool
+       * gets full we will try to find space in the older pools.  */
+      pool = calloc (1, sizeof *pool);
+      if (!pool)
+        return NULL;  /* Not enough memory for a new pool descriptor.  */
+      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.  */
+      /* Initialize first memory block.  */
+      mb = (memblock_t *) pool->mem;
+      mb->size = pool->size - BLOCK_HEAD_SIZE;
+      mb->flags = 0;
+
+      pool->okay = 1;
+
+      /* Take care: in _gcry_private_is_secure we do not lock and thus
+       * we assume that the second assignment below is atomic.  */
+      pool->next = mainpool.next;
+      mainpool.next = pool;
+
+      /* After the first time we allocated an overflow pool, print a
+       * warning.  */
+      if (!pool->next)
+        print_warn ();
+
+      /* Allocate.  */
+      mb = mb_get_new (pool, (memblock_t *) pool->mem, size);
+      if (mb)
+        {
+          stats_update (pool, mb->size, 0);
+          return &mb->aligned.c;
+        }
+    }
+
+  return NULL;
+}
+
+
+/* Allocate a block from the secmem of SIZE.  With XHINT set assume
+ * that the caller is a xmalloc style function.  */
+void *
+_gcry_secmem_malloc (size_t size, int xhint)
+{
+  void *p;
+
+  SECMEM_LOCK;
+  p = _gcry_secmem_malloc_internal (size, xhint);
+  SECMEM_UNLOCK;
+
+  return p;
+}
+
+static int
+_gcry_secmem_free_internal (void *a)
+{
+  pooldesc_t *pool;
+  memblock_t *mb;
+  int size;
+
+  for (pool = &mainpool; pool; pool = pool->next)
+    if (pool->okay && ptr_into_pool_p (pool, a))
+      break;
+  if (!pool)
+    return 0; /* A does not belong to use.  */
+
+  mb = ADDR_TO_BLOCK (a);
+  size = mb->size;
+
+  /* This does not make much sense: probably this memory is held in the
+   * cache. We do it anyway: */
+#define MB_WIPE_OUT(byte) \
+  wipememory2 (((char *) mb + BLOCK_HEAD_SIZE), (byte), size);
+
+  MB_WIPE_OUT (0xff);
+  MB_WIPE_OUT (0xaa);
+  MB_WIPE_OUT (0x55);
+  MB_WIPE_OUT (0x00);
+
+  /* Update stats.  */
+  stats_update (pool, 0, size);
+
+  mb->flags &= ~MB_FLAG_ACTIVE;
+
+  mb_merge (pool, mb);
+
+  return 1; /* Freed.  */
+}
+
+
+/* Wipe out and release memory.  Returns true if this function
+ * actually released A.  */
+int
+_gcry_secmem_free (void *a)
+{
+  int mine;
+
+  if (!a)
+    return 1; /* Tell caller that we handled it.  */
+
+  SECMEM_LOCK;
+  mine = _gcry_secmem_free_internal (a);
+  SECMEM_UNLOCK;
+  return mine;
+}
+
+
+static void *
+_gcry_secmem_realloc_internal (void *p, size_t newsize, int xhint)
+{
+  memblock_t *mb;
+  size_t size;
+  void *a;
+
+  mb = (memblock_t *) (void *) ((char *) p
+				- ((size_t) &((memblock_t *) 0)->aligned.c));
+  size = mb->size;
+  if (newsize < size)
+    {
+      /* It is easier to not shrink the memory.  */
+      a = p;
+    }
+  else
+    {
+      a = _gcry_secmem_malloc_internal (newsize, xhint);
+      if (a)
+	{
+	  memcpy (a, p, size);
+	  memset ((char *) a + size, 0, newsize - size);
+	  _gcry_secmem_free_internal (p);
+	}
+    }
+
+  return a;
+}
+
+
+/* Realloc memory.  With XHINT set assume that the caller is a xmalloc
+ * style function.  */
+void *
+_gcry_secmem_realloc (void *p, size_t newsize, int xhint)
+{
+  void *a;
+
+  SECMEM_LOCK;
+  a = _gcry_secmem_realloc_internal (p, newsize, xhint);
+  SECMEM_UNLOCK;
+
+  return a;
+}
+
+
+/* Return true if P points into the secure memory areas.  */
+int
+_gcry_private_is_secure (const void *p)
+{
+  pooldesc_t *pool;
+
+  /* We do no lock here because once a pool is allocatred it will not
+   * be removed anymore (except for gcry_secmem_term).  Further,
+   * adding a new pool to the list should be atomic.  */
+  for (pool = &mainpool; pool; pool = pool->next)
+    if (pool->okay && ptr_into_pool_p (pool, p))
+      return 1;
+
+  return 0;
+}
+
+
+/****************
+ * Warning:  This code might be called by an interrupt handler
+ *	     and frankly, there should really be such a handler,
+ *	     to make sure that the memory is wiped out.
+ *	     We hope that the OS wipes out mlocked memory after
+ *	     receiving a SIGKILL - it really should do so, otherwise
+ *	     there is no chance to get the secure memory cleaned.
+ */
+void
+_gcry_secmem_term ()
+{
+  pooldesc_t *pool, *next;
+
+  for (pool = &mainpool; pool; pool = next)
+    {
+      next = pool->next;
+      if (!pool->okay)
+        continue;
+
+      wipememory2 (pool->mem, 0xff, pool->size);
+      wipememory2 (pool->mem, 0xaa, pool->size);
+      wipememory2 (pool->mem, 0x55, pool->size);
+      wipememory2 (pool->mem, 0x00, pool->size);
+      if (0)
+        ;
+#if HAVE_MMAP
+      else if (pool->is_mmapped)
+        munmap (pool->mem, pool->size);
+#endif
+      else
+        free (pool->mem);
+      pool->mem = NULL;
+      pool->okay = 0;
+      pool->size = 0;
+      if (pool != &mainpool)
+        free (pool);
+    }
+  mainpool.next = NULL;
+  not_locked = 0;
+}
+
+
+/* Print stats of the secmem allocator.  With EXTENDED passwed as true
+ * a detiled listing is returned (used for testing).  */
+void
+_gcry_secmem_dump_stats (int extended)
+{
+  pooldesc_t *pool;
+  memblock_t *mb;
+  int i, poolno;
+
+  SECMEM_LOCK;
+
+  for (pool = &mainpool, poolno = 0; pool; pool = pool->next, poolno++)
+    {
+      if (!extended)
+        {
+          if (pool->okay)
+            log_info ("%-13s %u/%lu bytes in %u blocks\n",
+                      pool == &mainpool? "secmem usage:":"",
+                      pool->cur_alloced, (unsigned long)pool->size,
+                      pool->cur_blocks);
+        }
+      else
+        {
+          for (i = 0, mb = (memblock_t *) pool->mem;
+               ptr_into_pool_p (pool, mb);
+               mb = mb_get_next (pool, mb), i++)
+            log_info ("SECMEM: pool %d %s block %i size %i\n",
+                      poolno,
+                      (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free",
+                      i,
+                      mb->size);
+        }
+    }
+  SECMEM_UNLOCK;
+}
diff --git a/src/secmem.h b/src/secmem.h
new file mode 100644
index 0000000..8ad6ef1
--- /dev/null
+++ b/src/secmem.h
@@ -0,0 +1,42 @@
+/* secmem.h -  internal definitions for secmem
+ *	Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef G10_SECMEM_H
+#define G10_SECMEM_H 1
+
+void _gcry_secmem_init (size_t npool);
+void _gcry_secmem_term (void);
+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);
+
+/* Flags for _gcry_secmem_{set,get}_flags.  */
+#define GCRY_SECMEM_FLAG_NO_WARNING      (1 << 0)
+#define GCRY_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
+#define GCRY_SECMEM_FLAG_NOT_LOCKED      (1 << 2)
+#define GCRY_SECMEM_FLAG_NO_MLOCK        (1 << 3)
+#define GCRY_SECMEM_FLAG_NO_PRIV_DROP    (1 << 4)
+
+#endif /* G10_SECMEM_H */

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


hooks/post-receive
-- 
Error codes used by GnuPG et al.
http://git.gnupg.org




More information about the Gnupg-commits mailing list