# HG changeset patch # User Timo Sirainen # Date 1491914002 -10800 # Node ID 64d17b868bcc3081f661188c90f2ee1d241b8489 # Parent 1c952a42bf12a04e41cf9b0ecb4b94e965e7bc32 auth: Use mem_equals_timing_safe() for all password hash comparisons. It's unlikely these could be used to perform timing attacks, since the attacker would have to have broken MD5/SHA badly enough to be able to quickly generate string that result in wanted hashes. Still, the extra cost is almost nothing and it's always better to be super paranoid! diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/auth-master-connection.c Tue Apr 11 15:33:22 2017 +0300 @@ -117,7 +117,7 @@ client_pid); o_stream_nsend_str(conn->output, t_strdup_printf("FAIL\t%u\n", id)); - } else if (memcmp(client_conn->cookie, cookie, sizeof(cookie)) != 0) { + } else if (!mem_equals_timing_safe(client_conn->cookie, cookie, sizeof(cookie))) { i_error("Master requested auth for client %u with invalid cookie", client_pid); o_stream_nsend_str(conn->output, diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/mech-apop.c --- a/src/auth/mech-apop.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/mech-apop.c Tue Apr 11 15:33:22 2017 +0300 @@ -40,7 +40,7 @@ md5_update(&ctx, credentials, size); md5_final(&ctx, digest); - return memcmp(digest, request->response_digest, 16) == 0; + return mem_equals_timing_safe(digest, request->response_digest, 16); } static void diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/mech-cram-md5.c --- a/src/auth/mech-cram-md5.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/mech-cram-md5.c Tue Apr 11 15:33:22 2017 +0300 @@ -67,7 +67,7 @@ response_hex = binary_to_hex(digest, sizeof(digest)); - if (memcmp(response_hex, request->response, sizeof(digest)*2) != 0) { + if (!mem_equals_timing_safe(response_hex, request->response, sizeof(digest)*2)) { auth_request_log_info(&request->auth_request, AUTH_SUBSYS_MECH, "password mismatch"); return FALSE; diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/mech-digest-md5.c --- a/src/auth/mech-digest-md5.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/mech-digest-md5.c Tue Apr 11 15:33:22 2017 +0300 @@ -208,7 +208,7 @@ if (i == 0) { /* verify response */ - if (memcmp(response_hex, request->response, 32) != 0) { + if (!mem_equals_timing_safe(response_hex, request->response, 32)) { auth_request_log_info(&request->auth_request, AUTH_SUBSYS_MECH, "password mismatch"); diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/mech-gssapi.c --- a/src/auth/mech-gssapi.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/mech-gssapi.c Tue Apr 11 15:33:22 2017 +0300 @@ -274,7 +274,7 @@ const gss_OID_desc *oid2) { return oid1->length == oid2->length && - memcmp(oid1->elements, oid2->elements, oid1->length) == 0; + mem_equals_timing_safe(oid1->elements, oid2->elements, oid1->length); } static int diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/mech-ntlm.c --- a/src/auth/mech-ntlm.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/mech-ntlm.c Tue Apr 11 15:33:22 2017 +0300 @@ -54,7 +54,7 @@ } ntlmssp_v1_response(credentials, request->challenge, lm_response); - return memcmp(lm_response, client_response, LM_RESPONSE_SIZE) == 0; + return mem_equals_timing_safe(lm_response, client_response, LM_RESPONSE_SIZE); } static void @@ -118,8 +118,8 @@ response_length - NTLMSSP_V2_RESPONSE_SIZE, ntlm_v2_response); - return memcmp(ntlm_v2_response, client_response, - NTLMSSP_V2_RESPONSE_SIZE) == 0 ? 1 : -1; + return mem_equals_timing_safe(ntlm_v2_response, client_response, + NTLMSSP_V2_RESPONSE_SIZE) ? 1 : -1; } else { unsigned char ntlm_response[NTLMSSP_RESPONSE_SIZE]; const unsigned char *client_lm_response = @@ -133,8 +133,8 @@ ntlmssp_v1_response(credentials, request->challenge, ntlm_response); - return memcmp(ntlm_response, client_response, - NTLMSSP_RESPONSE_SIZE) == 0 ? 1 : -1; + return mem_equals_timing_safe(ntlm_response, client_response, + NTLMSSP_RESPONSE_SIZE) ? 1 : -1; } } diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/mech-rpa.c --- a/src/auth/mech-rpa.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/mech-rpa.c Tue Apr 11 15:33:22 2017 +0300 @@ -431,7 +431,7 @@ memcpy(request->pwd_md5, credentials, sizeof(request->pwd_md5)); rpa_user_response(request, response); - return memcmp(response, request->user_response, sizeof(response)) == 0; + return mem_equals_timing_safe(response, request->user_response, sizeof(response)); } static void diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/mech-scram-sha1.c --- a/src/auth/mech-scram-sha1.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/mech-scram-sha1.c Tue Apr 11 15:33:22 2017 +0300 @@ -246,7 +246,7 @@ safe_memset(client_key, 0, sizeof(client_key)); safe_memset(client_signature, 0, sizeof(client_signature)); - return memcmp(stored_key, request->stored_key, sizeof(stored_key)) == 0; + return mem_equals_timing_safe(stored_key, request->stored_key, sizeof(stored_key)); } static void credentials_callback(enum passdb_result result, diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/password-scheme-pbkdf2.c --- a/src/auth/password-scheme-pbkdf2.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/password-scheme-pbkdf2.c Tue Apr 11 15:33:22 2017 +0300 @@ -78,5 +78,5 @@ } pbkdf_run(plaintext, salt, rounds, key2); - return memcmp(key1, key2, sizeof(key1)) == 0 ? 1 : 0; + return mem_equals_timing_safe(key1, key2, sizeof(key1)) ? 1 : 0; } diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/password-scheme-scram.c --- a/src/auth/password-scheme-scram.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/password-scheme-scram.c Tue Apr 11 15:33:22 2017 +0300 @@ -125,8 +125,8 @@ /* Calculate StoredKey */ sha1_get_digest(client_key, sizeof(client_key), calculated_stored_key); - ret = memcmp(stored_key, calculated_stored_key, - sizeof(stored_key)) == 0 ? 1 : 0; + ret = mem_equals_timing_safe(stored_key, calculated_stored_key, + sizeof(stored_key)) ? 1 : 0; safe_memset(salted_password, 0, sizeof(salted_password)); safe_memset(client_key, 0, sizeof(client_key)); diff -r 1c952a42bf12 -r 64d17b868bcc src/auth/password-scheme.c --- a/src/auth/password-scheme.c Sun Apr 09 15:31:11 2017 +0300 +++ b/src/auth/password-scheme.c Tue Apr 11 15:33:22 2017 +0300 @@ -99,7 +99,7 @@ s->password_generate(plaintext, user, &generated, &generated_size); ret = size != generated_size ? 0 : - memcmp(generated, raw_password, size) == 0 ? 1 : 0; + mem_equals_timing_safe(generated, raw_password, size) ? 1 : 0; } if (ret == 0) @@ -471,7 +471,7 @@ sha1_loop(&ctx, plaintext, strlen(plaintext)); sha1_loop(&ctx, raw_password + SHA1_RESULTLEN, size - SHA1_RESULTLEN); sha1_result(&ctx, sha1_digest); - return memcmp(sha1_digest, raw_password, SHA1_RESULTLEN) == 0 ? 1 : 0; + return mem_equals_timing_safe(sha1_digest, raw_password, SHA1_RESULTLEN) ? 1 : 0; } static void @@ -513,8 +513,8 @@ sha256_loop(&ctx, raw_password + SHA256_RESULTLEN, size - SHA256_RESULTLEN); sha256_result(&ctx, sha256_digest); - return memcmp(sha256_digest, raw_password, - SHA256_RESULTLEN) == 0 ? 1 : 0; + return mem_equals_timing_safe(sha256_digest, raw_password, + SHA256_RESULTLEN) ? 1 : 0; } static void @@ -556,8 +556,8 @@ sha512_loop(&ctx, raw_password + SHA512_RESULTLEN, size - SHA512_RESULTLEN); sha512_result(&ctx, sha512_digest); - return memcmp(sha512_digest, raw_password, - SHA512_RESULTLEN) == 0 ? 1 : 0; + return mem_equals_timing_safe(sha512_digest, raw_password, + SHA512_RESULTLEN) ? 1 : 0; } static void @@ -598,7 +598,7 @@ md5_update(&ctx, plaintext, strlen(plaintext)); md5_update(&ctx, raw_password + MD5_RESULTLEN, size - MD5_RESULTLEN); md5_final(&ctx, md5_digest); - return memcmp(md5_digest, raw_password, MD5_RESULTLEN) == 0 ? 1 : 0; + return mem_equals_timing_safe(md5_digest, raw_password, MD5_RESULTLEN) ? 1 : 0; } static void