diff options
| author | Roy Marples <roy@marples.name> | 2019-04-26 15:16:44 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2019-04-26 15:16:44 +0100 |
| commit | e33994fe9a89da3d143b1e1f63a47a336328b2c2 (patch) | |
| tree | 2870ae90702b086cb8ea55aaec9f5c71f04e4c36 | |
| parent | 6adf6108ddb8d3e898aa715edfbaab0a900b4f8d (diff) | |
| download | dhcpcd-e33994fe9a89da3d143b1e1f63a47a336328b2c2.tar.xz | |
auth: Use consttime_memequal(3) to compare hashes
This stops any attacker from trying to infer secrets from latency.
Thanks to Maxime Villard <max@m00nbsd.net>
| -rw-r--r-- | auth.c | 2 | ||||
| -rw-r--r-- | compat/consttime_memequal.h | 28 | ||||
| -rwxr-xr-x | configure | 21 |
3 files changed, 50 insertions, 1 deletions
@@ -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 <drochner@NetBSD.org>. + * 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 */ @@ -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 <<EOF >_consttime_memequal.c +#include <string.h> +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 <<EOF >_dprintf.c |
