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

[email protected] (by NIIBE Yutaka)
Newsgroups gmane.comp.encryption.gpg.cvs
Message-ID <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.