From: David Howells <dhowells@redhat.com>
To: Steve French <sfrench@samba.org>
Cc: David Howells <dhowells@redhat.com>,
Paulo Alcantara <pc@manguebit.org>,
Enzo Matsumiya <ematsumiya@suse.de>,
linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 34/37] cifs: SMB1 split: cifsencrypt.c
Date: Mon, 22 Dec 2025 22:29:59 +0000 [thread overview]
Message-ID: <20251222223006.1075635-35-dhowells@redhat.com> (raw)
In-Reply-To: <20251222223006.1075635-1-dhowells@redhat.com>
Split SMB1-specific message signing into smb1encrypt.c.
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Enzo Matsumiya <ematsumiya@suse.de>
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
---
fs/smb/client/Makefile | 1 +
fs/smb/client/cifsencrypt.c | 123 -------------------------------
fs/smb/client/cifsproto.h | 5 --
fs/smb/client/smb1encrypt.c | 139 ++++++++++++++++++++++++++++++++++++
fs/smb/client/smb1proto.h | 9 +++
5 files changed, 149 insertions(+), 128 deletions(-)
create mode 100644 fs/smb/client/smb1encrypt.c
diff --git a/fs/smb/client/Makefile b/fs/smb/client/Makefile
index 82ad4bccb131..a66e3b5b5912 100644
--- a/fs/smb/client/Makefile
+++ b/fs/smb/client/Makefile
@@ -35,6 +35,7 @@ cifs-$(CONFIG_CIFS_ROOT) += cifsroot.o
cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += \
cifssmb.o \
smb1debug.o \
+ smb1encrypt.o \
smb1maperror.o \
smb1misc.o \
smb1ops.o \
diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
index 661c7b8dc602..50b7ec39053c 100644
--- a/fs/smb/client/cifsencrypt.c
+++ b/fs/smb/client/cifsencrypt.c
@@ -115,129 +115,6 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
return rc;
}
-/*
- * Calculate and return the CIFS signature based on the mac key and SMB PDU.
- * The 16 byte signature must be allocated by the caller. Note we only use the
- * 1st eight bytes and that the smb header signature field on input contains
- * the sequence number before this function is called. Also, this function
- * should be called with the server->srv_mutex held.
- */
-static int cifs_calc_signature(struct smb_rqst *rqst,
- struct TCP_Server_Info *server, char *signature)
-{
- struct md5_ctx ctx;
-
- if (!rqst->rq_iov || !signature || !server)
- return -EINVAL;
- if (fips_enabled) {
- cifs_dbg(VFS,
- "MD5 signature support is disabled due to FIPS\n");
- return -EOPNOTSUPP;
- }
-
- md5_init(&ctx);
- md5_update(&ctx, server->session_key.response, server->session_key.len);
-
- return __cifs_calc_signature(
- rqst, server, signature,
- &(struct cifs_calc_sig_ctx){ .md5 = &ctx });
-}
-
-/* must be called with server->srv_mutex held */
-int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
- __u32 *pexpected_response_sequence_number)
-{
- int rc = 0;
- char smb_signature[20];
- struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
-
- if ((cifs_pdu == NULL) || (server == NULL))
- return -EINVAL;
-
- spin_lock(&server->srv_lock);
- if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
- server->tcpStatus == CifsNeedNegotiate) {
- spin_unlock(&server->srv_lock);
- return rc;
- }
- spin_unlock(&server->srv_lock);
-
- if (!server->session_estab) {
- memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
- return rc;
- }
-
- cifs_pdu->Signature.Sequence.SequenceNumber =
- cpu_to_le32(server->sequence_number);
- cifs_pdu->Signature.Sequence.Reserved = 0;
-
- *pexpected_response_sequence_number = ++server->sequence_number;
- ++server->sequence_number;
-
- rc = cifs_calc_signature(rqst, server, smb_signature);
- if (rc)
- memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
- else
- memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
-
- return rc;
-}
-
-int cifs_verify_signature(struct smb_rqst *rqst,
- struct TCP_Server_Info *server,
- __u32 expected_sequence_number)
-{
- unsigned int rc;
- char server_response_sig[8];
- char what_we_think_sig_should_be[20];
- struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
-
- if (cifs_pdu == NULL || server == NULL)
- return -EINVAL;
-
- if (!server->session_estab)
- return 0;
-
- if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
- struct smb_com_lock_req *pSMB =
- (struct smb_com_lock_req *)cifs_pdu;
- if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
- return 0;
- }
-
- /* BB what if signatures are supposed to be on for session but
- server does not send one? BB */
-
- /* Do not need to verify session setups with signature "BSRSPYL " */
- if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
- cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
- cifs_pdu->Command);
-
- /* save off the original signature so we can modify the smb and check
- its signature against what the server sent */
- memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
-
- cifs_pdu->Signature.Sequence.SequenceNumber =
- cpu_to_le32(expected_sequence_number);
- cifs_pdu->Signature.Sequence.Reserved = 0;
-
- cifs_server_lock(server);
- rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
- cifs_server_unlock(server);
-
- if (rc)
- return rc;
-
-/* cifs_dump_mem("what we think it should be: ",
- what_we_think_sig_should_be, 16); */
-
- if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
- return -EACCES;
- else
- return 0;
-
-}
-
/* Build a proper attribute value/target info pairs blob.
* Fill in netbios and dns domain name and workstation name
* and client time (total five av pairs and + one end of fields indicator.
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 884a66b6bd34..ba571cc7453a 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -326,11 +326,6 @@ struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled,
enum smb3_tcon_ref_trace trace);
void tconInfoFree(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace);
-int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
- __u32 *pexpected_response_sequence_number);
-int cifs_verify_signature(struct smb_rqst *rqst,
- struct TCP_Server_Info *server,
- __u32 expected_sequence_number);
int setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp);
void cifs_crypto_secmech_release(struct TCP_Server_Info *server);
int calc_seckey(struct cifs_ses *ses);
diff --git a/fs/smb/client/smb1encrypt.c b/fs/smb/client/smb1encrypt.c
new file mode 100644
index 000000000000..0dbbce2431ff
--- /dev/null
+++ b/fs/smb/client/smb1encrypt.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ *
+ * Encryption and hashing operations relating to NTLM, NTLMv2. See MS-NLMP
+ * for more detailed information
+ *
+ * Copyright (C) International Business Machines Corp., 2005,2013
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ */
+
+#include <linux/fips.h>
+#include <crypto/md5.h>
+#include "cifsproto.h"
+#include "smb1proto.h"
+#include "cifs_debug.h"
+
+/*
+ * Calculate and return the CIFS signature based on the mac key and SMB PDU.
+ * The 16 byte signature must be allocated by the caller. Note we only use the
+ * 1st eight bytes and that the smb header signature field on input contains
+ * the sequence number before this function is called. Also, this function
+ * should be called with the server->srv_mutex held.
+ */
+static int cifs_calc_signature(struct smb_rqst *rqst,
+ struct TCP_Server_Info *server, char *signature)
+{
+ struct md5_ctx ctx;
+
+ if (!rqst->rq_iov || !signature || !server)
+ return -EINVAL;
+ if (fips_enabled) {
+ cifs_dbg(VFS,
+ "MD5 signature support is disabled due to FIPS\n");
+ return -EOPNOTSUPP;
+ }
+
+ md5_init(&ctx);
+ md5_update(&ctx, server->session_key.response, server->session_key.len);
+
+ return __cifs_calc_signature(
+ rqst, server, signature,
+ &(struct cifs_calc_sig_ctx){ .md5 = &ctx });
+}
+
+/* must be called with server->srv_mutex held */
+int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+ __u32 *pexpected_response_sequence_number)
+{
+ int rc = 0;
+ char smb_signature[20];
+ struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
+
+ if ((cifs_pdu == NULL) || (server == NULL))
+ return -EINVAL;
+
+ spin_lock(&server->srv_lock);
+ if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
+ server->tcpStatus == CifsNeedNegotiate) {
+ spin_unlock(&server->srv_lock);
+ return rc;
+ }
+ spin_unlock(&server->srv_lock);
+
+ if (!server->session_estab) {
+ memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
+ return rc;
+ }
+
+ cifs_pdu->Signature.Sequence.SequenceNumber =
+ cpu_to_le32(server->sequence_number);
+ cifs_pdu->Signature.Sequence.Reserved = 0;
+
+ *pexpected_response_sequence_number = ++server->sequence_number;
+ ++server->sequence_number;
+
+ rc = cifs_calc_signature(rqst, server, smb_signature);
+ if (rc)
+ memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
+ else
+ memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
+
+ return rc;
+}
+
+int cifs_verify_signature(struct smb_rqst *rqst,
+ struct TCP_Server_Info *server,
+ __u32 expected_sequence_number)
+{
+ unsigned int rc;
+ char server_response_sig[8];
+ char what_we_think_sig_should_be[20];
+ struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
+
+ if (cifs_pdu == NULL || server == NULL)
+ return -EINVAL;
+
+ if (!server->session_estab)
+ return 0;
+
+ if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
+ struct smb_com_lock_req *pSMB =
+ (struct smb_com_lock_req *)cifs_pdu;
+ if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
+ return 0;
+ }
+
+ /* BB what if signatures are supposed to be on for session but
+ server does not send one? BB */
+
+ /* Do not need to verify session setups with signature "BSRSPYL " */
+ if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
+ cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
+ cifs_pdu->Command);
+
+ /* save off the original signature so we can modify the smb and check
+ its signature against what the server sent */
+ memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
+
+ cifs_pdu->Signature.Sequence.SequenceNumber =
+ cpu_to_le32(expected_sequence_number);
+ cifs_pdu->Signature.Sequence.Reserved = 0;
+
+ cifs_server_lock(server);
+ rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
+ cifs_server_unlock(server);
+
+ if (rc)
+ return rc;
+
+/* cifs_dump_mem("what we think it should be: ",
+ what_we_think_sig_should_be, 16); */
+
+ if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
+ return -EACCES;
+ else
+ return 0;
+
+}
diff --git a/fs/smb/client/smb1proto.h b/fs/smb/client/smb1proto.h
index f5760af58999..0f54c0740da1 100644
--- a/fs/smb/client/smb1proto.h
+++ b/fs/smb/client/smb1proto.h
@@ -220,6 +220,15 @@ int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
void cifs_dump_detail(void *buf, size_t buf_len,
struct TCP_Server_Info *server);
+/*
+ * smb1encrypt.c
+ */
+int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+ __u32 *pexpected_response_sequence_number);
+int cifs_verify_signature(struct smb_rqst *rqst,
+ struct TCP_Server_Info *server,
+ __u32 expected_sequence_number);
+
/*
* smb1maperror.c
*/
next prev parent reply other threads:[~2025-12-22 22:32 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-22 22:29 [PATCH 00/37] cifs: Scripted header file cleanup and SMB1 split David Howells
2025-12-22 22:29 ` [PATCH 01/37] cifs: Scripted clean up fs/smb/client/cached_dir.h David Howells
2025-12-22 22:29 ` [PATCH 02/37] cifs: Scripted clean up fs/smb/client/dfs.h David Howells
2025-12-22 22:29 ` [PATCH 03/37] cifs: Scripted clean up fs/smb/client/cifsproto.h David Howells
2025-12-22 22:29 ` [PATCH 04/37] cifs: Scripted clean up fs/smb/client/cifs_unicode.h David Howells
2025-12-22 22:29 ` [PATCH 05/37] cifs: Scripted clean up fs/smb/client/netlink.h David Howells
2025-12-22 22:29 ` [PATCH 06/37] cifs: Scripted clean up fs/smb/client/cifsfs.h David Howells
2025-12-22 22:29 ` [PATCH 07/37] cifs: Scripted clean up fs/smb/client/dfs_cache.h David Howells
2025-12-22 22:29 ` [PATCH 08/37] cifs: Scripted clean up fs/smb/client/dns_resolve.h David Howells
2025-12-22 22:29 ` [PATCH 09/37] cifs: Scripted clean up fs/smb/client/cifsglob.h David Howells
2025-12-22 22:29 ` [PATCH 10/37] cifs: Scripted clean up fs/smb/client/fscache.h David Howells
2025-12-22 22:29 ` [PATCH 11/37] cifs: Scripted clean up fs/smb/client/fs_context.h David Howells
2025-12-22 22:29 ` [PATCH 12/37] cifs: Scripted clean up fs/smb/client/cifs_spnego.h David Howells
2025-12-22 22:29 ` [PATCH 13/37] cifs: Scripted clean up fs/smb/client/compress.h David Howells
2025-12-22 22:29 ` [PATCH 14/37] cifs: Scripted clean up fs/smb/client/cifs_swn.h David Howells
2025-12-22 22:29 ` [PATCH 15/37] cifs: Scripted clean up fs/smb/client/cifs_debug.h David Howells
2025-12-22 22:29 ` [PATCH 16/37] cifs: Scripted clean up fs/smb/client/smb2proto.h David Howells
2025-12-22 22:29 ` [PATCH 17/37] cifs: Scripted clean up fs/smb/client/reparse.h David Howells
2025-12-22 22:29 ` [PATCH 18/37] cifs: Scripted clean up fs/smb/client/ntlmssp.h David Howells
2025-12-22 22:29 ` [PATCH 19/37] cifs: SMB1 split: Rename cifstransport.c David Howells
2025-12-22 22:29 ` [PATCH 20/37] cifs: SMB1 split: Create smb1proto.h for SMB1 declarations David Howells
2025-12-22 22:29 ` [PATCH 21/37] cifs: SMB1 split: Separate out SMB1 decls into smb1proto.h David Howells
2025-12-22 22:29 ` [PATCH 22/37] cifs: SMB1 split: Move some SMB1 receive bits to smb1transport.c David Howells
2025-12-22 22:29 ` [PATCH 23/37] cifs: SMB1 split: Move some SMB1 received PDU checking " David Howells
2025-12-22 22:29 ` [PATCH 24/37] cifs: SMB1 split: Add some #includes David Howells
2025-12-22 22:29 ` [PATCH 25/37] cifs: SMB1 split: Split SMB1 protocol defs into smb1pdu.h David Howells
2026-01-19 6:51 ` ChenXiaoSong
2025-12-22 22:29 ` [PATCH 26/37] cifs: SMB1 split: Adjust #includes David Howells
2025-12-22 22:29 ` [PATCH 27/37] cifs: SMB1 split: Move BCC access functions David Howells
2025-12-22 22:29 ` [PATCH 28/37] cifs: SMB1 split: Don't return smb_hdr from cifs_{,small_}buf_get() David Howells
2025-12-22 22:29 ` [PATCH 29/37] cifs: Fix cifs_dump_mids() to call ->dump_detail David Howells
2025-12-22 22:29 ` [PATCH 30/37] cifs: SMB1 split: Move inline funcs David Howells
2025-12-22 22:29 ` [PATCH 31/37] cifs: SMB1 split: cifs_debug.c David Howells
2025-12-22 22:29 ` [PATCH 32/37] cifs: SMB1 split: misc.c David Howells
2025-12-22 22:29 ` [PATCH 33/37] cifs: SMB1 split: netmisc.c David Howells
2025-12-22 22:29 ` David Howells [this message]
2025-12-22 22:30 ` [PATCH 35/37] cifs: SMB1 split: sess.c David Howells
2025-12-22 22:30 ` [PATCH 36/37] cifs: SMB1 split: connect.c David Howells
2025-12-22 22:30 ` [PATCH 37/37] cifs: SMB1 split: Make BCC accessors conditional David Howells
2026-01-15 16:53 ` [PATCH 00/37] cifs: Scripted header file cleanup and SMB1 split Enzo Matsumiya
2026-01-16 2:50 ` Steve French
2026-01-16 3:06 ` ChenXiaoSong
[not found] ` <CAH2r5msqwTqvCzpozKz_SPZsB-qP3RV_pfXZxZwMKMXWfmJHDg@mail.gmail.com>
2026-01-16 6:57 ` ChenXiaoSong
2026-01-16 6:58 ` David Howells
2026-01-16 7:04 ` ChenXiaoSong
2026-01-16 9:21 ` David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251222223006.1075635-35-dhowells@redhat.com \
--to=dhowells@redhat.com \
--cc=ematsumiya@suse.de \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pc@manguebit.org \
--cc=sfrench@samba.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox