From ea6006944bc6de9eba8b9fa44cc326005bde5091 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Sat, 7 Sep 2019 13:37:36 -0400 Subject: [PATCH] [mod_auth] http_auth_const_time_memeq improvement employ volatile, which might matter with some compilers (or might not) explicitly check that string lengths match (or else might match string where last char of short string matches repeated chars in longer string) --- src/http_auth.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/http_auth.c b/src/http_auth.c index e9a64f60..d3d3f6dd 100644 --- a/src/http_auth.c +++ b/src/http_auth.c @@ -56,11 +56,22 @@ int http_auth_const_time_memeq (const char *a, const size_t alen, const char *b, /* constant time memory compare, unless compiler figures it out * (similar to mod_secdownload.c:const_time_memeq()) */ /* round to next multiple of 64 to avoid potentially leaking exact - * password length when subject to high precision timing attacks) */ + * password length when subject to high precision timing attacks) + * (not necessary when comparing digests, which have defined lengths) + */ + /* Note: some libs provide similar funcs but might not obscure length, e.g. + * OpenSSL: + * int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len) + * Note: some OS provide similar funcs but might not obscure length, e.g. + * OpenBSD: int timingsafe_bcmp(const void *b1, const void *b2, size_t len) + * NetBSD: int consttime_memequal(void *b1, void *b2, size_t len) + */ + const volatile unsigned char * const av = (const unsigned char *)a; + const volatile unsigned char * const bv = (const unsigned char *)b; size_t lim = ((alen >= blen ? alen : blen) + 0x3F) & ~0x3F; - int diff = 0; + int diff = (alen != blen); /*(never match if string length mismatch)*/ for (size_t i = 0, j = 0; lim; --lim) { - diff |= (a[i] ^ b[j]); + diff |= (av[i] ^ bv[j]); i += (i < alen); j += (j < blen); }