1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-11-20 02:42:09 +03:00

src: enable clear memory on all platforms

- convert `_libssh2_explicit_zero()` to macro. This allows inlining
  where supported (e.g. `SecureZeroMemory()`).

- replace `SecureZeroMemory()` (in `wincng.c`) and
  `LIBSSH2_CLEAR_MEMORY`-guarded `memset()` (in `os400qc3.c`) with
  `_libssh2_explicit_zero()` macro.

- delete `LIBSSH2_CLEAR_MEMORY` guards, which enables secure-zeroing
  universally.

- add `LIBSSH2_NO_CLEAR_MEMORY` option to disable secure-zeroing.

- while here, delete double/triple inclusion of `misc.h`.
  `libssh2_priv.h` included it already.

Closes #810
This commit is contained in:
Viktor Szakats
2023-03-07 14:21:46 +00:00
parent 505ea626b6
commit a0e424a51c
17 changed files with 35 additions and 77 deletions

View File

@@ -456,7 +456,6 @@ m4_case([$1],
AC_DEFINE(LIBSSH2_MBEDTLS, 1, [Use $1]) AC_DEFINE(LIBSSH2_MBEDTLS, 1, [Use $1])
LIBS="$LIBS -lmbedcrypto" LIBS="$LIBS -lmbedcrypto"
found_crypto="$1" found_crypto="$1"
support_clear_memory=yes
]) ])
], ],

View File

@@ -83,7 +83,6 @@ AC_SYS_LARGEFILE
found_crypto=none found_crypto=none
found_crypto_str="" found_crypto_str=""
support_clear_memory=no
crypto_errors="" crypto_errors=""
m4_set_add([crypto_backends], [openssl]) m4_set_add([crypto_backends], [openssl])
@@ -176,25 +175,11 @@ fi
AC_ARG_ENABLE(clear-memory, AC_ARG_ENABLE(clear-memory,
AC_HELP_STRING([--disable-clear-memory],[Disable clearing of memory before being freed]), AC_HELP_STRING([--disable-clear-memory],[Disable clearing of memory before being freed]),
[CLEAR_MEMORY=$enableval]) [CLEAR_MEMORY=$enableval])
if test "$CLEAR_MEMORY" != "no"; then if test "$CLEAR_MEMORY" = "no"; then
if test "$support_clear_memory" = "yes"; then AC_DEFINE(LIBSSH2_NO_CLEAR_MEMORY, 1, [Disable clearing of memory before being freed])
AC_DEFINE(LIBSSH2_CLEAR_MEMORY, 1, [Enable clearing of memory before being freed])
enable_clear_memory=yes
else
if test "$CLEAR_MEMORY" = "yes"; then
AC_MSG_ERROR([secure clearing/zeroing of memory is not supported by the selected crypto backend])
else
AC_MSG_WARN([secure clearing/zeroing of memory is not supported by the selected crypto backend])
fi
enable_clear_memory=unsupported
fi
else
if test "$support_clear_memory" = "yes"; then
enable_clear_memory=no enable_clear_memory=no
else else
AC_MSG_WARN([secure clearing/zeroing of memory is not supported by the selected crypto backend]) enable_clear_memory=yes
enable_clear_memory=unsupported
fi
fi fi
dnl ************************************************************ dnl ************************************************************

View File

@@ -185,9 +185,6 @@
/* to make a symbol visible */ /* to make a symbol visible */
#undef LIBSSH2_API #undef LIBSSH2_API
/* Enable clearing of memory before being freed */
#define LIBSSH2_CLEAR_MEMORY 1
/* Enable "none" cipher -- NOT RECOMMENDED */ /* Enable "none" cipher -- NOT RECOMMENDED */
#undef LIBSSH2_CRYPT_NONE #undef LIBSSH2_CRYPT_NONE

View File

@@ -236,9 +236,9 @@ target_include_directories(libssh2
## Options ## Options
option(CLEAR_MEMORY "Enable clearing of memory before being freed" ON) option(CLEAR_MEMORY "Enable clearing of memory before being freed" ON)
if(CLEAR_MEMORY) if(NOT CLEAR_MEMORY)
add_definitions(-DLIBSSH2_CLEAR_MEMORY) add_definitions(-DLIBSSH2_NO_CLEAR_MEMORY)
endif(CLEAR_MEMORY) endif()
add_feature_info("Shared library" BUILD_SHARED_LIBS add_feature_info("Shared library" BUILD_SHARED_LIBS
"creating libssh2 as a shared library (.so/.dll)") "creating libssh2 as a shared library (.so/.dll)")

View File

@@ -39,7 +39,6 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include "agent.h" #include "agent.h"
#include "misc.h"
#include <errno.h> #include <errno.h>
#ifdef HAVE_SYS_UN_H #ifdef HAVE_SYS_UN_H
#include <sys/un.h> #include <sys/un.h>

View File

@@ -40,7 +40,6 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include "misc.h"
#include "session.h" #include "session.h"
#ifdef WIN32 #ifdef WIN32
#include <stdlib.h> #include <stdlib.h>

View File

@@ -39,7 +39,6 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include "agent.h" #include "agent.h"
#include "misc.h"
#include <errno.h> #include <errno.h>
#ifdef HAVE_SYS_UN_H #ifdef HAVE_SYS_UN_H
#include <sys/un.h> #include <sys/un.h>

View File

@@ -37,7 +37,6 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include "misc.h"
/* Needed for struct iovec on some platforms */ /* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H #ifdef HAVE_SYS_UIO_H

View File

@@ -37,7 +37,6 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include "misc.h"
struct known_host { struct known_host {
struct list_node node; struct list_node node;

View File

@@ -59,17 +59,6 @@
# define LIBSSH2_WINDOWS_APP # define LIBSSH2_WINDOWS_APP
# endif # endif
# endif # endif
/* TODO: Enable this unconditionally for all platforms.
Also delete autotools logic that enables it only for mbedTLS.
And CMake logic which already enabled it unconditionally.
The actual memory clearing logic uses SecureZeroMemory(),
memset_s() or plain memset(), whichever is available, and
does not depend on any crypto backend function. */
#ifndef LIBSSH2_CLEAR_MEMORY
#define LIBSSH2_CLEAR_MEMORY
#endif
#endif #endif
#ifdef HAVE_WS2TCPIP_H #ifdef HAVE_WS2TCPIP_H
@@ -117,7 +106,7 @@
#include "libssh2.h" #include "libssh2.h"
#include "libssh2_publickey.h" #include "libssh2_publickey.h"
#include "libssh2_sftp.h" #include "libssh2_sftp.h"
#include "misc.h" /* for the linked list stuff */ #include "misc.h"
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0

View File

@@ -96,12 +96,8 @@ _libssh2_mbedtls_safe_free(void *buf, int len)
if(!buf) if(!buf)
return; return;
#ifdef LIBSSH2_CLEAR_MEMORY
if(len > 0) if(len > 0)
_libssh2_explicit_zero(buf, len); _libssh2_explicit_zero(buf, len);
#else
(void)len;
#endif
mbedtls_free(buf); mbedtls_free(buf);
} }

View File

@@ -739,20 +739,14 @@ void _libssh2_aes_ctr_increment(unsigned char *ctr,
} }
} }
#if !defined(WIN32) && !defined(HAVE_MEMSET_S) #ifdef LIBSSH2_MEMZERO
static void * (* const volatile memset_libssh)(void *, int, size_t) = memset; static void * (* const volatile memset_libssh)(void *, int, size_t) = memset;
#endif
void _libssh2_explicit_zero(void *buf, size_t size) void _libssh2_memzero(void *buf, size_t size)
{ {
#ifdef WIN32
SecureZeroMemory(buf, size);
#elif defined(HAVE_MEMSET_S)
(void)memset_s(buf, size, 0, size);
#else
memset_libssh(buf, 0, size); memset_libssh(buf, 0, size);
#endif
} }
#endif
/* String buffer */ /* String buffer */

View File

@@ -38,6 +38,23 @@
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
*/ */
#ifdef LIBSSH2_NO_CLEAR_MEMORY
#define _libssh2_explicit_zero(buf, size) do { \
(void)buf; \
(void)size; \
} while(0)
#else
#ifdef WIN32
#define _libssh2_explicit_zero(buf, size) SecureZeroMemory(buf, size)
#elif defined(HAVE_MEMSET_S)
#define _libssh2_explicit_zero(buf, size) (void)memset_s(buf, size, 0, size)
#else
#define LIBSSH2_MEMZERO
void _libssh2_memzero(void *buf, size_t size);
#define _libssh2_explicit_zero(buf, size) _libssh2_memzero(buf, size)
#endif
#endif
struct list_head { struct list_head {
struct list_node *last; struct list_node *last;
struct list_node *first; struct list_node *first;
@@ -89,7 +106,6 @@ void _libssh2_store_bignum2_bytes(unsigned char **buf,
const unsigned char *bytes, const unsigned char *bytes,
size_t len); size_t len);
void *_libssh2_calloc(LIBSSH2_SESSION *session, size_t size); void *_libssh2_calloc(LIBSSH2_SESSION *session, size_t size);
void _libssh2_explicit_zero(void *buf, size_t size);
struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session); struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session);
void _libssh2_string_buf_free(LIBSSH2_SESSION *session, void _libssh2_string_buf_free(LIBSSH2_SESSION *session,

View File

@@ -44,7 +44,6 @@
#if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL) #if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)
#include <string.h> #include <string.h>
#include "misc.h"
#ifndef EVP_MAX_BLOCK_LENGTH #ifndef EVP_MAX_BLOCK_LENGTH
#define EVP_MAX_BLOCK_LENGTH 32 #define EVP_MAX_BLOCK_LENGTH 32

View File

@@ -757,10 +757,9 @@ _libssh2_bn_free(_libssh2_bn *bn)
{ {
if(bn) { if(bn) {
if(bn->bignum) { if(bn->bignum) {
#ifdef LIBSSH2_CLEAR_MEMORY
if(bn->length) if(bn->length)
memset((char *) bn->bignum, 0, bn->length); _libssh2_explicit_zero(bn->bignum, bn->length);
#endif
free(bn->bignum); free(bn->bignum);
} }
@@ -781,10 +780,9 @@ _libssh2_bn_resize(_libssh2_bn *bn, size_t newlen)
if(!bn->bignum) if(!bn->bignum)
bignum = (unsigned char *) malloc(newlen); bignum = (unsigned char *) malloc(newlen);
else { else {
#ifdef LIBSSH2_CLEAR_MEMORY
if(newlen < bn->length) if(newlen < bn->length)
memset((char *) bn->bignum + newlen, 0, bn->length - newlen); _libssh2_explicit_zero(bn->bignum + newlen, bn->length - newlen);
#endif
if(!newlen) { if(!newlen) {
free((char *) bn->bignum); free((char *) bn->bignum);
bn->bignum = NULL; bn->bignum = NULL;

View File

@@ -56,7 +56,6 @@
#include "session.h" #include "session.h"
#include "channel.h" #include "channel.h"
#include "mac.h" #include "mac.h"
#include "misc.h"
/* libssh2_default_alloc /* libssh2_default_alloc
*/ */

View File

@@ -59,7 +59,6 @@
#include <windows.h> #include <windows.h>
#include <bcrypt.h> #include <bcrypt.h>
#include <math.h> #include <math.h>
#include "misc.h"
#ifdef HAVE_STDLIB_H #ifdef HAVE_STDLIB_H
#include <stdlib.h> #include <stdlib.h>
@@ -435,12 +434,8 @@ _libssh2_wincng_safe_free(void *buf, int len)
if(!buf) if(!buf)
return; return;
#ifdef LIBSSH2_CLEAR_MEMORY
if(len > 0) if(len > 0)
SecureZeroMemory(buf, len); _libssh2_explicit_zero(buf, len);
#else
(void)len;
#endif
free(buf); free(buf);
} }
@@ -2086,11 +2081,9 @@ _libssh2_wincng_bignum_resize(_libssh2_bn *bn, unsigned long length)
if(length == bn->length) if(length == bn->length)
return 0; return 0;
#ifdef LIBSSH2_CLEAR_MEMORY
if(bn->bignum && bn->length > 0 && length < bn->length) { if(bn->bignum && bn->length > 0 && length < bn->length) {
SecureZeroMemory(bn->bignum + length, bn->length - length); _libssh2_explicit_zero(bn->bignum + length, bn->length - length);
} }
#endif
bignum = realloc(bn->bignum, length); bignum = realloc(bn->bignum, length);
if(!bignum) if(!bignum)
@@ -2289,9 +2282,7 @@ _libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len,
if(offset > 0) { if(offset > 0) {
memmove(bn->bignum, bn->bignum + offset, length); memmove(bn->bignum, bn->bignum + offset, length);
#ifdef LIBSSH2_CLEAR_MEMORY _libssh2_explicit_zero(bn->bignum + length, offset);
SecureZeroMemory(bn->bignum + length, offset);
#endif
bignum = realloc(bn->bignum, length); bignum = realloc(bn->bignum, length);
if(bignum) { if(bignum) {