crypto_util.c (4103B)
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 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. */ 64 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 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 117 tor_str_wipe_and_free_(char *str) 118 { 119 if (!str) 120 return; 121 memwipe(str, 0, strlen(str)); 122 tor_free_(str); 123 }