Use asm directives to protect OPENSSL_cleanse.
Compilers have a bad habit of removing "superfluous" memset calls that
are trying to zero memory. For example, when memset()ing a buffer and
then free()ing it, the compiler might decide that the memset is
unobservable and thus can be removed.
Previously we tried to stop this by a) implementing memset in assembly
on x86 and b) putting the function in its own file for other platforms.
This change removes those tricks in favour of using asm directives to
scare the compiler away. As best as our compiler folks can tell, this is
sufficient and will continue to be so.
Change-Id: I40e0a62c3043038bafd8c63a91814a75a3c59269
Reviewed-on: https://boringssl-review.googlesource.com/1339
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/mem.c b/crypto/mem.c
index a5f639b..e9c035e 100644
--- a/crypto/mem.c
+++ b/crypto/mem.c
@@ -93,6 +93,19 @@
return ret;
}
+void OPENSSL_cleanse(void *ptr, size_t len) {
+ memset(ptr, 0, len);
+
+ /* As best as we can tell, this is sufficient to break any optimisations that
+ might try to eliminate "superfluous" memsets. If there's an easy way to
+ detect memset_s, it would be better to use that. */
+#if defined(OPENSSL_WINDOWS)
+ __asm;
+#else
+ __asm__ __volatile__("" : : "r"(ptr) : "memory");
+#endif
+}
+
int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) {
size_t i;
const uint8_t *a = in_a;