Tor  0.4.7.0-alpha-dev
crypto_util.c
Go to the documentation of this file.
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 
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 memwipe(void *mem, uint8_t byte, size_t sz)
56 {
57  if (sz == 0) {
58  return;
59  }
60  /* If sz is nonzero, then mem must not be NULL. */
61  tor_assert(mem != NULL);
62 
63  /* Data this large is likely to be an underflow. */
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  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  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
118 {
119  if (!str)
120  return;
121  memwipe(str, 0, strlen(str));
122  tor_free_(str);
123 }
Utility macros to handle different features and behavior in different compilers.
void tor_str_wipe_and_free_(char *str)
Definition: crypto_util.c:117
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
Headers for log.c.
void tor_free_(void *mem)
Definition: malloc.c:227
#define SIZE_T_CEILING
Definition: torint.h:126
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102