From e33994fe9a89da3d143b1e1f63a47a336328b2c2 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Fri, 26 Apr 2019 15:16:44 +0100 Subject: [PATCH] auth: Use consttime_memequal(3) to compare hashes This stops any attacker from trying to infer secrets from latency. Thanks to Maxime Villard --- auth.c | 2 +- compat/consttime_memequal.h | 28 ++++++++++++++++++++++++++++ configure | 21 +++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 compat/consttime_memequal.h diff --git a/auth.c b/auth.c index 45fe9aa5..accba805 100644 --- a/auth.c +++ b/auth.c @@ -336,7 +336,7 @@ gottoken: } free(mm); - if (memcmp(d, &hmac, dlen)) { + if (consttime_memequal(d, &hmac, dlen)) { errno = EPERM; return NULL; } diff --git a/compat/consttime_memequal.h b/compat/consttime_memequal.h new file mode 100644 index 00000000..98306484 --- /dev/null +++ b/compat/consttime_memequal.h @@ -0,0 +1,28 @@ +/* + * Written by Matthias Drochner . + * Public domain. + */ + +#ifndef CONSTTIME_MEMEQUAL_H +#define CONSTTIME_MEMEQUAL_H +inline static int +consttime_memequal(const void *b1, const void *b2, size_t len) +{ + const unsigned char *c1 = b1, *c2 = b2; + unsigned int res = 0; + + while (len--) + res |= *c1++ ^ *c2++; + + /* + * Map 0 to 1 and [1, 256) to 0 using only constant-time + * arithmetic. + * + * This is not simply `!res' because although many CPUs support + * branchless conditional moves and many compilers will take + * advantage of them, certain compilers generate branches on + * certain CPUs for `!res'. + */ + return (1 & ((res - 1) >> 8)); +} +#endif /* CONSTTIME_MEMEQUAL_H */ diff --git a/configure b/configure index 3a6304b8..44848918 100755 --- a/configure +++ b/configure @@ -820,6 +820,27 @@ if [ "$STRTOI" = no ]; then echo "#include \"compat/strtoi.h\"" >>$CONFIG_H fi +if [ -z "$CONSTTIME_MEMEQUAL" ]; then + printf "Testing for consttime_memequal ... " + cat <_consttime_memequal.c +#include +int main(void) { + return consttime_memequal("deadbeef", "deadbeef", 8); +} +EOF + if $XCC _consttime_memequal.c -o _consttime_memequal 2>&3; then + CONSTTIME_MEMEQUAL=yes + else + CONSTTIME_MEMEQUAL=no + fi + echo "$CONSTTIME_MEMEQUAL" + rm -f _consttime_memequal.c _consttime_memequal +fi +if [ "$CONSTTIME_MEMEQUAL" = no ]; then + echo "#include \"compat/consttime_memequal.h\"" \ + >>$CONFIG_H +fi + if [ -z "$DPRINTF" ]; then printf "Testing for dprintf ... " cat <_dprintf.c -- 2.47.2