diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c index f9e1026a12c..761507efc32 100644 --- a/src/backend/libpq/auth-scram.c +++ b/src/backend/libpq/auth-scram.c @@ -542,7 +542,7 @@ scram_verify_plain_password(const char *username, const char *password, * Compare the secret's Server Key with the one computed from the * user-supplied password. */ - return memcmp(computed_key, server_key, SCRAM_KEY_LEN) == 0; + return timingsafe_bcmp(computed_key, server_key, SCRAM_KEY_LEN) == 0; } @@ -1082,9 +1082,9 @@ verify_final_nonce(scram_state *state) if (final_nonce_len != client_nonce_len + server_nonce_len) return false; - if (memcmp(state->client_final_nonce, state->client_nonce, client_nonce_len) != 0) + if (timingsafe_bcmp(state->client_final_nonce, state->client_nonce, client_nonce_len) != 0) return false; - if (memcmp(state->client_final_nonce + client_nonce_len, state->server_nonce, server_nonce_len) != 0) + if (timingsafe_bcmp(state->client_final_nonce + client_nonce_len, state->server_nonce, server_nonce_len) != 0) return false; return true; @@ -1136,7 +1136,7 @@ verify_client_proof(scram_state *state) if (scram_H(ClientKey, SCRAM_KEY_LEN, client_StoredKey) < 0) elog(ERROR, "could not hash stored key"); - if (memcmp(client_StoredKey, state->StoredKey, SCRAM_KEY_LEN) != 0) + if (timingsafe_bcmp(client_StoredKey, state->StoredKey, SCRAM_KEY_LEN) != 0) return false; return true; diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index a7b91053dfd..f07ba8bb2fe 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -3469,7 +3469,7 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por } pfree(cryptvector); - if (memcmp(receivepacket->vector, encryptedpassword, RADIUS_VECTOR_LENGTH) != 0) + if (timingsafe_bcmp(receivepacket->vector, encryptedpassword, RADIUS_VECTOR_LENGTH) != 0) { ereport(LOG, (errmsg("RADIUS response from %s has incorrect MD5 signature", diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index 3fcad991a7e..69a7c67e716 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -196,7 +196,8 @@ md5_crypt_verify(const char *role, const char *shadow_pass, return STATUS_ERROR; } - if (strcmp(client_pass, crypt_pwd) == 0) + if (strlen(client_pass) == strlen(crypt_pwd) && + timingsafe_bcmp(client_pass, crypt_pwd, strlen(crypt_pwd)) == 0) retval = STATUS_OK; else { @@ -261,7 +262,8 @@ plain_crypt_verify(const char *role, const char *shadow_pass, */ return STATUS_ERROR; } - if (strcmp(crypt_client_pass, shadow_pass) == 0) + if (strlen(crypt_client_pass) == strlen(shadow_pass) && + timingsafe_bcmp(crypt_client_pass, shadow_pass, strlen(shadow_pass)) == 0) return STATUS_OK; else { diff --git a/src/interfaces/libpq/fe-auth-scram.c b/src/interfaces/libpq/fe-auth-scram.c index cf3195e5815..f44fc2594f9 100644 --- a/src/interfaces/libpq/fe-auth-scram.c +++ b/src/interfaces/libpq/fe-auth-scram.c @@ -628,7 +628,7 @@ read_server_first_message(fe_scram_state *state, char *input) /* Verify immediately that the server used our part of the nonce */ if (strlen(nonce) < strlen(state->client_nonce) || - memcmp(nonce, state->client_nonce, strlen(state->client_nonce)) != 0) + timingsafe_bcmp(nonce, state->client_nonce, strlen(state->client_nonce)) != 0) { appendPQExpBufferStr(&conn->errorMessage, libpq_gettext("invalid SCRAM response (nonce mismatch)\n")); @@ -857,7 +857,8 @@ verify_server_signature(fe_scram_state *state, bool *match) pg_hmac_free(ctx); /* signature processed, so now check after it */ - if (memcmp(expected_ServerSignature, state->ServerSignature, SCRAM_KEY_LEN) != 0) + if (timingsafe_bcmp(expected_ServerSignature, state->ServerSignature, + SCRAM_KEY_LEN) != 0) *match = false; else *match = true;