From 477983f4bc14dae3131bd80282a94e1c67695c0d Mon Sep 17 00:00:00 2001 From: Andrew Ayer Date: Wed, 23 Jul 2014 19:32:30 -0700 Subject: [PATCH] Ensure memsets of sensitive memory aren't optimized away --- crypto-openssl.cpp | 3 ++- crypto.cpp | 2 +- key.cpp | 4 ++-- util.cpp | 11 +++++++++++ util.hpp | 1 + 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/crypto-openssl.cpp b/crypto-openssl.cpp index e833ada..6483e86 100644 --- a/crypto-openssl.cpp +++ b/crypto-openssl.cpp @@ -30,6 +30,7 @@ #include "crypto.hpp" #include "key.hpp" +#include "util.hpp" #include #include #include @@ -61,7 +62,7 @@ Aes_ecb_encryptor::~Aes_ecb_encryptor () // Note: Explicit destructor necessary because class contains an auto_ptr // which contains an incomplete type when the auto_ptr is declared. - std::memset(&impl->key, '\0', sizeof(impl->key)); + explicit_memset(&impl->key, '\0', sizeof(impl->key)); } void Aes_ecb_encryptor::encrypt(const unsigned char* plain, unsigned char* cipher) diff --git a/crypto.cpp b/crypto.cpp index f2d9d28..3ae3ecb 100644 --- a/crypto.cpp +++ b/crypto.cpp @@ -43,7 +43,7 @@ Aes_ctr_encryptor::Aes_ctr_encryptor (const unsigned char* raw_key, const unsign Aes_ctr_encryptor::~Aes_ctr_encryptor () { - std::memset(pad, '\0', BLOCK_LEN); + explicit_memset(pad, '\0', BLOCK_LEN); } void Aes_ctr_encryptor::process (const unsigned char* in, unsigned char* out, size_t len) diff --git a/key.cpp b/key.cpp index 552ae38..0ae24b8 100644 --- a/key.cpp +++ b/key.cpp @@ -45,8 +45,8 @@ Key_file::Entry::Entry () { version = 0; - std::memset(aes_key, 0, AES_KEY_LEN); - std::memset(hmac_key, 0, HMAC_KEY_LEN); + explicit_memset(aes_key, 0, AES_KEY_LEN); + explicit_memset(hmac_key, 0, HMAC_KEY_LEN); } void Key_file::Entry::load (std::istream& in) diff --git a/util.cpp b/util.cpp index 84e8253..189e52a 100644 --- a/util.cpp +++ b/util.cpp @@ -81,6 +81,17 @@ void write_be32 (std::ostream& out, uint32_t i) out.write(reinterpret_cast(buffer), 4); } +void* explicit_memset (void* s, int c, std::size_t n) +{ + volatile unsigned char* p = reinterpret_cast(s); + + while (n--) { + *p++ = c; + } + + return s; +} + static void init_std_streams_platform (); // platform-specific initialization void init_std_streams () diff --git a/util.hpp b/util.hpp index 107cdfc..e79d805 100644 --- a/util.hpp +++ b/util.hpp @@ -70,6 +70,7 @@ uint32_t load_be32 (const unsigned char*); void store_be32 (unsigned char*, uint32_t); bool read_be32 (std::istream& in, uint32_t&); void write_be32 (std::ostream& out, uint32_t); +void* explicit_memset (void* s, int c, size_t n); // memset that won't be optimized away void init_std_streams (); mode_t util_umask (mode_t); int util_rename (const char*, const char*);