]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cifs: SMB1 split: cifsencrypt.c
authorDavid Howells <dhowells@redhat.com>
Wed, 17 Dec 2025 15:34:08 +0000 (15:34 +0000)
committerSteve French <stfrench@microsoft.com>
Sun, 8 Feb 2026 23:07:45 +0000 (17:07 -0600)
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
Acked-by: Enzo Matsumiya <ematsumiya@suse.de>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/Makefile
fs/smb/client/cifsencrypt.c
fs/smb/client/cifsproto.h
fs/smb/client/smb1encrypt.c [new file with mode: 0644]
fs/smb/client/smb1proto.h

index 82ad4bccb131961f092e9159a58f2d4d41c53a69..a66e3b5b591298a83f15ae6dd314ac9c54c438ac 100644 (file)
@@ -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 \
index 661c7b8dc602c8eb8f0b4d76166b52d0a69079df..50b7ec39053c15ef8e7f011643c73f937ba5f392 100644 (file)
@@ -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.
index 884a66b6bd347d5e4473ad1071b2473e2f3c2334..ba571cc7453ac6d99495994a23d083889499bd41 100644 (file)
@@ -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 (file)
index 0000000..0dbbce2
--- /dev/null
@@ -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;
+
+}
index 515168576bf945e200e7f0844c7a469164af1db4..d621e533c0086b9aed43d4131be389688ab5bfbf 100644 (file)
@@ -219,6 +219,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
  */