Add string ctrl operations to TLS1 PRF, update documentation.
[openssl.git] / crypto / cryptlib.c
index 14a84243c646aee63c46bc3fb051eda586e1717e..8052893db233afed2682cbb2b4bbaf16051affea 100644 (file)
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
 
-#include "internal/cryptlib.h"
+#include "internal/cryptlib_int.h"
 #include <openssl/safestack.h>
 
 #if     defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
@@ -210,6 +210,7 @@ void OPENSSL_cpuid_setup(void)
  * detaches
  */
 
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
     switch (fdwReason) {
@@ -234,6 +235,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
     case DLL_THREAD_ATTACH:
         break;
     case DLL_THREAD_DETACH:
+        OPENSSL_thread_stop();
         break;
     case DLL_PROCESS_DETACH:
         break;
@@ -465,11 +467,30 @@ void OpenSSLDie(const char *file, int line, const char *assertion)
 #endif
 }
 
-int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
+/* volatile unsigned char* pointers are there because
+ * 1. Accessing a variable declared volatile via a pointer
+ *    that lacks a volatile qualifier causes undefined behavior.
+ * 2. When the variable itself is not volatile the compiler is
+ *    not required to keep all those reads and can convert
+ *    this into canonical memcmp() which doesn't read the whole block.
+ * Pointers to volatile resolve the first problem fully. The second
+ * problem cannot be resolved in any Standard-compliant way but this
+ * works the problem around. Compilers typically react to
+ * pointers to volatile by preserving the reads and writes through them.
+ * The latter is not required by the Standard if the memory pointed to
+ * is not volatile.
+ * Pointers themselves are volatile in the function signature to work
+ * around a subtle bug in gcc 4.6+ which causes writes through
+ * pointers to volatile to not be emitted in some rare,
+ * never needed in real life, pieces of code.
+ */
+int CRYPTO_memcmp(const volatile void * volatile in_a,
+                  const volatile void * volatile in_b,
+                  size_t len)
 {
     size_t i;
-    const unsigned char *a = in_a;
-    const unsigned char *b = in_b;
+    const volatile unsigned char *a = in_a;
+    const volatile unsigned char *b = in_b;
     unsigned char x = 0;
 
     for (i = 0; i < len; i++)