Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -668,6 +668,10 @@ buf_read_u32 (struct buffer *buf, bool *good) |
668 | 668 |
} |
669 | 669 |
} |
670 | 670 |
|
671 |
+/** |
|
672 |
+ * Compare src buffer contents with match. |
|
673 |
+ * *NOT* constant time. Do not use when comparing HMACs. |
|
674 |
+ */ |
|
671 | 675 |
static inline bool |
672 | 676 |
buf_string_match (const struct buffer *src, const void *match, int size) |
673 | 677 |
{ |
... | ... |
@@ -676,6 +680,10 @@ buf_string_match (const struct buffer *src, const void *match, int size) |
676 | 676 |
return memcmp (BPTR (src), match, size) == 0; |
677 | 677 |
} |
678 | 678 |
|
679 |
+/** |
|
680 |
+ * Compare first size bytes of src buffer contents with match. |
|
681 |
+ * *NOT* constant time. Do not use when comparing HMACs. |
|
682 |
+ */ |
|
679 | 683 |
static inline bool |
680 | 684 |
buf_string_match_head (const struct buffer *src, const void *match, int size) |
681 | 685 |
{ |
... | ... |
@@ -65,6 +65,24 @@ |
65 | 65 |
#define CRYPT_ERROR(format) \ |
66 | 66 |
do { msg (D_CRYPT_ERRORS, "%s: " format, error_prefix); goto error_exit; } while (false) |
67 | 67 |
|
68 |
+/** |
|
69 |
+ * As memcmp(), but constant-time. |
|
70 |
+ * Returns 0 when data is equal, non-zero otherwise. |
|
71 |
+ */ |
|
72 |
+static int |
|
73 |
+memcmp_constant_time (const void *a, const void *b, size_t size) { |
|
74 |
+ const uint8_t * a1 = a; |
|
75 |
+ const uint8_t * b1 = b; |
|
76 |
+ int ret = 0; |
|
77 |
+ size_t i; |
|
78 |
+ |
|
79 |
+ for (i = 0; i < size; i++) { |
|
80 |
+ ret |= *a1++ ^ *b1++; |
|
81 |
+ } |
|
82 |
+ |
|
83 |
+ return ret; |
|
84 |
+} |
|
85 |
+ |
|
68 | 86 |
void |
69 | 87 |
openvpn_encrypt (struct buffer *buf, struct buffer work, |
70 | 88 |
const struct crypto_options *opt, |
... | ... |
@@ -244,7 +262,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, |
244 | 244 |
hmac_ctx_final (ctx->hmac, local_hmac); |
245 | 245 |
|
246 | 246 |
/* Compare locally computed HMAC with packet HMAC */ |
247 |
- if (memcmp (local_hmac, BPTR (buf), hmac_len)) |
|
247 |
+ if (memcmp_constant_time (local_hmac, BPTR (buf), hmac_len)) |
|
248 | 248 |
CRYPT_ERROR ("packet HMAC authentication failed"); |
249 | 249 |
|
250 | 250 |
ASSERT (buf_advance (buf, hmac_len)); |