The Samba-Bugzilla – Attachment 17207 Details for
Bug 15010
Sensitive data comparisons use memcmp()
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch for master
bug_15010.patch (text/plain), 29.17 KB, created by
Jennifer Sutton
on 2022-03-11 01:59:52 UTC
(
hide
)
Description:
patch for master
Filename:
MIME Type:
Creator:
Jennifer Sutton
Created:
2022-03-11 01:59:52 UTC
Size:
29.17 KB
patch
obsolete
>From fed54956a9c1a01423ecc3388ae791656e79990c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 17 Feb 2022 15:35:42 +1300 >Subject: [PATCH] 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> >--- > auth/gensec/schannel.c | 4 ++-- > auth/ntlmssp/ntlmssp_ndr.c | 2 +- > auth/ntlmssp/ntlmssp_server.c | 4 ++-- > auth/ntlmssp/ntlmssp_sign.c | 4 ++-- > auth/ntlmssp/ntlmssp_util.c | 2 +- > lib/util/data_blob.c | 24 +++++++++++++++++++ > lib/util/data_blob.h | 6 +++++ > libcli/auth/credentials.c | 19 +++++++-------- > libcli/auth/netlogon_creds_cli.c | 10 ++++---- > libcli/auth/ntlm_check.c | 8 +++---- > libcli/smb/smbXcli_base.c | 6 ++--- > libcli/smb/smb_signing.c | 4 ++-- > source3/librpc/crypto/gse_krb5.c | 4 ++-- > source3/passdb/machine_account_secrets.c | 12 +++++----- > source3/rpc_client/cli_netlogon.c | 12 +++++----- > source3/rpc_server/netlogon/srv_netlog_nt.c | 4 ++-- > source3/rpc_server/samr/srv_samr_chgpasswd.c | 18 +++++++------- > source3/winbindd/winbindd_dual_srv.c | 12 +++++----- > source3/winbindd/winbindd_pam.c | 8 +++---- > source4/auth/ntlm/auth_sam.c | 4 ++-- > .../dsdb/samdb/ldb_modules/password_hash.c | 10 ++++---- > source4/libcli/raw/smb_signing.c | 2 +- > .../rpc_server/backupkey/dcesrv_backupkey.c | 6 ++--- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 4 ++-- > source4/rpc_server/samr/samr_password.c | 6 ++--- > 25 files changed, 112 insertions(+), 83 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/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c >index 6f3b474fd71..1aeba343e9f 100644 >--- a/auth/ntlmssp/ntlmssp_util.c >+++ b/auth/ntlmssp/ntlmssp_util.c >@@ -177,7 +177,7 @@ NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, > /* Does this blob looks like it could be NTLMSSP? */ > bool ntlmssp_blob_matches_magic(const DATA_BLOB *blob) > { >- if (blob->length > 8 && memcmp("NTLMSSP\0", blob->data, 8) == 0) { >+ if (blob->length > 8 && memcmp_const_time("NTLMSSP\0", blob->data, 8) == 0) { > return true; > } else { > return false; >diff --git a/lib/util/data_blob.c b/lib/util/data_blob.c >index 77b077f7ef9..2416d4da00a 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 }; > >@@ -129,6 +130,29 @@ _PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2) > return ret; > } > >+/** >+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 > **/ >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 >@@ -86,6 +86,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 > **/ >diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c >index 23339d98bfa..56b8111efa1 100644 >--- a/libcli/auth/credentials.c >+++ b/libcli/auth/credentials.c >@@ -42,15 +42,14 @@ bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge) > * of the following steps. > */ > >- if (challenge->data[1] == challenge->data[0] && >- challenge->data[2] == challenge->data[0] && >- challenge->data[3] == challenge->data[0] && >- challenge->data[4] == challenge->data[0]) >- { >- return false; >- } >+ uint8_t result = 0; > >- return true; >+ result |= (challenge->data[1] ^ challenge->data[0]); >+ result |= (challenge->data[2] ^ challenge->data[0]); >+ result |= (challenge->data[3] ^ challenge->data[0]); >+ result |= (challenge->data[4] ^ challenge->data[0]); >+ >+ return result != 0; > } > > void netlogon_creds_random_challenge(struct netr_Credential *challenge) >@@ -659,7 +658,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 +677,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 0f3e4fa3f90..13f51bb6344 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 f98f0c98674..c238fa1a9de 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 50dae9d7f3e..9551621ce8a 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 3daa8468ddc..d710e61dc94 100644 >--- a/source3/winbindd/winbindd_dual_srv.c >+++ b/source3/winbindd/winbindd_dual_srv.c >@@ -1476,12 +1476,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 c2fcc399ab8..9b5dd732097 100644 >--- a/source3/winbindd/winbindd_pam.c >+++ b/source3/winbindd/winbindd_pam.c >@@ -1117,12 +1117,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 cf0656ae0da..d897f084482 100644 >--- a/source4/auth/ntlm/auth_sam.c >+++ b/source4/auth/ntlm/auth_sam.c >@@ -368,12 +368,12 @@ 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; > } > > E_deshash("", zero_string_des_hash.hash); >- if (!lm_history_pwd || memcmp(lm_history_pwd->hash, zero_string_des_hash.hash, 16) == 0) { >+ if (!lm_history_pwd || memcmp_const_time(lm_history_pwd->hash, zero_string_des_hash.hash, 16) == 0) { > lm_history_pwd = NULL; > } > >diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c >index 3978d82a79a..0d51a75c69c 100644 >--- a/source4/dsdb/samdb/ldb_modules/password_hash.c >+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c >@@ -602,7 +602,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"); > } >@@ -2831,7 +2831,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->og.nt_hash) { >- 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); > } > >@@ -2844,7 +2844,7 @@ static int check_password_restrictions(struct setup_password_fields_io *io, WERR > * (as the SAMR operations request it). */ > if (io->og.lm_hash) { > if ((!io->o.lm_hash && !nt_hash_checked) >- || (io->o.lm_hash && memcmp(io->og.lm_hash->hash, io->o.lm_hash->hash, 16) != 0)) { >+ || (io->o.lm_hash && memcmp_const_time(io->og.lm_hash->hash, io->o.lm_hash->hash, 16) != 0)) { > return make_error_and_update_badPwdCount(io, werror); > } > } >@@ -2933,7 +2933,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++) { >- ret = memcmp(io->n.nt_hash, io->o.nt_history[i].hash, 16); >+ ret = memcmp_const_time(io->n.nt_hash, io->o.nt_history[i].hash, 16); > if (ret == 0) { > ret = LDB_ERR_CONSTRAINT_VIOLATION; > *werror = WERR_PASSWORD_RESTRICTION; >@@ -2953,7 +2953,7 @@ static int check_password_restrictions(struct setup_password_fields_io *io, WERR > > /* checks the LM hash password history */ > for (i = 0; i < io->o.lm_history_len; i++) { >- ret = memcmp(io->n.lm_hash, io->o.lm_history[i].hash, 16); >+ ret = memcmp_const_time(io->n.lm_hash, io->o.lm_history[i].hash, 16); > if (ret == 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 cfd6d148b0a..326f32d51e8 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -897,7 +897,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; >@@ -911,7 +911,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 c0fbaacd4d8..36eb92c13c2 100644 >--- a/source4/rpc_server/samr/samr_password.c >+++ b/source4/rpc_server/samr/samr_password.c >@@ -250,7 +250,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, > status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); > goto failed; > } >- if (memcmp(lm_verifier.hash, r->in.hash->hash, 16) != 0) { >+ if (memcmp_const_time(lm_verifier.hash, r->in.hash->hash, 16) != 0) { > authsam_update_bad_pwd_count(sam_ctx, res[0], ldb_get_default_basedn(sam_ctx)); > status = NT_STATUS_WRONG_PASSWORD; > goto failed; >@@ -450,7 +450,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; > } >@@ -473,7 +473,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(lm_verifier.hash, r->in.lm_verifier->hash, 16) != 0) { >+ if (memcmp_const_time(lm_verifier.hash, r->in.lm_verifier->hash, 16) != 0) { > status = NT_STATUS_WRONG_PASSWORD; > goto failed; > } >-- >2.35.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 15010
: 17207