]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
auth: Call ZERO_ARRAY()/ZERO_STRUCT() for sensitive variables on stack
authorPavel Filipenský <pfilipensky@samba.org>
Sun, 8 Mar 2026 07:43:39 +0000 (08:43 +0100)
committerPavel Filipensky <pfilipensky@samba.org>
Tue, 31 Mar 2026 08:15:33 +0000 (08:15 +0000)
Signed-off-by: Pavel Filipenský <pfilipensky@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
auth/credentials/credentials.c
auth/gensec/schannel.c
libcli/auth/credentials.c
libcli/auth/ntlm_check.c
libcli/auth/session.c
libcli/auth/smbdes.c
libcli/auth/smbencrypt.c

index fd2d9a040d1d5e932df6546939599c5be793f315..9f4f7ad35975e8b4495c088d63dce638227fa0a5 100644 (file)
@@ -1812,16 +1812,19 @@ _PUBLIC_ bool cli_credentials_parse_password_fd(struct cli_credentials *credenti
                                "Error reading password from file descriptor "
                                "%d: empty password\n",
                                fd);
+                       ZERO_ARRAY(pass);
                        return false;
 
                default:
                        fprintf(stderr, "Error reading password from file descriptor %d: %s\n",
                                        fd, strerror(errno));
+                       ZERO_ARRAY(pass);
                        return false;
                }
        }
 
        cli_credentials_set_password(credentials, pass, obtained);
+       ZERO_ARRAY(pass);
        return true;
 }
 
index 6e88e11990deea0bd742994d5b7fbce1bd3246f2..10157fffba5bdb3b5b113b654582f737a4b66024 100644 (file)
@@ -287,6 +287,7 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state,
                                        GNUTLS_CIPHER_AES_128_CFB8,
                                        &key,
                                        &iv);
+               ZERO_ARRAY(sess_kf0);
                if (rc < 0) {
                        DBG_ERR("ERROR: gnutls_cipher_init: %s\n",
                                gnutls_strerror(rc));
@@ -373,6 +374,7 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state,
                                      zeros,
                                      4,
                                      digest2);
+               ZERO_ARRAY(sess_kf0);
                if (rc < 0) {
                        ZERO_ARRAY(digest2);
                        return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED);
index 8470815b82eb1be0630e026e7d2a54595a2479f6..d9ab7943566f5ed7c11412d5f9549b391131c83b 100644 (file)
@@ -194,9 +194,13 @@ static NTSTATUS netlogon_creds_init_64bit(struct netlogon_creds_CredentialState
 
        rc = des_crypt128(creds->session_key, sum2, machine_password->hash);
        if (rc != 0) {
+               ZERO_ARRAY(sum);
+               ZERO_ARRAY(sum2);
                return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
        }
 
+       ZERO_ARRAY(sum);
+       ZERO_ARRAY(sum2);
        return NT_STATUS_OK;
 }
 
@@ -398,6 +402,7 @@ static NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_Credentia
                return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
        }
        *key = tmp;
+       ZERO_STRUCT(tmp);
 
        return NT_STATUS_OK;
 }
@@ -416,6 +421,7 @@ static NTSTATUS netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_Credentia
                return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
        }
        *key = tmp;
+       ZERO_STRUCT(tmp);
 
        return NT_STATUS_OK;
 }
@@ -434,6 +440,7 @@ NTSTATUS netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds
                return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
        }
        *pass = tmp;
+       ZERO_STRUCT(tmp);
 
        return NT_STATUS_OK;
 }
@@ -452,6 +459,7 @@ NTSTATUS netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds
                return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
        }
        *pass = tmp;
+       ZERO_STRUCT(tmp);
 
        return NT_STATUS_OK;
 }
index 190d5e73332d39d19a459f669ac21dfc2704a658..67bf31a008e52fa105c6bb3fda445a596584a654 100644 (file)
@@ -58,6 +58,7 @@ static bool smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx,
 
        rc = SMBOWFencrypt(part_passwd, sec_blob->data, p24);
        if (rc != 0) {
+               ZERO_ARRAY(p24);
                return false;
        }
 
@@ -73,16 +74,19 @@ static bool smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx,
 #endif
        ok = mem_equal_const_time(p24, nt_response->data, 24);
        if (!ok) {
+               ZERO_ARRAY(p24);
                return false;
        }
        if (user_sess_key != NULL) {
                *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
                if (user_sess_key->data == NULL) {
                        DBG_ERR("data_blob_talloc failed\n");
+                       ZERO_ARRAY(p24);
                        return false;
                }
                SMBsesskeygen_ntv1(part_passwd, user_sess_key->data);
        }
+       ZERO_ARRAY(p24);
        return true;
 }
 
@@ -132,6 +136,7 @@ static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
        */
 
        if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
+               ZERO_ARRAY(kr);
                return false;
        }
 
@@ -140,6 +145,8 @@ static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
                                    &client_key_data,
                                    value_from_encryption);
        if (!NT_STATUS_IS_OK(status)) {
+               ZERO_ARRAY(kr);
+               ZERO_ARRAY(value_from_encryption);
                return false;
        }
 
@@ -159,21 +166,29 @@ static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
 
        ok = mem_equal_const_time(value_from_encryption, ntv2_response->data, 16);
        if (!ok) {
+               ZERO_ARRAY(kr);
+               ZERO_ARRAY(value_from_encryption);
                return false;
        }
        if (user_sess_key != NULL) {
                *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
                if (user_sess_key->data == NULL) {
                        DBG_ERR("data_blob_talloc failed\n");
+                       ZERO_ARRAY(kr);
+                       ZERO_ARRAY(value_from_encryption);
                        return false;
                }
 
                status = SMBsesskeygen_ntv2(
                        kr, value_from_encryption, user_sess_key->data);
                if (!NT_STATUS_IS_OK(status)) {
+                       ZERO_ARRAY(kr);
+                       ZERO_ARRAY(value_from_encryption);
                        return false;
                }
        }
+       ZERO_ARRAY(kr);
+       ZERO_ARRAY(value_from_encryption);
        return true;
 }
 
@@ -218,6 +233,7 @@ static bool smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx,
        client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16);
 
        if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
+               ZERO_ARRAY(kr);
                return false;
        }
 
@@ -226,19 +242,27 @@ static bool smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx,
                                    &client_key_data,
                                    value_from_encryption);
        if (!NT_STATUS_IS_OK(status)) {
+               ZERO_ARRAY(kr);
+               ZERO_ARRAY(value_from_encryption);
                return false;
        }
        *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
        if (user_sess_key->data == NULL) {
                DBG_ERR("data_blob_talloc failed\n");
+               ZERO_ARRAY(kr);
+               ZERO_ARRAY(value_from_encryption);
                return false;
        }
        status = SMBsesskeygen_ntv2(kr,
                                    value_from_encryption,
                                    user_sess_key->data);
        if (!NT_STATUS_IS_OK(status)) {
+               ZERO_ARRAY(kr);
+               ZERO_ARRAY(value_from_encryption);
                return false;
        }
+       ZERO_ARRAY(kr);
+       ZERO_ARRAY(value_from_encryption);
        return true;
 }
 
@@ -521,6 +545,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                memset(first_8_lm_hash + 8, '\0', 8);
                                *user_sess_key = data_blob_talloc(mem_ctx, first_8_lm_hash, 16);
                                *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, 8);
+                               ZERO_ARRAY(first_8_lm_hash);
                        }
                        return NT_STATUS_OK;
                }
@@ -639,6 +664,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                memset(first_8_lm_hash + 8, '\0', 8);
                                *user_sess_key = data_blob_talloc(mem_ctx, first_8_lm_hash, 16);
                                *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, 8);
+                               ZERO_ARRAY(first_8_lm_hash);
                        }
                        return NT_STATUS_OK;
                }
index 515b7aed629bc58b7902cd83039bf1598ec8b747..5674c7574ed60728aa312103b3ef03258f9c542a 100644 (file)
@@ -56,10 +56,17 @@ int sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessio
 
                rc = des_crypt56_gnutls(bout, bin, key, encrypt);
                if (rc != 0) {
+                       ZERO_ARRAY(bin);
+                       ZERO_ARRAY(bout);
+                       ZERO_ARRAY(key);
                        return rc;
                }
 
                memcpy(&out->data[i], bout, 8);
+
+               ZERO_ARRAY(bin);
+               ZERO_ARRAY(bout);
+               ZERO_ARRAY(key);
        }
        return 0;
 }
index c6c4441930630ac0fffdc0c9084fe1d2efe748f8..407e484a5312e679b33863bbdf052c5c09d7d812 100644 (file)
@@ -73,11 +73,15 @@ int des_crypt56_gnutls(uint8_t out[8], const uint8_t in[8],
 
        ret = gnutls_global_init();
        if (ret != 0) {
+               ZERO_ARRAY(key2);
+               ZERO_ARRAY(outb);
                return ret;
        }
 
        ret = gnutls_cipher_init(&ctx, GNUTLS_CIPHER_DES_CBC, &key, &iv);
        if (ret != 0) {
+               ZERO_ARRAY(key2);
+               ZERO_ARRAY(outb);
                return ret;
        }
 
@@ -94,6 +98,8 @@ int des_crypt56_gnutls(uint8_t out[8], const uint8_t in[8],
 
        gnutls_cipher_deinit(ctx);
 
+       ZERO_ARRAY(key2);
+       ZERO_ARRAY(outb);
        return ret;
 }
 
@@ -147,10 +153,13 @@ int des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16])
 
        ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT);
        if (ret != 0) {
+               ZERO_ARRAY(buf);
                return ret;
        }
 
-       return des_crypt56_gnutls(out, buf, key+9, SAMBA_GNUTLS_ENCRYPT);
+       ret = des_crypt56_gnutls(out, buf, key + 9, SAMBA_GNUTLS_ENCRYPT);
+       ZERO_ARRAY(buf);
+       return ret;
 }
 
 /* des encryption with a 112 bit (14 byte) key */
@@ -163,18 +172,27 @@ int des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14],
        if (encrypt == SAMBA_GNUTLS_ENCRYPT) {
                ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT);
                if (ret != 0) {
+                       ZERO_ARRAY(buf);
                        return ret;
                }
 
-               return des_crypt56_gnutls(out, buf, key+7, SAMBA_GNUTLS_ENCRYPT);
+               ret = des_crypt56_gnutls(out,
+                                        buf,
+                                        key + 7,
+                                        SAMBA_GNUTLS_ENCRYPT);
+               ZERO_ARRAY(buf);
+               return ret;
        }
 
        ret = des_crypt56_gnutls(buf, in, key+7, SAMBA_GNUTLS_DECRYPT);
        if (ret != 0) {
+               ZERO_ARRAY(buf);
                return ret;
        }
 
-       return des_crypt56_gnutls(out, buf, key, SAMBA_GNUTLS_DECRYPT);
+       ret = des_crypt56_gnutls(out, buf, key, SAMBA_GNUTLS_DECRYPT);
+       ZERO_ARRAY(buf);
+       return ret;
 }
 
 /* des encryption of a 16 byte lump of data with a 112 bit key */
index f2bcda7fc0567ed30f0bb0c3f4c102a43a8be10e..9b92737d8b44a8ba78c958c8c8194da66ec142ab 100644 (file)
@@ -50,6 +50,7 @@ int SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[24
        dump_data(100, p24, 24);
 #endif
 
+       ZERO_STRUCT(p21);
        return rc;
 }
 
@@ -72,6 +73,7 @@ bool SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24])
        if (rc != 0) {
                ret = false;
        }
+       ZERO_ARRAY(lm_hash);
        return ret;
 }
 
@@ -277,11 +279,14 @@ out:
 int SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24])
 {
        uint8_t p21[21];
+       int rc;
 
        ZERO_STRUCT(p21);
 
        memcpy(p21, passwd, 16);
-       return E_P24(p21, c8, p24);
+       rc = E_P24(p21, c8, p24);
+       ZERO_STRUCT(p21);
+       return rc;
 }
 
 /* Does the des encryption. */
@@ -302,6 +307,7 @@ int SMBNTencrypt_hash(const uint8_t nt_hash[16], const uint8_t *c8, uint8_t *p24
        dump_data(100, p24, 24);
 #endif
 
+       ZERO_STRUCT(p21);
        return rc;
 }
 
@@ -309,9 +315,12 @@ int SMBNTencrypt_hash(const uint8_t nt_hash[16], const uint8_t *c8, uint8_t *p24
 
 int SMBNTencrypt(const char *passwd, const uint8_t *c8, uint8_t *p24)
 {
+       int ret;
        uint8_t nt_hash[16];
        E_md4hash(passwd, nt_hash);
-       return SMBNTencrypt_hash(nt_hash, c8, p24);
+       ret = SMBNTencrypt_hash(nt_hash, c8, p24);
+       ZERO_ARRAY(nt_hash);
+       return ret;
 }
 
 
@@ -411,14 +420,20 @@ NTSTATUS SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16],
 
        rc = des_crypt56_gnutls(p24, lm_resp, partial_lm_hash, SAMBA_GNUTLS_ENCRYPT);
        if (rc < 0) {
+               ZERO_ARRAY(partial_lm_hash);
+               ZERO_ARRAY(p24);
                return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
        }
        rc = des_crypt56_gnutls(p24+8, lm_resp, partial_lm_hash + 7, SAMBA_GNUTLS_ENCRYPT);
        if (rc < 0) {
+               ZERO_ARRAY(partial_lm_hash);
+               ZERO_ARRAY(p24);
                return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
        }
 
        memcpy(sess_key, p24, 16);
+       ZERO_ARRAY(partial_lm_hash);
+       ZERO_ARRAY(p24);
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100, ("SMBsesskeygen_lm_sess_key: \n"));
@@ -506,6 +521,7 @@ static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx,
                                    ntlmv2_response);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(mem_ctx);
+               ZERO_ARRAY(ntlmv2_response);
                return data_blob(NULL, 0);
        }
 
@@ -518,6 +534,7 @@ static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx,
 
        talloc_free(mem_ctx);
 
+       ZERO_ARRAY(ntlmv2_response);
        return final_response;
 }
 
@@ -541,6 +558,7 @@ static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx,
                                    lmv2_response);
        if (!NT_STATUS_IS_OK(status)) {
                data_blob_free(&lmv2_client_data);
+               ZERO_ARRAY(lmv2_response);
                return data_blob(NULL, 0);
        }
        memcpy(final_response.data, lmv2_response, sizeof(lmv2_response));
@@ -552,6 +570,7 @@ static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx,
 
        data_blob_free(&lmv2_client_data);
 
+       ZERO_ARRAY(lmv2_response);
        return final_response;
 }
 
@@ -571,6 +590,7 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx,
           This prevents username swapping during the auth exchange
        */
        if (!ntv2_owf_gen(nt_hash, user, domain, ntlm_v2_hash)) {
+               ZERO_ARRAY(ntlm_v2_hash);
                return false;
        }
 
@@ -598,6 +618,7 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx,
                                                    nt_response->data,
                                                    user_session_key->data);
                        if (!NT_STATUS_IS_OK(status)) {
+                               ZERO_ARRAY(ntlm_v2_hash);
                                return false;
                        }
                }
@@ -622,11 +643,13 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx,
                                                    lm_response->data,
                                                    lm_session_key->data);
                        if (!NT_STATUS_IS_OK(status)) {
+                               ZERO_ARRAY(ntlm_v2_hash);
                                return false;
                        }
                }
        }
 
+       ZERO_ARRAY(ntlm_v2_hash);
        return true;
 }
 
@@ -639,12 +662,24 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx,
                      DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key)
 {
        uint8_t nt_hash[16];
+       bool ret;
+
        E_md4hash(password, nt_hash);
 
-       return SMBNTLMv2encrypt_hash(mem_ctx,
-                                    user, domain, nt_hash,
-                                    server_chal, NULL, names_blob,
-                                    lm_response, nt_response, lm_session_key, user_session_key);
+       ret = SMBNTLMv2encrypt_hash(mem_ctx,
+                                   user,
+                                   domain,
+                                   nt_hash,
+                                   server_chal,
+                                   NULL,
+                                   names_blob,
+                                   lm_response,
+                                   nt_response,
+                                   lm_session_key,
+                                   user_session_key);
+
+       ZERO_ARRAY(nt_hash);
+       return ret;
 }
 
 static NTSTATUS NTLMv2_RESPONSE_verify_workstation(const char *account_name,