changeset 21952:e19e015f7449

auth: Make plaintext password comparisons safe against timing attacks
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Sun, 09 Apr 2017 00:50:15 +0300
parents 3ef988b95d96
children ec6539bd0690
files src/auth/password-scheme.c
diffstat 1 files changed, 17 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/password-scheme.c	Sun Apr 09 00:49:37 2017 +0300
+++ b/src/auth/password-scheme.c	Sun Apr 09 00:50:15 2017 +0300
@@ -610,6 +610,18 @@
 }
 
 static int
+plain_verify(const char *plaintext, const char *user ATTR_UNUSED,
+	     const unsigned char *raw_password, size_t size,
+	     const char **error_r ATTR_UNUSED)
+{
+	size_t plaintext_len = strlen(plaintext);
+
+	if (plaintext_len != size)
+		return 0;
+	return mem_equals_timing_safe(plaintext, raw_password, size) ? 1 : 0;
+}
+
+static int
 plain_trunc_verify(const char *plaintext, const char *user ATTR_UNUSED,
 		   const unsigned char *raw_password, size_t size,
 		   const char **error_r)
@@ -633,10 +645,10 @@
 	if (size-i == trunc_len && plaintext_len >= trunc_len) {
 		/* possibly truncated password. allow the given password as
 		   long as the prefix matches. */
-		return memcmp(raw_password+i, plaintext, trunc_len) == 0 ? 1 : 0;
+		return mem_equals_timing_safe(raw_password+i, plaintext, trunc_len) ? 1 : 0;
 	}
 	return plaintext_len == size-i &&
-		memcmp(raw_password+i, plaintext, plaintext_len) == 0 ? 1 : 0;
+		mem_equals_timing_safe(raw_password+i, plaintext, plaintext_len) ? 1 : 0;
 }
 
 static void
@@ -803,9 +815,9 @@
 	{ "SSHA", PW_ENCODING_BASE64, 0, ssha_verify, ssha_generate },
 	{ "SSHA256", PW_ENCODING_BASE64, 0, ssha256_verify, ssha256_generate },
 	{ "SSHA512", PW_ENCODING_BASE64, 0, ssha512_verify, ssha512_generate },
-	{ "PLAIN", PW_ENCODING_NONE, 0, NULL, plain_generate },
-	{ "CLEAR", PW_ENCODING_NONE, 0, NULL, plain_generate },
-	{ "CLEARTEXT", PW_ENCODING_NONE, 0, NULL, plain_generate },
+	{ "PLAIN", PW_ENCODING_NONE, 0, plain_verify, plain_generate },
+	{ "CLEAR", PW_ENCODING_NONE, 0, plain_verify, plain_generate },
+	{ "CLEARTEXT", PW_ENCODING_NONE, 0, plain_verify, plain_generate },
 	{ "PLAIN-TRUNC", PW_ENCODING_NONE, 0, plain_trunc_verify, plain_generate },
 	{ "CRAM-MD5", PW_ENCODING_HEX, CRAM_MD5_CONTEXTLEN,
 	  NULL, cram_md5_generate },