Project

General

Profile

diff

devnexen, 2019-08-24 14:04

 
1
diff --git a/src/mod_authn_file.c b/src/mod_authn_file.c
2
index 1e16075e..174a4c78 100644
3
--- a/src/mod_authn_file.c
4
+++ b/src/mod_authn_file.c
5
@@ -356,7 +356,7 @@ static handler_t mod_authn_file_htdigest_basic(server *srv, connection *con, voi
6
 
7
     mod_authn_file_digest(&ai, pw, strlen(pw));
8
 
9
-    return (0 == memcmp(htdigest, ai.digest, ai.dlen)
10
+    return (0 == safe_memcmp(htdigest, ai.digest, ai.dlen)
11
             && http_auth_match_rules(require, username->ptr, NULL, NULL))
12
       ? HANDLER_GO_ON
13
       : HANDLER_ERROR;
14
diff --git a/src/safe_memclear.c b/src/safe_memclear.c
15
index 15617a46..1072c86d 100644
16
--- a/src/safe_memclear.c
17
+++ b/src/safe_memclear.c
18
@@ -47,3 +47,21 @@ void safe_memclear(void *s, size_t n) {
19
 	safe_memset(s, 0, n);
20
 #endif
21
 }
22
+
23
+// Safer version of memcmp against timing attacks,
24
+// the volatile pragma guaranting it.
25
+// Semantically different than its counterpart though
26
+// as not a real comparison call but bytes differences counting.
27
+int safe_memcmp(const void *a, const void *b, size_t n) {
28
+	const volatile uint8_t *ua = (const volatile uint8_t *)a;
29
+	const volatile uint8_t *ub = (const volatile uint8_t *)b;
30
+	uint8_t res = 0;
31
+	int d = n;
32
+
33
+	while (d >= 0) {
34
+		--d;
35
+		res |= ua[d] ^ ub[d];
36
+	}
37
+
38
+	return (int)res;
39
+}
40
diff --git a/src/safe_memclear.h b/src/safe_memclear.h
41
index 9fd25636..dc590c5e 100644
42
--- a/src/safe_memclear.h
43
+++ b/src/safe_memclear.h
44
@@ -3,5 +3,6 @@
45
 #include "first.h"
46
 
47
 void safe_memclear(void *s, size_t n);
48
+int safe_memcmp(const void *a, const void *b, size_t n);
49
 
50
 #endif