summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Sutton <josephsutton@catalyst.net.nz>2022-02-17 15:35:42 +1300
committerAndrew Bartlett <abartlet@samba.org>2022-06-09 22:49:29 +0000
commitae6634c78774d2368e815dea650ba71650dd1861 (patch)
treebf361a9acf1e5eb9595b25adea734d303bad31c4
parent87f68500ed651f393e2fc6c514ab08b561a60a9b (diff)
downloadsamba-ae6634c78774d2368e815dea650ba71650dd1861.tar.gz
auth: Use constant-time memcmp when comparing sensitive buffers
This helps to avoid timing attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15010 Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-rw-r--r--auth/gensec/schannel.c4
-rw-r--r--auth/ntlmssp/ntlmssp_ndr.c2
-rw-r--r--auth/ntlmssp/ntlmssp_server.c4
-rw-r--r--auth/ntlmssp/ntlmssp_sign.c4
-rw-r--r--lib/util/data_blob.c24
-rw-r--r--lib/util/data_blob.h6
-rw-r--r--libcli/auth/credentials.c4
-rw-r--r--libcli/auth/netlogon_creds_cli.c10
-rw-r--r--libcli/auth/ntlm_check.c8
-rw-r--r--libcli/smb/smbXcli_base.c6
-rw-r--r--libcli/smb/smb_signing.c4
-rw-r--r--source3/librpc/crypto/gse_krb5.c4
-rw-r--r--source3/passdb/machine_account_secrets.c12
-rw-r--r--source3/rpc_client/cli_netlogon.c12
-rw-r--r--source3/rpc_server/netlogon/srv_netlog_nt.c4
-rw-r--r--source3/rpc_server/samr/srv_samr_chgpasswd.c18
-rw-r--r--source3/winbindd/winbindd_dual_srv.c12
-rw-r--r--source3/winbindd/winbindd_pam.c8
-rw-r--r--source4/auth/ntlm/auth_sam.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/password_hash.c6
-rw-r--r--source4/libcli/raw/smb_signing.c2
-rw-r--r--source4/rpc_server/backupkey/dcesrv_backupkey.c6
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c4
-rw-r--r--source4/rpc_server/samr/samr_password.c2
24 files changed, 99 insertions, 69 deletions
diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c
index 6ebbe8f3179..2fbfb019124 100644
--- a/auth/gensec/schannel.c
+++ b/auth/gensec/schannel.c
@@ -649,7 +649,7 @@ static NTSTATUS netsec_incoming_packet(struct schannel_state *state,
return NT_STATUS_ACCESS_DENIED;
}
- ret = memcmp(checksum, sig->data+16, checksum_length);
+ ret = memcmp_const_time(checksum, sig->data+16, checksum_length);
if (ret != 0) {
dump_data_pw("calc digest:", checksum, checksum_length);
dump_data_pw("wire digest:", sig->data+16, checksum_length);
@@ -665,7 +665,7 @@ static NTSTATUS netsec_incoming_packet(struct schannel_state *state,
ZERO_ARRAY(checksum);
- ret = memcmp(seq_num, sig->data+8, 8);
+ ret = memcmp_const_time(seq_num, sig->data+8, 8);
if (ret != 0) {
dump_data_pw("calc seq num:", seq_num, 8);
dump_data_pw("wire seq num:", sig->data+8, 8);
diff --git a/auth/ntlmssp/ntlmssp_ndr.c b/auth/ntlmssp/ntlmssp_ndr.c
index c8b16ccd413..6de00427bbd 100644
--- a/auth/ntlmssp/ntlmssp_ndr.c
+++ b/auth/ntlmssp/ntlmssp_ndr.c
@@ -31,7 +31,7 @@ do { \
if (!NDR_ERR_CODE_IS_SUCCESS(__ndr_err)) { \
return ndr_map_error2ntstatus(__ndr_err); \
} \
- if (memcmp(r->Signature, "NTLMSSP\0", 8)) {\
+ if (memcmp_const_time(r->Signature, "NTLMSSP\0", 8)) { \
return NT_STATUS_INVALID_PARAMETER; \
} \
return NT_STATUS_OK; \
diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c
index e077c2f7379..55688602881 100644
--- a/auth/ntlmssp/ntlmssp_server.c
+++ b/auth/ntlmssp/ntlmssp_server.c
@@ -1095,8 +1095,8 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
}
gnutls_hmac_deinit(hmac_hnd, mic_buffer);
- cmp = memcmp(request.data + NTLMSSP_MIC_OFFSET,
- mic_buffer, NTLMSSP_MIC_SIZE);
+ cmp = memcmp_const_time(request.data + NTLMSSP_MIC_OFFSET,
+ mic_buffer, NTLMSSP_MIC_SIZE);
if (cmp != 0) {
DEBUG(1,("%s: invalid NTLMSSP_MIC for "
"user=[%s] domain=[%s] workstation=[%s]\n",
diff --git a/auth/ntlmssp/ntlmssp_sign.c b/auth/ntlmssp/ntlmssp_sign.c
index 89f1aa04f7a..b831308aa2c 100644
--- a/auth/ntlmssp/ntlmssp_sign.c
+++ b/auth/ntlmssp/ntlmssp_sign.c
@@ -291,7 +291,7 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state,
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
if (local_sig.length != sig->length ||
- memcmp(local_sig.data, sig->data, sig->length) != 0) {
+ memcmp_const_time(local_sig.data, sig->data, sig->length) != 0) {
DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n"));
dump_data(5, local_sig.data, local_sig.length);
@@ -304,7 +304,7 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state,
}
} else {
if (local_sig.length != sig->length ||
- memcmp(local_sig.data + 8, sig->data + 8, sig->length - 8) != 0) {
+ memcmp_const_time(local_sig.data + 8, sig->data + 8, sig->length - 8) != 0) {
DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n"));
dump_data(5, local_sig.data, local_sig.length);
diff --git a/lib/util/data_blob.c b/lib/util/data_blob.c
index da1730dccf5..1b05809119d 100644
--- a/lib/util/data_blob.c
+++ b/lib/util/data_blob.c
@@ -21,6 +21,7 @@
#include "replace.h"
#include "attr.h"
#include "data_blob.h"
+#include "lib/util/samba_util.h"
const DATA_BLOB data_blob_null = { NULL, 0 };
@@ -130,6 +131,29 @@ _PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2)
}
/**
+check if two data blobs are equal, where the time taken should not depend on the
+contents of either blob.
+**/
+_PUBLIC_ int data_blob_cmp_const_time(const DATA_BLOB *d1, const DATA_BLOB *d2)
+{
+ int ret;
+ if (d1->data == NULL && d2->data != NULL) {
+ return -1;
+ }
+ if (d1->data != NULL && d2->data == NULL) {
+ return 1;
+ }
+ if (d1->data == d2->data) {
+ return d1->length - d2->length;
+ }
+ ret = memcmp_const_time(d1->data, d2->data, MIN(d1->length, d2->length));
+ if (ret == 0) {
+ return d1->length - d2->length;
+ }
+ return ret;
+}
+
+/**
print the data_blob as hex string
**/
_PUBLIC_ char *data_blob_hex_string_lower(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
diff --git a/lib/util/data_blob.h b/lib/util/data_blob.h
index 7a0dc3b0014..0f3eae16592 100644
--- a/lib/util/data_blob.h
+++ b/lib/util/data_blob.h
@@ -87,6 +87,12 @@ check if two data blobs are equal
_PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2);
/**
+check if two data blobs are equal, where the time taken should not depend on the
+contents of either blob.
+**/
+_PUBLIC_ int data_blob_cmp_const_time(const DATA_BLOB *d1, const DATA_BLOB *d2);
+
+/**
print the data_blob as hex string
**/
_PUBLIC_ char *data_blob_hex_string_upper(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob);
diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c
index 23339d98bfa..bd257410c5c 100644
--- a/libcli/auth/credentials.c
+++ b/libcli/auth/credentials.c
@@ -659,7 +659,7 @@ bool netlogon_creds_client_check(struct netlogon_creds_CredentialState *creds,
const struct netr_Credential *received_credentials)
{
if (!received_credentials ||
- memcmp(received_credentials->data, creds->server.data, 8) != 0) {
+ memcmp_const_time(received_credentials->data, creds->server.data, 8) != 0) {
DEBUG(2,("credentials check failed\n"));
return false;
}
@@ -678,7 +678,7 @@ next comes the server specific functions
static bool netlogon_creds_server_check_internal(const struct netlogon_creds_CredentialState *creds,
const struct netr_Credential *received_credentials)
{
- if (memcmp(received_credentials->data, creds->client.data, 8) != 0) {
+ if (memcmp_const_time(received_credentials->data, creds->client.data, 8) != 0) {
DEBUG(2,("credentials check failed\n"));
dump_data_pw("client creds", creds->client.data, 8);
dump_data_pw("calc creds", received_credentials->data, 8);
diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
index e92a042c012..369e3d94d3f 100644
--- a/libcli/auth/netlogon_creds_cli.c
+++ b/libcli/auth/netlogon_creds_cli.c
@@ -652,7 +652,7 @@ bool netlogon_creds_cli_validate(struct netlogon_creds_cli_context *context,
return false;
}
- cmp = data_blob_cmp(&blob1, &blob2);
+ cmp = data_blob_cmp_const_time(&blob1, &blob2);
TALLOC_FREE(frame);
@@ -3227,8 +3227,8 @@ static void netlogon_creds_cli_ServerGetTrustInfo_done(struct tevent_req *subreq
return;
}
- cmp = memcmp(state->new_owf_password.hash,
- zero.hash, sizeof(zero.hash));
+ cmp = memcmp_const_time(state->new_owf_password.hash,
+ zero.hash, sizeof(zero.hash));
if (cmp != 0) {
status = netlogon_creds_des_decrypt(&state->tmp_creds,
&state->new_owf_password);
@@ -3237,8 +3237,8 @@ static void netlogon_creds_cli_ServerGetTrustInfo_done(struct tevent_req *subreq
return;
}
}
- cmp = memcmp(state->old_owf_password.hash,
- zero.hash, sizeof(zero.hash));
+ cmp = memcmp_const_time(state->old_owf_password.hash,
+ zero.hash, sizeof(zero.hash));
if (cmp != 0) {
status = netlogon_creds_des_decrypt(&state->tmp_creds,
&state->old_owf_password);
diff --git a/libcli/auth/ntlm_check.c b/libcli/auth/ntlm_check.c
index 846e0c07cd5..d71bdb3b1a4 100644
--- a/libcli/auth/ntlm_check.c
+++ b/libcli/auth/ntlm_check.c
@@ -71,7 +71,7 @@ static bool smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx,
DEBUGADD(100,("Value from encryption was |\n"));
dump_data(100, p24, 24);
#endif
- ok = (memcmp(p24, nt_response->data, 24) == 0);
+ ok = (memcmp_const_time(p24, nt_response->data, 24) == 0);
if (!ok) {
return false;
}
@@ -157,7 +157,7 @@ static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
#endif
data_blob_clear_free(&client_key_data);
- ok = (memcmp(value_from_encryption, ntv2_response->data, 16) == 0);
+ ok = (memcmp_const_time(value_from_encryption, ntv2_response->data, 16) == 0);
if (!ok) {
return false;
}
@@ -271,7 +271,7 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
}
if (client_nt && stored_nt) {
- if (memcmp(client_nt->hash, stored_nt->hash, sizeof(stored_nt->hash)) == 0) {
+ if (memcmp_const_time(client_nt->hash, stored_nt->hash, sizeof(stored_nt->hash)) == 0) {
return NT_STATUS_OK;
} else {
DEBUG(3,("hash_password_check: Interactive logon: NT password check failed for user %s\n",
@@ -289,7 +289,7 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
return NT_STATUS_NOT_FOUND;
}
- if (memcmp(client_lanman->hash, stored_lanman->hash, sizeof(stored_lanman->hash)) == 0) {
+ if (memcmp_const_time(client_lanman->hash, stored_lanman->hash, sizeof(stored_lanman->hash)) == 0) {
return NT_STATUS_OK;
} else {
DEBUG(3,("hash_password_check: Interactive logon: LANMAN password check failed for user %s\n",
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 57d39d60fca..60c3da5b691 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -3998,9 +3998,9 @@ static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
if (signing_key) {
int cmp;
- cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
- state->smb2.hdr+SMB2_HDR_SIGNATURE,
- 16);
+ cmp = memcmp_const_time(inhdr+SMB2_HDR_SIGNATURE,
+ state->smb2.hdr+SMB2_HDR_SIGNATURE,
+ 16);
if (cmp == 0) {
state->smb2.signing_skipped = true;
signing_key = NULL;
diff --git a/libcli/smb/smb_signing.c b/libcli/smb/smb_signing.c
index f01865c9bc5..ee9b854275a 100644
--- a/libcli/smb/smb_signing.c
+++ b/libcli/smb/smb_signing.c
@@ -339,7 +339,7 @@ bool smb1_signing_check_pdu(struct smb1_signing_state *si,
}
reply_sent_mac = &inhdr[HDR_SS_FIELD];
- good = (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0);
+ good = (memcmp_const_time(reply_sent_mac, calc_md5_mac, 8) == 0);
if (!good) {
int i;
@@ -354,7 +354,7 @@ bool smb1_signing_check_pdu(struct smb1_signing_state *si,
for (i = -sign_range; i < sign_range; i++) {
smb1_signing_md5(&si->mac_key, inhdr, len,
seqnum+i, calc_md5_mac);
- if (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0) {
+ if (memcmp_const_time(reply_sent_mac, calc_md5_mac, 8) == 0) {
DBG_ERR("out of seq. seq num %u matches. "
"We were expecting seq %u\n",
(unsigned int)seqnum+i,
diff --git a/source3/librpc/crypto/gse_krb5.c b/source3/librpc/crypto/gse_krb5.c
index 83741c914a3..13547047165 100644
--- a/source3/librpc/crypto/gse_krb5.c
+++ b/source3/librpc/crypto/gse_krb5.c
@@ -240,8 +240,8 @@ static krb5_error_code fill_mem_keytab_from_secrets(krb5_context krbctx,
* check if keytab is up to date */
if ((ct->length == KRB5_KEY_LENGTH(KRB5_KT_KEY(&kt_entry))) &&
- (memcmp(KRB5_KEY_DATA(KRB5_KT_KEY(&kt_entry)),
- ct->data, ct->length) == 0)) {
+ (memcmp_const_time(KRB5_KEY_DATA(KRB5_KT_KEY(&kt_entry)),
+ ct->data, ct->length) == 0)) {
/* keytab is already up to date, return */
smb_krb5_kt_free_entry(krbctx, &kt_entry);
goto out;
diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c
index 35f72c219f4..203b5ee0eb5 100644
--- a/source3/passdb/machine_account_secrets.c
+++ b/source3/passdb/machine_account_secrets.c
@@ -1873,9 +1873,9 @@ static NTSTATUS secrets_check_password_change(const struct secrets_domain_info1
return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
}
- cmp = memcmp(sn->password->nt_hash.hash,
- cn->password->nt_hash.hash,
- 16);
+ cmp = memcmp_const_time(sn->password->nt_hash.hash,
+ cn->password->nt_hash.hash,
+ 16);
if (cmp != 0) {
DBG_ERR("next password.nt_hash differs for %s.\n",
domain);
@@ -1883,9 +1883,9 @@ static NTSTATUS secrets_check_password_change(const struct secrets_domain_info1
return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
}
- cmp = memcmp(stored->password->nt_hash.hash,
- cookie->password->nt_hash.hash,
- 16);
+ cmp = memcmp_const_time(stored->password->nt_hash.hash,
+ cookie->password->nt_hash.hash,
+ 16);
if (cmp != 0) {
DBG_ERR("password.nt_hash differs for %s.\n",
domain);
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index f446f0c8724..e76d5b8bdc5 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -325,9 +325,9 @@ again:
status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
if (NT_STATUS_IS_OK(status)) {
- int cmp = memcmp(found_session_key,
- creds->session_key,
- sizeof(found_session_key));
+ int cmp = memcmp_const_time(found_session_key,
+ creds->session_key,
+ sizeof(found_session_key));
found_existing_creds = (cmp != 0);
memcpy(found_session_key,
@@ -356,9 +356,9 @@ again:
status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
if (NT_STATUS_IS_OK(status)) {
- int cmp = memcmp(found_session_key,
- creds->session_key,
- sizeof(found_session_key));
+ int cmp = memcmp_const_time(found_session_key,
+ creds->session_key,
+ sizeof(found_session_key));
found_existing_creds = (cmp != 0);
memcpy(found_session_key, creds->session_key,
diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index 5906464a9f3..b1f4d9c2b04 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -1577,7 +1577,7 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
confounder_len = 512 - new_password.length;
enc_blob = data_blob_const(r->in.new_password->data, confounder_len);
dec_blob = data_blob_const(password_buf.data, confounder_len);
- if (confounder_len > 0 && data_blob_cmp(&dec_blob, &enc_blob) == 0) {
+ if (confounder_len > 0 && data_blob_cmp_const_time(&dec_blob, &enc_blob) == 0) {
DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
confounder_len);
TALLOC_FREE(creds);
@@ -1592,7 +1592,7 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
new_password.length);
dec_blob = data_blob_const(password_buf.data + confounder_len,
new_password.length);
- if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
+ if (data_blob_cmp_const_time(&dec_blob, &enc_blob) == 0) {
DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
new_password.length);
TALLOC_FREE(creds);
diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c
index e326745169e..5ff3edb5eb7 100644
--- a/source3/rpc_server/samr/srv_samr_chgpasswd.c
+++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c
@@ -817,7 +817,7 @@ static NTSTATUS check_oem_password(const char *user,
NTSTATUS status = NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER;
return gnutls_error_to_ntstatus(rc, status);
}
- if (memcmp(verifier, old_nt_hash_encrypted, 16)) {
+ if (memcmp_const_time(verifier, old_nt_hash_encrypted, 16)) {
DEBUG(0, ("check_oem_password: old nt "
"password doesn't match.\n"));
return NT_STATUS_WRONG_PASSWORD;
@@ -848,7 +848,7 @@ static NTSTATUS check_oem_password(const char *user,
NTSTATUS status = NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER;
return gnutls_error_to_ntstatus(rc, status);
}
- if (memcmp(verifier, old_lm_hash_encrypted, 16)) {
+ if (memcmp_const_time(verifier, old_lm_hash_encrypted, 16)) {
DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
return NT_STATUS_WRONG_PASSWORD;
}
@@ -872,7 +872,7 @@ static NTSTATUS check_oem_password(const char *user,
NTSTATUS status = NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER;
return gnutls_error_to_ntstatus(rc, status);
}
- if (memcmp(verifier, old_lm_hash_encrypted, 16)) {
+ if (memcmp_const_time(verifier, old_lm_hash_encrypted, 16)) {
DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
return NT_STATUS_WRONG_PASSWORD;
}
@@ -915,8 +915,8 @@ static bool password_in_history(uint8_t nt_pw[NT_HASH_LEN],
* New format: zero salt and then plain nt hash.
* Directly compare the hashes.
*/
- if (memcmp(nt_pw, old_nt_pw_salted_md5_hash,
- SALTED_MD5_HASH_LEN) == 0)
+ if (memcmp_const_time(nt_pw, old_nt_pw_salted_md5_hash,
+ SALTED_MD5_HASH_LEN) == 0)
{
return true;
}
@@ -945,9 +945,9 @@ static bool password_in_history(uint8_t nt_pw[NT_HASH_LEN],
}
gnutls_hash_deinit(hash_hnd, new_nt_pw_salted_md5_hash);
- if (memcmp(new_nt_pw_salted_md5_hash,
- old_nt_pw_salted_md5_hash,
- SALTED_MD5_HASH_LEN) == 0) {
+ if (memcmp_const_time(new_nt_pw_salted_md5_hash,
+ old_nt_pw_salted_md5_hash,
+ SALTED_MD5_HASH_LEN) == 0) {
return true;
}
}
@@ -986,7 +986,7 @@ static bool check_passwd_history(struct samu *sampass, const char *plaintext)
E_md4hash(plaintext, new_nt_p16);
- if (!memcmp(nt_pw, new_nt_p16, NT_HASH_LEN)) {
+ if (!memcmp_const_time(nt_pw, new_nt_p16, NT_HASH_LEN)) {
DEBUG(10,("check_passwd_history: proposed new password for user %s is the same as the current password !\n",
pdb_get_username(sampass) ));
return True;
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index bb164d9914a..59564798ded 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -1536,12 +1536,12 @@ reconnect:
}
}
- cmp_new = memcmp(new_owf_password.hash,
- cur_nt_hash->hash,
- sizeof(cur_nt_hash->hash));
- cmp_old = memcmp(old_owf_password.hash,
- cur_nt_hash->hash,
- sizeof(cur_nt_hash->hash));
+ cmp_new = memcmp_const_time(new_owf_password.hash,
+ cur_nt_hash->hash,
+ sizeof(cur_nt_hash->hash));
+ cmp_old = memcmp_const_time(old_owf_password.hash,
+ cur_nt_hash->hash,
+ sizeof(cur_nt_hash->hash));
if (cmp_new != 0 && cmp_old != 0) {
DEBUG(1,("%s:Error: credentials for domain[%s/%s] doesn't match "
"any password known to dcname[%s]\n",
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 21649c69b10..b8c9fb67a65 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1215,12 +1215,12 @@ static NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
}
gnutls_hash_deinit(hash_hnd, salted_hash);
- password_good = (memcmp(cached_nt_pass, salted_hash,
- NT_HASH_LEN) == 0);
+ password_good = (memcmp_const_time(cached_nt_pass, salted_hash,
+ NT_HASH_LEN) == 0);
} else {
/* Old cached cred - direct store of nt_hash (bad bad bad !). */
- password_good = (memcmp(cached_nt_pass, new_nt_pass,
- NT_HASH_LEN) == 0);
+ password_good = (memcmp_const_time(cached_nt_pass, new_nt_pass,
+ NT_HASH_LEN) == 0);
}
if (password_good) {
diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index 14b6c707aa5..1bbf6c3fd16 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -364,7 +364,7 @@ static NTSTATUS authsam_password_check_and_record(struct auth4_context *auth_con
*/
E_md4hash("", zero_string_hash.hash);
- if (memcmp(nt_history_pwd->hash, zero_string_hash.hash, 16) == 0) {
+ if (memcmp_const_time(nt_history_pwd->hash, zero_string_hash.hash, 16) == 0) {
continue;
}
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index faf8a35818f..1b194799b9f 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -601,7 +601,7 @@ static int password_hash_bypass(struct ldb_module *module, struct ldb_request *r
"supplementalCredentialsBlob length differ");
}
- if (memcmp(sce->values[0].data, blob.data, blob.length) != 0) {
+ if (memcmp_const_time(sce->values[0].data, blob.data, blob.length) != 0) {
return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
"supplementalCredentialsBlob memcmp differ");
}
@@ -2754,7 +2754,7 @@ static int check_password_restrictions(struct setup_password_fields_io *io, WERR
/* The password modify through the NT hash is encouraged and
has no problems at all */
- if (!io->o.nt_hash || memcmp(io->og.nt_hash->hash, io->o.nt_hash->hash, 16) != 0) {
+ if (!io->o.nt_hash || memcmp_const_time(io->og.nt_hash->hash, io->o.nt_hash->hash, 16) != 0) {
return make_error_and_update_badPwdCount(io, werror);
}
}
@@ -2842,7 +2842,7 @@ static int check_password_restrictions(struct setup_password_fields_io *io, WERR
/* checks the NT hash password history */
for (i = 0; i < io->o.nt_history_len; i++) {
- int pw_cmp = memcmp(io->n.nt_hash, io->o.nt_history[i].hash, 16);
+ int pw_cmp = memcmp_const_time(io->n.nt_hash, io->o.nt_history[i].hash, 16);
if (pw_cmp == 0) {
ret = LDB_ERR_CONSTRAINT_VIOLATION;
*werror = WERR_PASSWORD_RESTRICTION;
diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c
index 40734cb7205..cd781506897 100644
--- a/source4/libcli/raw/smb_signing.c
+++ b/source4/libcli/raw/smb_signing.c
@@ -198,7 +198,7 @@ bool check_signed_incoming_message(struct smb_request_buffer *in, DATA_BLOB *mac
gnutls_hash_deinit(hash_hnd, calc_md5_mac);
- ok = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
+ ok = (memcmp_const_time(server_sent_mac, calc_md5_mac, 8) == 0);
if (i == 0) {
if (!ok) {
diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c
index 181f95a5918..5fbd36323e4 100644
--- a/source4/rpc_server/backupkey/dcesrv_backupkey.c
+++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c
@@ -451,7 +451,7 @@ static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
* point to the same area
*/
- if (memcmp(hash, uncrypted_accesscheckv2.hash, hash_size) != 0) {
+ if (memcmp_const_time(hash, uncrypted_accesscheckv2.hash, hash_size) != 0) {
DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
return WERR_INVALID_DATA;
}
@@ -486,7 +486,7 @@ static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
* point to the same area
*/
- if (memcmp(hash, uncrypted_accesscheckv3.hash, hash_size) != 0) {
+ if (memcmp_const_time(hash, uncrypted_accesscheckv3.hash, hash_size) != 0) {
DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
return WERR_INVALID_DATA;
}
@@ -1547,7 +1547,7 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
dump_data_pw("mac: \n", mac, sizeof(mac));
dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
- if (memcmp(mac, rc4payload.mac, sizeof(mac)) != 0) {
+ if (memcmp_const_time(mac, rc4payload.mac, sizeof(mac)) != 0) {
return WERR_INVALID_ACCESS;
}
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 062a92597ce..7978b20555c 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -873,7 +873,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
confounder_len = 512 - new_password.length;
enc_blob = data_blob_const(r->in.new_password->data, confounder_len);
dec_blob = data_blob_const(password_buf.data, confounder_len);
- if (confounder_len > 0 && data_blob_cmp(&dec_blob, &enc_blob) == 0) {
+ if (confounder_len > 0 && data_blob_cmp_const_time(&dec_blob, &enc_blob) == 0) {
DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
confounder_len);
return NT_STATUS_WRONG_PASSWORD;
@@ -887,7 +887,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
new_password.length);
dec_blob = data_blob_const(password_buf.data + confounder_len,
new_password.length);
- if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
+ if (data_blob_cmp_const_time(&dec_blob, &enc_blob) == 0) {
DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
new_password.length);
return NT_STATUS_WRONG_PASSWORD;
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index 0107c98da75..7dfde68b0d7 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -240,7 +240,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
goto failed;
}
- if (memcmp(nt_verifier.hash, r->in.nt_verifier->hash, 16) != 0) {
+ if (memcmp_const_time(nt_verifier.hash, r->in.nt_verifier->hash, 16) != 0) {
status = NT_STATUS_WRONG_PASSWORD;
goto failed;
}