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:
@@ -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
|
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
23
configure.ac
23
configure.ac
@@ -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 ************************************************************
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)")
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/misc.c
12
src/misc.c
@@ -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 */
|
||||||
|
|
||||||
|
|||||||
18
src/misc.h
18
src/misc.h
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
15
src/wincng.c
15
src/wincng.c
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user