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 : }
|