crypto_util.c 3.8 KB

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