mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-12 06:03:43 +01:00
fe3aca1491
* ADD new /src/common/crypto_rand.[ch] module. * ADD new /src/common/crypto_util.[ch] module (contains the memwipe() function, since all crypto_* modules need this). * FIXES part of #24658: https://bugs.torproject.org/24658
106 lines
3.6 KiB
C
106 lines
3.6 KiB
C
/* Copyright (c) 2001, Matej Pfajfar.
|
|
* Copyright (c) 2001-2004, Roger Dingledine.
|
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
|
* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
|
/* See LICENSE for licensing information */
|
|
|
|
/**
|
|
* \file crypto_util.c
|
|
*
|
|
* \brief Common cryptographic utilities.
|
|
**/
|
|
|
|
#ifndef CRYPTO_UTIL_PRIVATE
|
|
#define CRYPTO_UTIL_PRIVATE
|
|
|
|
#include <string.h>
|
|
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#include <wincrypt.h>
|
|
#endif /* defined(_WIN32) */
|
|
|
|
#include "crypto_util.h"
|
|
#include "util.h"
|
|
|
|
DISABLE_GCC_WARNING(redundant-decls)
|
|
|
|
#include <openssl/crypto.h>
|
|
|
|
ENABLE_GCC_WARNING(redundant-decls)
|
|
|
|
/**
|
|
* Destroy the <b>sz</b> bytes of data stored at <b>mem</b>, setting them to
|
|
* the value <b>byte</b>.
|
|
* If <b>mem</b> is NULL or <b>sz</b> is zero, nothing happens.
|
|
*
|
|
* This function is preferable to memset, since many compilers will happily
|
|
* optimize out memset() when they can convince themselves that the data being
|
|
* cleared will never be read.
|
|
*
|
|
* Right now, our convention is to use this function when we are wiping data
|
|
* that's about to become inaccessible, such as stack buffers that are about
|
|
* to go out of scope or structures that are about to get freed. (In
|
|
* practice, it appears that the compilers we're currently using will optimize
|
|
* out the memset()s for stack-allocated buffers, but not those for
|
|
* about-to-be-freed structures. That could change, though, so we're being
|
|
* wary.) If there are live reads for the data, then you can just use
|
|
* memset().
|
|
*/
|
|
void
|
|
memwipe(void *mem, uint8_t byte, size_t sz)
|
|
{
|
|
if (sz == 0) {
|
|
return;
|
|
}
|
|
/* If sz is nonzero, then mem must not be NULL. */
|
|
tor_assert(mem != NULL);
|
|
|
|
/* Data this large is likely to be an underflow. */
|
|
tor_assert(sz < SIZE_T_CEILING);
|
|
|
|
/* Because whole-program-optimization exists, we may not be able to just
|
|
* have this function call "memset". A smart compiler could inline it, then
|
|
* eliminate dead memsets, and declare itself to be clever. */
|
|
|
|
#if defined(SecureZeroMemory) || defined(HAVE_SECUREZEROMEMORY)
|
|
/* Here's what you do on windows. */
|
|
SecureZeroMemory(mem,sz);
|
|
#elif defined(HAVE_RTLSECUREZEROMEMORY)
|
|
RtlSecureZeroMemory(mem,sz);
|
|
#elif defined(HAVE_EXPLICIT_BZERO)
|
|
/* The BSDs provide this. */
|
|
explicit_bzero(mem, sz);
|
|
#elif defined(HAVE_MEMSET_S)
|
|
/* This is in the C99 standard. */
|
|
memset_s(mem, sz, 0, sz);
|
|
#else
|
|
/* This is a slow and ugly function from OpenSSL that fills 'mem' with junk
|
|
* based on the pointer value, then uses that junk to update a global
|
|
* variable. It's an elaborate ruse to trick the compiler into not
|
|
* optimizing out the "wipe this memory" code. Read it if you like zany
|
|
* programming tricks! In later versions of Tor, we should look for better
|
|
* not-optimized-out memory wiping stuff...
|
|
*
|
|
* ...or maybe not. In practice, there are pure-asm implementations of
|
|
* OPENSSL_cleanse() on most platforms, which ought to do the job.
|
|
**/
|
|
|
|
OPENSSL_cleanse(mem, sz);
|
|
#endif /* defined(SecureZeroMemory) || defined(HAVE_SECUREZEROMEMORY) || ... */
|
|
|
|
/* Just in case some caller of memwipe() is relying on getting a buffer
|
|
* filled with a particular value, fill the buffer.
|
|
*
|
|
* If this function gets inlined, this memset might get eliminated, but
|
|
* that's okay: We only care about this particular memset in the case where
|
|
* the caller should have been using memset(), and the memset() wouldn't get
|
|
* eliminated. In other words, this is here so that we won't break anything
|
|
* if somebody accidentally calls memwipe() instead of memset().
|
|
**/
|
|
memset(mem, byte, sz);
|
|
}
|
|
|
|
#endif /* !defined(CRYPTO_UTIL_PRIVATE) */
|
|
|