]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
auth: Use consttime_memequal(3) to compare hashes
authorRoy Marples <roy@marples.name>
Fri, 26 Apr 2019 14:16:44 +0000 (15:16 +0100)
committerRoy Marples <roy@marples.name>
Fri, 26 Apr 2019 14:16:44 +0000 (15:16 +0100)
This stops any attacker from trying to infer secrets from latency.

Thanks to Maxime Villard <max@m00nbsd.net>

auth.c
compat/consttime_memequal.h [new file with mode: 0644]
configure

diff --git a/auth.c b/auth.c
index 45fe9aa57ffc36cc408300ccb6aaba9830bed538..accba8051d6a4fca7888a3dc58a92e47ab982df4 100644 (file)
--- 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 (file)
index 0000000..9830648
--- /dev/null
@@ -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 */
index 3a6304b8b4e29d80dec2f70c821563072c3c452a..448489184896ec229ddd6a37ccb6a6bde6e0dd5d 100755 (executable)
--- 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 <<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