summaryrefslogtreecommitdiff
path: root/src/ck.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2021-10-18 10:59:57 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2021-10-27 04:16:38 -0400
commit9d05b648ee415177a71c12f00ad899ea7703eaed (patch)
tree896405d56ab4af5bf2fb51ec5fff4a34a8f73c39 /src/ck.c
parent14b8d90288e4f69cf5430040ad6397adbad3e588 (diff)
downloadlighttpd-git-9d05b648ee415177a71c12f00ad899ea7703eaed.tar.gz
[core] make ck_memeq_const_time() more generic (#3112)
make ck_memeq_const_time() more generically reusable remove implementation requirements that strings be '\0' terminated, or at least have an initialized byte following each string (s[len]) x-ref: https://redmine.lighttpd.net/issues/3112 "mod_auth cache password doesn't match"
Diffstat (limited to 'src/ck.c')
-rw-r--r--src/ck.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/src/ck.c b/src/ck.c
index 212c0858..437eb0c5 100644
--- a/src/ck.c
+++ b/src/ck.c
@@ -264,17 +264,12 @@ ck_strerror_s (char * const s, const rsize_t maxsize, const errno_t errnum)
int
-ck_memeq_const_time (const void *a, const size_t alen, const void *b, const size_t blen)
+ck_memeq_const_time (const void *a, size_t alen, const void *b, size_t blen)
{
/* constant time memory compare for equality */
/* rounds to next multiple of 64 to avoid potentially leaking exact
* string lengths when subject to high precision timing attacks
*/
- /* Note: implementation detail
- * each string is expected to have a valid char one byte after len,
- * i.e. a[alen] and b[blen], and which must match if the strings match.
- * (In most use cases, this char is end of string '\0').
- */
/* 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)
@@ -282,10 +277,14 @@ ck_memeq_const_time (const void *a, const size_t alen, const void *b, const size
* 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;
+ const volatile unsigned char * const av =
+ (const unsigned char *)(alen ? a : "");
+ const volatile unsigned char * const bv =
+ (const unsigned char *)(blen ? b : "");
size_t lim = ((alen >= blen ? alen : blen) + 0x3F) & ~0x3F;
int diff = (alen != blen); /*(never match if string length mismatch)*/
+ alen -= (alen != 0);
+ blen -= (blen != 0);
for (size_t i = 0, j = 0; lim; --lim) {
diff |= (av[i] ^ bv[j]);
i += (i < alen);