From 239e5dfb7e80b50cab860a915da98593509a8137 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Tue, 3 Nov 2020 20:01:06 +0100 Subject: [PATCH] Replace OPENSSL_cleanse --- src/support/cleanse.cpp | 28 +++++++++++++++++++++++++--- src/support/cleanse.h | 2 ++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/support/cleanse.cpp b/src/support/cleanse.cpp index db39ac9c3..7c58c94fe 100644 --- a/src/support/cleanse.cpp +++ b/src/support/cleanse.cpp @@ -3,11 +3,33 @@ // Distributed under the GPLv3 software license, see the accompanying // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -#include "cleanse.h" +#include -#include +#include + +#if defined(_MSC_VER) +#include // For SecureZeroMemory. +#endif void memory_cleanse(void *ptr, size_t len) { - OPENSSL_cleanse(ptr, len); +#if defined(_MSC_VER) + /* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */ + SecureZeroMemory(ptr, len); +#else + std::memset(ptr, 0, len); + + /* Memory barrier that scares the compiler away from optimizing out the memset. + * + * Quoting Adam Langley in commit ad1907fe73334d6c696c8539646c21b11178f20f + * in BoringSSL (ISC License): + * As best as we can tell, this is sufficient to break any optimisations that + * might try to eliminate "superfluous" memsets. + * This method is used in memzero_explicit() the Linux kernel, too. Its advantage is that it + * is pretty efficient because the compiler can still implement the memset() efficiently, + * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by + * Yang et al. (USENIX Security 2017) for more background. + */ + __asm__ __volatile__("" : : "r"(ptr) : "memory"); +#endif } diff --git a/src/support/cleanse.h b/src/support/cleanse.h index f7bfda283..de5682d6a 100644 --- a/src/support/cleanse.h +++ b/src/support/cleanse.h @@ -8,6 +8,8 @@ #include +/** Secure overwrite a buffer (possibly containing secret data) with zero-bytes. The write + * operation will not be optimized out by the compiler. */ void memory_cleanse(void *ptr, size_t len); #endif // BITCOIN_SUPPORT_CLEANSE_H