1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-11-21 14:00:51 +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])
LIBS="$LIBS -lmbedcrypto"
found_crypto="$1"
support_clear_memory=yes
])
],

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -59,17 +59,6 @@
# define LIBSSH2_WINDOWS_APP
# 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
#ifdef HAVE_WS2TCPIP_H
@@ -117,7 +106,7 @@
#include "libssh2.h"
#include "libssh2_publickey.h"
#include "libssh2_sftp.h"
#include "misc.h" /* for the linked list stuff */
#include "misc.h"
#ifndef FALSE
#define FALSE 0

View File

@@ -96,12 +96,8 @@ _libssh2_mbedtls_safe_free(void *buf, int len)
if(!buf)
return;
#ifdef LIBSSH2_CLEAR_MEMORY
if(len > 0)
_libssh2_explicit_zero(buf, len);
#else
(void)len;
#endif
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;
#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);
#endif
}
#endif
/* String buffer */

View File

@@ -38,6 +38,23 @@
* 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_node *last;
struct list_node *first;
@@ -89,7 +106,6 @@ void _libssh2_store_bignum2_bytes(unsigned char **buf,
const unsigned char *bytes,
size_t len);
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);
void _libssh2_string_buf_free(LIBSSH2_SESSION *session,

View File

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

View File

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

View File

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

View File

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