LCOV - code coverage report
Current view: top level - lib/crypt_ops - crypto_util.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 10 10 100.0 %
Date: 2021-11-24 03:28:48 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2001, Matej Pfajfar.
       2             :  * Copyright (c) 2001-2004, Roger Dingledine.
       3             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       4             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       5             : /* See LICENSE for licensing information */
       6             : 
       7             : /**
       8             :  * \file crypto_util.c
       9             :  *
      10             :  * \brief Common cryptographic utilities.
      11             :  **/
      12             : 
      13             : #include "lib/crypt_ops/crypto_util.h"
      14             : #include "lib/cc/compat_compiler.h"
      15             : 
      16             : #include <string.h>
      17             : 
      18             : #ifdef _WIN32
      19             : #include <winsock2.h>
      20             : #include <windows.h>
      21             : #include <wincrypt.h>
      22             : #endif /* defined(_WIN32) */
      23             : 
      24             : #include <stdlib.h>
      25             : 
      26             : #ifdef ENABLE_OPENSSL
      27             : DISABLE_GCC_WARNING("-Wredundant-decls")
      28             : #include <openssl/err.h>
      29             : #include <openssl/crypto.h>
      30             : ENABLE_GCC_WARNING("-Wredundant-decls")
      31             : #endif /* defined(ENABLE_OPENSSL) */
      32             : 
      33             : #include "lib/log/log.h"
      34             : #include "lib/log/util_bug.h"
      35             : 
      36             : /**
      37             :  * Destroy the <b>sz</b> bytes of data stored at <b>mem</b>, setting them to
      38             :  * the value <b>byte</b>.
      39             :  * If <b>mem</b> is NULL or <b>sz</b> is zero, nothing happens.
      40             :  *
      41             :  * This function is preferable to memset, since many compilers will happily
      42             :  * optimize out memset() when they can convince themselves that the data being
      43             :  * cleared will never be read.
      44             :  *
      45             :  * Right now, our convention is to use this function when we are wiping data
      46             :  * that's about to become inaccessible, such as stack buffers that are about
      47             :  * to go out of scope or structures that are about to get freed.  (In
      48             :  * practice, it appears that the compilers we're currently using will optimize
      49             :  * out the memset()s for stack-allocated buffers, but not those for
      50             :  * about-to-be-freed structures. That could change, though, so we're being
      51             :  * wary.)  If there are live reads for the data, then you can just use
      52             :  * memset().
      53             :  */
      54             : void
      55      459736 : memwipe(void *mem, uint8_t byte, size_t sz)
      56             : {
      57      459736 :   if (sz == 0) {
      58             :     return;
      59             :   }
      60             :   /* If sz is nonzero, then mem must not be NULL. */
      61      445930 :   tor_assert(mem != NULL);
      62             : 
      63             :   /* Data this large is likely to be an underflow. */
      64      445930 :   tor_assert(sz < SIZE_T_CEILING);
      65             : 
      66             :   /* Because whole-program-optimization exists, we may not be able to just
      67             :    * have this function call "memset".  A smart compiler could inline it, then
      68             :    * eliminate dead memsets, and declare itself to be clever. */
      69             : 
      70             : #if defined(SecureZeroMemory) || defined(HAVE_SECUREZEROMEMORY)
      71             :   /* Here's what you do on windows. */
      72             :   SecureZeroMemory(mem,sz);
      73             : #elif defined(HAVE_RTLSECUREZEROMEMORY)
      74             :   RtlSecureZeroMemory(mem,sz);
      75             : #elif defined(HAVE_EXPLICIT_BZERO)
      76             :   /* The BSDs provide this. */
      77      445930 :   explicit_bzero(mem, sz);
      78             : #elif defined(HAVE_MEMSET_S)
      79             :   /* This is in the C99 standard. */
      80             :   memset_s(mem, sz, 0, sz);
      81             : #elif defined(ENABLE_OPENSSL)
      82             :   /* This is a slow and ugly function from OpenSSL that fills 'mem' with junk
      83             :    * based on the pointer value, then uses that junk to update a global
      84             :    * variable.  It's an elaborate ruse to trick the compiler into not
      85             :    * optimizing out the "wipe this memory" code.  Read it if you like zany
      86             :    * programming tricks! In later versions of Tor, we should look for better
      87             :    * not-optimized-out memory wiping stuff...
      88             :    *
      89             :    * ...or maybe not.  In practice, there are pure-asm implementations of
      90             :    * OPENSSL_cleanse() on most platforms, which ought to do the job.
      91             :    **/
      92             : 
      93             :   OPENSSL_cleanse(mem, sz);
      94             : #else
      95             :   memset(mem, 0, sz);
      96             :   asm volatile("" ::: "memory");
      97             : #endif /* defined(SecureZeroMemory) || defined(HAVE_SECUREZEROMEMORY) || ... */
      98             : 
      99             :   /* Just in case some caller of memwipe() is relying on getting a buffer
     100             :    * filled with a particular value, fill the buffer.
     101             :    *
     102             :    * If this function gets inlined, this memset might get eliminated, but
     103             :    * that's okay: We only care about this particular memset in the case where
     104             :    * the caller should have been using memset(), and the memset() wouldn't get
     105             :    * eliminated.  In other words, this is here so that we won't break anything
     106             :    * if somebody accidentally calls memwipe() instead of memset().
     107             :    **/
     108      445871 :   memset(mem, byte, sz);
     109             : }
     110             : 
     111             : /**
     112             :  * Securely all memory in <b>str</b>, then free it.
     113             :  *
     114             :  * As tor_free(), tolerates null pointers.
     115             :  **/
     116             : void
     117         504 : tor_str_wipe_and_free_(char *str)
     118             : {
     119         504 :   if (!str)
     120             :     return;
     121         177 :   memwipe(str, 0, strlen(str));
     122         177 :   tor_free_(str);
     123             : }

Generated by: LCOV version 1.14