aboutsummaryrefslogtreecommitdiff
path: root/crypto/cryptlib.c
diff options
context:
space:
mode:
authorDmitry-Me <wipedout@yandex.ru>2016-02-01 11:48:28 +0300
committerRich Salz <rsalz@openssl.org>2016-02-01 08:32:58 -0500
commiteb507efba8e2333a284a2a79638f729bdc35c502 (patch)
tree82eb78d6cb926059213f092e952d246834943ba9 /crypto/cryptlib.c
parent995197ab84901df1cdf83509c4ce3511ea7f5ec0 (diff)
downloadopenssl-eb507efba8e2333a284a2a79638f729bdc35c502.zip
openssl-eb507efba8e2333a284a2a79638f729bdc35c502.tar.gz
openssl-eb507efba8e2333a284a2a79638f729bdc35c502.tar.bz2
Comment "secure memcmp" implementation
Signed-off-by: Rich Salz <rsalz@openssl.org> Reviewed-by: Tim Hudson <tjh@openssl.org>
Diffstat (limited to 'crypto/cryptlib.c')
-rw-r--r--crypto/cryptlib.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c
index d317340..bd58d35 100644
--- a/crypto/cryptlib.c
+++ b/crypto/cryptlib.c
@@ -465,6 +465,23 @@ void OpenSSLDie(const char *file, int line, const char *assertion)
#endif
}
+/* 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)