[PATCH] Use explicit_bzero for wipememory
Jussi Kivilinna
jussi.kivilinna at iki.fi
Tue Nov 20 19:51:02 CET 2018
* configure.ac (AC_CHECK_FUNCS): Check for 'explicit_bzero'.
* src/g10lib.h (wipememory2): Use _gcry_fast_wipememory if _SET is
zero.
(_gcry_fast_wipememory): New.
(_gcry_wipememory2): Rename to...
(_gcry_fast_wipememory2): ...this.
* src/misc.c (_gcry_wipememory): New.
(_gcry_wipememory2): Rename to...
(_gcry_fast_wipememory2): ...this.
(_gcry_fast_wipememory2) [HAVE_EXPLICIT_BZERO]: Use explicit_bzero if
SET is zero.
(_gcry_burn_stack): Use _gcry_fast_wipememory.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
0 files changed
diff --git a/configure.ac b/configure.ac
index 9803d518b..5843884c6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1772,6 +1772,7 @@ AC_CHECK_FUNCS(strtoul memmove stricmp atexit raise)
AC_CHECK_FUNCS(strerror rand mmap getpagesize sysconf waitpid wait4)
AC_CHECK_FUNCS(gettimeofday getrusage gethrtime clock_gettime syslog)
AC_CHECK_FUNCS(syscall fcntl ftruncate flockfile)
+AC_CHECK_FUNCS(explicit_bzero)
GNUPG_CHECK_MLOCK
diff --git a/src/g10lib.h b/src/g10lib.h
index 9b2147812..694c2d83e 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -334,15 +334,16 @@ void __gcry_burn_stack (unsigned int bytes);
do { __gcry_burn_stack (bytes); \
__gcry_burn_stack_dummy (); } while(0)
-
/* To avoid that a compiler optimizes certain memset calls away, these
macros may be used instead. For small constant length buffers,
memory wiping is inlined. For non-constant or large length buffers,
- memory is wiped with memset through _gcry_wipememory. */
-void _gcry_wipememory2(void *ptr, int set, size_t len);
+ memory is wiped with memset through _gcry_fast_wipememory. */
#define wipememory2(_ptr,_set,_len) do { \
if (!CONSTANT_P(_len) || _len > 64) { \
- _gcry_wipememory2((void *)_ptr, _set, _len); \
+ if (CONSTANT_P(_set) && (_set) == 0) \
+ _gcry_fast_wipememory((void *)_ptr, _len); \
+ else \
+ _gcry_fast_wipememory2((void *)_ptr, _set, _len); \
} else {\
volatile char *_vptr = (volatile char *)(_ptr); \
size_t _vlen = (_len); \
@@ -353,6 +354,9 @@ void _gcry_wipememory2(void *ptr, int set, size_t len);
} while(0)
#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+void _gcry_fast_wipememory(void *ptr, size_t len);
+void _gcry_fast_wipememory2(void *ptr, int set, size_t len);
+
#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
defined(HAVE_GCC_ATTRIBUTE_MAY_ALIAS)
diff --git a/src/misc.c b/src/misc.c
index 420ce74db..bb39e1c2f 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -32,6 +32,8 @@
static int verbosity_level = 0;
+/* Prevent compiler from optimizing away the call to memset by accessing
+ memset through volatile pointer. */
static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset;
static void (*fatal_error_handler)(void*,int, const char*) = NULL;
@@ -500,8 +502,37 @@ _gcry_strtokenize (const char *string, const char *delim)
void
-_gcry_wipememory2 (void *ptr, int set, size_t len)
+_gcry_fast_wipememory (void *ptr, size_t len)
{
+ /* Note: This function is called from wipememory/wipememory2 only if LEN
+ is large or unknown at compile time. New wipe function alternatives
+ need to be checked before adding to this function. New implementations
+ need to be faster than wipememory/wipememory2 macros in 'misc.h'.
+
+ Following implementations were found to have suboptimal performance:
+
+ - [_WIN32/mingw32] SecureZeroMemory; Inline function, equivalent to
+ volatile byte buffer set: while(buflen--) (volatile char *)(buf++)=set;
+ */
+#ifdef HAVE_EXPLICIT_BZERO
+ explicit_bzero (ptr, len);
+#else
+ memset_ptr (ptr, 0, len);
+#endif
+}
+
+
+void
+_gcry_fast_wipememory2 (void *ptr, int set, size_t len)
+{
+#ifdef HAVE_EXPLICIT_BZERO
+ if (set == 0)
+ {
+ explicit_bzero (ptr, len);
+ return;
+ }
+#endif
+
memset_ptr (ptr, set, len);
}
@@ -514,11 +545,11 @@ __gcry_burn_stack (unsigned int bytes)
unsigned int buflen = ((!bytes + bytes) + 63) & ~63;
char buf[buflen];
- memset_ptr (buf, 0, buflen);
+ _gcry_fast_wipememory (buf, buflen);
#else
volatile char buf[64];
- wipememory (buf, sizeof buf);
+ _gcry_fast_wipememory (buf, sizeof buf);
if (bytes > sizeof buf)
_gcry_burn_stack (bytes - sizeof buf);
More information about the Gcrypt-devel
mailing list