mirror of
https://github.com/znc/znc.git
synced 2026-08-06 17:03:14 +02:00
Utils: prefer CRYPTO_memcmp in ConstantTimeEquals when OpenSSL is available
Per review feedback on #2017: a hand-rolled byte loop can in principle be folded back into a short-circuiting compare by an aggressive optimizer. Use CRYPTO_memcmp under HAVE_LIBSSL since OpenSSL is already a build dependency for the SHA256 path. For non-OpenSSL builds, mark the accumulator and pointers volatile and note in a comment that this is best-effort.
This commit is contained in:
+13
-3
@@ -28,6 +28,7 @@
|
||||
#ifdef HAVE_LIBSSL
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/rsa.h>
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x20700000L))
|
||||
#define X509_getm_notBefore X509_get_notBefore
|
||||
@@ -279,13 +280,22 @@ bool CUtils::ConstantTimeEquals(const CString& a, const CString& b) {
|
||||
if (a.length() != b.length()) {
|
||||
return false;
|
||||
}
|
||||
unsigned char acc = 0;
|
||||
const unsigned char* pa = reinterpret_cast<const unsigned char*>(a.data());
|
||||
const unsigned char* pb = reinterpret_cast<const unsigned char*>(b.data());
|
||||
#ifdef HAVE_LIBSSL
|
||||
return CRYPTO_memcmp(a.data(), b.data(), a.length()) == 0;
|
||||
#else
|
||||
// Best-effort fallback when OpenSSL is unavailable: an optimizer is
|
||||
// in principle allowed to short-circuit this loop, so the volatile
|
||||
// accumulator and pointers are a hint rather than a guarantee.
|
||||
volatile unsigned char acc = 0;
|
||||
const volatile unsigned char* pa =
|
||||
reinterpret_cast<const volatile unsigned char*>(a.data());
|
||||
const volatile unsigned char* pb =
|
||||
reinterpret_cast<const volatile unsigned char*>(b.data());
|
||||
for (size_t i = 0; i < a.length(); ++i) {
|
||||
acc |= static_cast<unsigned char>(pa[i] ^ pb[i]);
|
||||
}
|
||||
return acc == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
CString CUtils::GetPass(const CString& sPrompt) {
|
||||
|
||||
Reference in New Issue
Block a user