All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY
@ 2021-08-17  5:24 Ronnie Sahlberg
  2021-08-17  5:24 ` [PATCH 2/3] cifs: move calc_lanman_hash to smb1ops.c Ronnie Sahlberg
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Ronnie Sahlberg @ 2021-08-17  5:24 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/Makefile  | 4 +++-
 fs/cifs/smb1ops.c | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index 87fcacdf3de7..96739082718d 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_CIFS) += cifs.o
 cifs-y := trace.o cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o \
 	  inode.o link.o misc.o netmisc.o smbencrypt.o transport.o \
 	  cifs_unicode.o nterr.o cifsencrypt.o \
-	  readdir.o ioctl.o sess.o export.o smb1ops.o unc.o winucase.o \
+	  readdir.o ioctl.o sess.o export.o unc.o winucase.o \
 	  smb2ops.o smb2maperror.o smb2transport.o \
 	  smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o fs_context.o \
 	  dns_resolve.o cifs_spnego_negtokeninit.asn1.o asn1.o
@@ -17,6 +17,8 @@ $(obj)/asn1.o: $(obj)/cifs_spnego_negtokeninit.asn1.h
 
 $(obj)/cifs_spnego_negtokeninit.asn1.o: $(obj)/cifs_spnego_negtokeninit.asn1.c $(obj)/cifs_spnego_negtokeninit.asn1.h
 
+cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += smb1ops.o
+
 cifs-$(CONFIG_CIFS_XATTR) += xattr.o
 
 cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 3b83839fc2c2..beb1f74e25a7 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -5,6 +5,7 @@
  *  Copyright (c) 2012, Jeff Layton <jlayton@redhat.com>
  */
 
+#include <ctype.h>
 #include <linux/pagemap.h>
 #include <linux/vfs.h>
 #include "cifsglob.h"
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/3] cifs: move calc_lanman_hash to smb1ops.c
  2021-08-17  5:24 [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY Ronnie Sahlberg
@ 2021-08-17  5:24 ` Ronnie Sahlberg
  2021-08-17  5:24 ` [PATCH 3/3] cifs: move functions that depend on DES to smp1ops.c Ronnie Sahlberg
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Ronnie Sahlberg @ 2021-08-17  5:24 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

This is only used by SMB1 so lets move it to smb1ops which is conditionally
compiled in depending on CIFS_ALLOW_INSECURE_LEGACY

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifsencrypt.c | 42 ------------------------------------------
 fs/cifs/smb1ops.c     | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index ecf15d845dbd..79572d18ad7a 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -289,48 +289,6 @@ int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
 	return rc;
 }
 
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
-			char *lnm_session_key)
-{
-	int i, len;
-	int rc;
-	char password_with_pad[CIFS_ENCPWD_SIZE] = {0};
-
-	if (password) {
-		for (len = 0; len < CIFS_ENCPWD_SIZE; len++)
-			if (!password[len])
-				break;
-
-		memcpy(password_with_pad, password, len);
-	}
-
-	if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
-		memcpy(lnm_session_key, password_with_pad,
-			CIFS_ENCPWD_SIZE);
-		return 0;
-	}
-
-	/* calculate old style session key */
-	/* calling toupper is less broken than repeatedly
-	calling nls_toupper would be since that will never
-	work for UTF8, but neither handles multibyte code pages
-	but the only alternative would be converting to UCS-16 (Unicode)
-	(using a routine something like UniStrupr) then
-	uppercasing and then converting back from Unicode - which
-	would only worth doing it if we knew it were utf8. Basically
-	utf8 and other multibyte codepages each need their own strupper
-	function since a byte at a time will ont work. */
-
-	for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
-		password_with_pad[i] = toupper(password_with_pad[i]);
-
-	rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
-
-	return rc;
-}
-#endif /* CIFS_WEAK_PW_HASH */
-
 /* 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/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index beb1f74e25a7..5444cbc42043 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -15,6 +15,48 @@
 #include "cifs_unicode.h"
 #include "fs_context.h"
 
+#ifdef CONFIG_CIFS_WEAK_PW_HASH
+int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
+			char *lnm_session_key)
+{
+	int i, len;
+	int rc;
+	char password_with_pad[CIFS_ENCPWD_SIZE] = {0};
+
+	if (password) {
+		for (len = 0; len < CIFS_ENCPWD_SIZE; len++)
+			if (!password[len])
+				break;
+
+		memcpy(password_with_pad, password, len);
+	}
+
+	if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
+		memcpy(lnm_session_key, password_with_pad,
+			CIFS_ENCPWD_SIZE);
+		return 0;
+	}
+
+	/* calculate old style session key */
+	/* calling toupper is less broken than repeatedly
+	calling nls_toupper would be since that will never
+	work for UTF8, but neither handles multibyte code pages
+	but the only alternative would be converting to UCS-16 (Unicode)
+	(using a routine something like UniStrupr) then
+	uppercasing and then converting back from Unicode - which
+	would only worth doing it if we knew it were utf8. Basically
+	utf8 and other multibyte codepages each need their own strupper
+	function since a byte at a time will ont work. */
+
+	for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
+		password_with_pad[i] = toupper(password_with_pad[i]);
+
+	rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
+
+	return rc;
+}
+#endif /* CIFS_WEAK_PW_HASH */
+
 /*
  * An NT cancel request header looks just like the original request except:
  *
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3] cifs: move functions that depend on DES to smp1ops.c
  2021-08-17  5:24 [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY Ronnie Sahlberg
  2021-08-17  5:24 ` [PATCH 2/3] cifs: move calc_lanman_hash to smb1ops.c Ronnie Sahlberg
@ 2021-08-17  5:24 ` Ronnie Sahlberg
  2021-08-17  5:51   ` Steve French
  2021-08-17  8:02 ` [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY kernel test robot
  2021-08-17 17:19 ` kernel test robot
  3 siblings, 1 reply; 7+ messages in thread
From: Ronnie Sahlberg @ 2021-08-17  5:24 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Move all dependencies of DES into smb1ops.c
Make SMB1 support depend on CONFIG_LIB_DES

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/Kconfig       |   3 +-
 fs/cifs/cifsencrypt.c |  39 ------
 fs/cifs/cifsproto.h   |   9 --
 fs/cifs/connect.c     | 162 ---------------------
 fs/cifs/ntlmssp.h     |   1 +
 fs/cifs/sess.c        |   5 +
 fs/cifs/smb1ops.c     | 319 ++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/smbencrypt.c  | 114 ---------------
 8 files changed, 326 insertions(+), 326 deletions(-)

diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 7364950a9ef4..c01464476ba9 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -16,7 +16,6 @@ config CIFS
 	select CRYPTO_GCM
 	select CRYPTO_ECB
 	select CRYPTO_AES
-	select CRYPTO_LIB_DES
 	select KEYS
 	select DNS_RESOLVER
 	select ASN1
@@ -72,7 +71,7 @@ config CIFS_STATS2
 
 config CIFS_ALLOW_INSECURE_LEGACY
 	bool "Support legacy servers which use less secure dialects"
-	depends on CIFS
+	depends on CIFS && CRYPTO_LIB_DES
 	default y
 	help
 	  Modern dialects, SMB2.1 and later (including SMB3 and 3.1.1), have
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 79572d18ad7a..7680e0a9bea3 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -250,45 +250,6 @@ int cifs_verify_signature(struct smb_rqst *rqst,
 
 }
 
-/* first calculate 24 bytes ntlm response and then 16 byte session key */
-int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
-{
-	int rc = 0;
-	unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
-	char temp_key[CIFS_SESS_KEY_SIZE];
-
-	if (!ses)
-		return -EINVAL;
-
-	ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
-	if (!ses->auth_key.response)
-		return -ENOMEM;
-
-	ses->auth_key.len = temp_len;
-
-	rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
-			ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
-	if (rc) {
-		cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
-			 __func__, rc);
-		return rc;
-	}
-
-	rc = E_md4hash(ses->password, temp_key, nls_cp);
-	if (rc) {
-		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
-			 __func__, rc);
-		return rc;
-	}
-
-	rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
-	if (rc)
-		cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
-			 __func__, rc);
-
-	return rc;
-}
-
 /* 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/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index e0def0f0714b..4a686048f1fa 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -296,10 +296,6 @@ extern int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
 extern int cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required);
 extern int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses);
 
-extern int CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
-		    const char *tree, struct cifs_tcon *tcon,
-		    const struct nls_table *);
-
 extern int CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
 		const char *searchName, struct cifs_sb_info *cifs_sb,
 		__u16 *searchHandle, __u16 search_flags,
@@ -498,9 +494,6 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
 extern int cifs_verify_signature(struct smb_rqst *rqst,
 				 struct TCP_Server_Info *server,
 				__u32 expected_sequence_number);
-extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *,
-			const struct nls_table *);
-extern int setup_ntlm_response(struct cifs_ses *, const struct nls_table *);
 extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
 extern void cifs_crypto_secmech_release(struct TCP_Server_Info *server);
 extern int calc_seckey(struct cifs_ses *);
@@ -550,8 +543,6 @@ extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
 extern int mdfour(unsigned char *, unsigned char *, int);
 extern int E_md4hash(const unsigned char *passwd, unsigned char *p16,
 			const struct nls_table *codepage);
-extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
-			unsigned char *p24);
 
 extern int
 cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 3781eee9360a..7dba7b59dd51 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3642,168 +3642,6 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
 }
 #endif
 
-/*
- * Issue a TREE_CONNECT request.
- */
-int
-CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
-	 const char *tree, struct cifs_tcon *tcon,
-	 const struct nls_table *nls_codepage)
-{
-	struct smb_hdr *smb_buffer;
-	struct smb_hdr *smb_buffer_response;
-	TCONX_REQ *pSMB;
-	TCONX_RSP *pSMBr;
-	unsigned char *bcc_ptr;
-	int rc = 0;
-	int length;
-	__u16 bytes_left, count;
-
-	if (ses == NULL)
-		return -EIO;
-
-	smb_buffer = cifs_buf_get();
-	if (smb_buffer == NULL)
-		return -ENOMEM;
-
-	smb_buffer_response = smb_buffer;
-
-	header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
-			NULL /*no tid */ , 4 /*wct */ );
-
-	smb_buffer->Mid = get_next_mid(ses->server);
-	smb_buffer->Uid = ses->Suid;
-	pSMB = (TCONX_REQ *) smb_buffer;
-	pSMBr = (TCONX_RSP *) smb_buffer_response;
-
-	pSMB->AndXCommand = 0xFF;
-	pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
-	bcc_ptr = &pSMB->Password[0];
-	if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) {
-		pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
-		*bcc_ptr = 0; /* password is null byte */
-		bcc_ptr++;              /* skip password */
-		/* already aligned so no need to do it below */
-	} else {
-		pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-		/* BB FIXME add code to fail this if NTLMv2 or Kerberos
-		   specified as required (when that support is added to
-		   the vfs in the future) as only NTLM or the much
-		   weaker LANMAN (which we do not send by default) is accepted
-		   by Samba (not sure whether other servers allow
-		   NTLMv2 password here) */
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-		if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
-		    (ses->sectype == LANMAN))
-			calc_lanman_hash(tcon->password, ses->server->cryptkey,
-					 ses->server->sec_mode &
-					    SECMODE_PW_ENCRYPT ? true : false,
-					 bcc_ptr);
-		else
-#endif /* CIFS_WEAK_PW_HASH */
-		rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
-					bcc_ptr, nls_codepage);
-		if (rc) {
-			cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
-				 __func__, rc);
-			cifs_buf_release(smb_buffer);
-			return rc;
-		}
-
-		bcc_ptr += CIFS_AUTH_RESP_SIZE;
-		if (ses->capabilities & CAP_UNICODE) {
-			/* must align unicode strings */
-			*bcc_ptr = 0; /* null byte password */
-			bcc_ptr++;
-		}
-	}
-
-	if (ses->server->sign)
-		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
-	if (ses->capabilities & CAP_STATUS32) {
-		smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
-	}
-	if (ses->capabilities & CAP_DFS) {
-		smb_buffer->Flags2 |= SMBFLG2_DFS;
-	}
-	if (ses->capabilities & CAP_UNICODE) {
-		smb_buffer->Flags2 |= SMBFLG2_UNICODE;
-		length =
-		    cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
-			6 /* max utf8 char length in bytes */ *
-			(/* server len*/ + 256 /* share len */), nls_codepage);
-		bcc_ptr += 2 * length;	/* convert num 16 bit words to bytes */
-		bcc_ptr += 2;	/* skip trailing null */
-	} else {		/* ASCII */
-		strcpy(bcc_ptr, tree);
-		bcc_ptr += strlen(tree) + 1;
-	}
-	strcpy(bcc_ptr, "?????");
-	bcc_ptr += strlen("?????");
-	bcc_ptr += 1;
-	count = bcc_ptr - &pSMB->Password[0];
-	be32_add_cpu(&pSMB->hdr.smb_buf_length, count);
-	pSMB->ByteCount = cpu_to_le16(count);
-
-	rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
-			 0);
-
-	/* above now done in SendReceive */
-	if (rc == 0) {
-		bool is_unicode;
-
-		tcon->tidStatus = CifsGood;
-		tcon->need_reconnect = false;
-		tcon->tid = smb_buffer_response->Tid;
-		bcc_ptr = pByteArea(smb_buffer_response);
-		bytes_left = get_bcc(smb_buffer_response);
-		length = strnlen(bcc_ptr, bytes_left - 2);
-		if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
-			is_unicode = true;
-		else
-			is_unicode = false;
-
-
-		/* skip service field (NB: this field is always ASCII) */
-		if (length == 3) {
-			if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
-			    (bcc_ptr[2] == 'C')) {
-				cifs_dbg(FYI, "IPC connection\n");
-				tcon->ipc = true;
-				tcon->pipe = true;
-			}
-		} else if (length == 2) {
-			if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
-				/* the most common case */
-				cifs_dbg(FYI, "disk share connection\n");
-			}
-		}
-		bcc_ptr += length + 1;
-		bytes_left -= (length + 1);
-		strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
-
-		/* mostly informational -- no need to fail on error here */
-		kfree(tcon->nativeFileSystem);
-		tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
-						      bytes_left, is_unicode,
-						      nls_codepage);
-
-		cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
-
-		if ((smb_buffer_response->WordCount == 3) ||
-			 (smb_buffer_response->WordCount == 7))
-			/* field is in same location */
-			tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
-		else
-			tcon->Flags = 0;
-		cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
-	}
-
-	cifs_buf_release(smb_buffer);
-	return rc;
-}
-
 static void delayed_free(struct rcu_head *p)
 {
 	struct cifs_sb_info *cifs_sb = container_of(p, struct cifs_sb_info, rcu);
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 378133ce8869..54f740c75be6 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -124,3 +124,4 @@ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, struct cifs_ses *ses);
 int build_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
 			struct cifs_ses *ses,
 			const struct nls_table *nls_cp);
+int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp);
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index c5785fd3f52e..34a990e1ae44 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -1061,6 +1061,8 @@ sess_auth_lanman(struct sess_data *sess_data)
 
 #endif
 
+
+#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
 static void
 sess_auth_ntlm(struct sess_data *sess_data)
 {
@@ -1170,6 +1172,7 @@ sess_auth_ntlm(struct sess_data *sess_data)
 	kfree(ses->auth_key.response);
 	ses->auth_key.response = NULL;
 }
+#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 
 static void
 sess_auth_ntlmv2(struct sess_data *sess_data)
@@ -1687,9 +1690,11 @@ static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
 #else
 		return -EOPNOTSUPP;
 #endif
+#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
 	case NTLM:
 		sess_data->func = sess_auth_ntlm;
 		break;
+#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 	case NTLMv2:
 		sess_data->func = sess_auth_ntlmv2;
 		break;
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 5444cbc42043..c79d5bb2440d 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -6,6 +6,7 @@
  */
 
 #include <ctype.h>
+#include <linux/fips.h>
 #include <linux/pagemap.h>
 #include <linux/vfs.h>
 #include "cifsglob.h"
@@ -14,8 +15,103 @@
 #include "cifspdu.h"
 #include "cifs_unicode.h"
 #include "fs_context.h"
+#include "ntlmssp.h"
+
+#include <crypto/des.h>
+
+static void
+str_to_key(unsigned char *str, unsigned char *key)
+{
+	int i;
+
+	key[0] = str[0] >> 1;
+	key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
+	key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
+	key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
+	key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
+	key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
+	key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
+	key[7] = str[6] & 0x7F;
+	for (i = 0; i < 8; i++)
+		key[i] = (key[i] << 1);
+}
+
+static int
+smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
+{
+	unsigned char key2[8];
+	struct des_ctx ctx;
+
+	str_to_key(key, key2);
+
+	if (fips_enabled) {
+		cifs_dbg(VFS, "FIPS compliance enabled: DES not permitted\n");
+		return -ENOENT;
+	}
+
+	des_expand_key(&ctx, key2, DES_KEY_SIZE);
+	des_encrypt(&ctx, out, in);
+	memzero_explicit(&ctx, sizeof(ctx));
+
+	return 0;
+}
+
+static int
+E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
+{
+	int rc;
+
+	rc = smbhash(p24, c8, p21);
+	if (rc)
+		return rc;
+	rc = smbhash(p24 + 8, c8, p21 + 7);
+	if (rc)
+		return rc;
+	rc = smbhash(p24 + 16, c8, p21 + 14);
+	return rc;
+}
 
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
+static int
+E_P16(unsigned char *p14, unsigned char *p16)
+{
+	int rc;
+	unsigned char sp8[8] =
+	    { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+
+	rc = smbhash(p16, sp8, p14);
+	if (rc)
+		return rc;
+	rc = smbhash(p16 + 8, sp8, p14 + 7);
+	return rc;
+}
+
+/*
+   This implements the X/Open SMB password encryption
+   It takes a password, a 8 byte "crypt key" and puts 24 bytes of
+   encrypted password into p24 */
+/* Note that password must be uppercased and null terminated */
+static int
+SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
+{
+	int rc;
+	unsigned char p14[14], p16[16], p21[21];
+
+	memset(p14, '\0', 14);
+	memset(p16, '\0', 16);
+	memset(p21, '\0', 21);
+
+	memcpy(p14, passwd, 14);
+	rc = E_P16(p14, p16);
+	if (rc)
+		return rc;
+
+	memcpy(p21, p16, 16);
+	rc = E_P24(p21, c8, p24);
+
+	return rc;
+}
+
 int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
 			char *lnm_session_key)
 {
@@ -57,6 +153,229 @@ int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
 }
 #endif /* CIFS_WEAK_PW_HASH */
 
+/* Does the NT MD4 hash then des encryption. */
+static int
+SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
+		const struct nls_table *codepage)
+{
+	int rc;
+	unsigned char p16[16], p21[21];
+
+	memset(p16, '\0', 16);
+	memset(p21, '\0', 21);
+
+	rc = E_md4hash(passwd, p16, codepage);
+	if (rc) {
+		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
+			 __func__, rc);
+		return rc;
+	}
+	memcpy(p21, p16, 16);
+	rc = E_P24(p21, c8, p24);
+	return rc;
+}
+
+/*
+ * Issue a TREE_CONNECT request.
+ */
+static int
+CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
+	 const char *tree, struct cifs_tcon *tcon,
+	 const struct nls_table *nls_codepage)
+{
+	struct smb_hdr *smb_buffer;
+	struct smb_hdr *smb_buffer_response;
+	TCONX_REQ *pSMB;
+	TCONX_RSP *pSMBr;
+	unsigned char *bcc_ptr;
+	int rc = 0;
+	int length;
+	__u16 bytes_left, count;
+
+	if (ses == NULL)
+		return -EIO;
+
+	smb_buffer = cifs_buf_get();
+	if (smb_buffer == NULL)
+		return -ENOMEM;
+
+	smb_buffer_response = smb_buffer;
+
+	header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
+			NULL /*no tid */ , 4 /*wct */ );
+
+	smb_buffer->Mid = get_next_mid(ses->server);
+	smb_buffer->Uid = ses->Suid;
+	pSMB = (TCONX_REQ *) smb_buffer;
+	pSMBr = (TCONX_RSP *) smb_buffer_response;
+
+	pSMB->AndXCommand = 0xFF;
+	pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
+	bcc_ptr = &pSMB->Password[0];
+	if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) {
+		pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
+		*bcc_ptr = 0; /* password is null byte */
+		bcc_ptr++;              /* skip password */
+		/* already aligned so no need to do it below */
+	} else {
+		pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
+		/* BB FIXME add code to fail this if NTLMv2 or Kerberos
+		   specified as required (when that support is added to
+		   the vfs in the future) as only NTLM or the much
+		   weaker LANMAN (which we do not send by default) is accepted
+		   by Samba (not sure whether other servers allow
+		   NTLMv2 password here) */
+#ifdef CONFIG_CIFS_WEAK_PW_HASH
+		if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
+		    (ses->sectype == LANMAN))
+			calc_lanman_hash(tcon->password, ses->server->cryptkey,
+					 ses->server->sec_mode &
+					    SECMODE_PW_ENCRYPT ? true : false,
+					 bcc_ptr);
+		else
+#endif /* CIFS_WEAK_PW_HASH */
+		rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
+					bcc_ptr, nls_codepage);
+		if (rc) {
+			cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
+				 __func__, rc);
+			cifs_buf_release(smb_buffer);
+			return rc;
+		}
+
+		bcc_ptr += CIFS_AUTH_RESP_SIZE;
+		if (ses->capabilities & CAP_UNICODE) {
+			/* must align unicode strings */
+			*bcc_ptr = 0; /* null byte password */
+			bcc_ptr++;
+		}
+	}
+
+	if (ses->server->sign)
+		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+
+	if (ses->capabilities & CAP_STATUS32) {
+		smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
+	}
+	if (ses->capabilities & CAP_DFS) {
+		smb_buffer->Flags2 |= SMBFLG2_DFS;
+	}
+	if (ses->capabilities & CAP_UNICODE) {
+		smb_buffer->Flags2 |= SMBFLG2_UNICODE;
+		length =
+		    cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
+			6 /* max utf8 char length in bytes */ *
+			(/* server len*/ + 256 /* share len */), nls_codepage);
+		bcc_ptr += 2 * length;	/* convert num 16 bit words to bytes */
+		bcc_ptr += 2;	/* skip trailing null */
+	} else {		/* ASCII */
+		strcpy(bcc_ptr, tree);
+		bcc_ptr += strlen(tree) + 1;
+	}
+	strcpy(bcc_ptr, "?????");
+	bcc_ptr += strlen("?????");
+	bcc_ptr += 1;
+	count = bcc_ptr - &pSMB->Password[0];
+	be32_add_cpu(&pSMB->hdr.smb_buf_length, count);
+	pSMB->ByteCount = cpu_to_le16(count);
+
+	rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
+			 0);
+
+	/* above now done in SendReceive */
+	if (rc == 0) {
+		bool is_unicode;
+
+		tcon->tidStatus = CifsGood;
+		tcon->need_reconnect = false;
+		tcon->tid = smb_buffer_response->Tid;
+		bcc_ptr = pByteArea(smb_buffer_response);
+		bytes_left = get_bcc(smb_buffer_response);
+		length = strnlen(bcc_ptr, bytes_left - 2);
+		if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
+			is_unicode = true;
+		else
+			is_unicode = false;
+
+
+		/* skip service field (NB: this field is always ASCII) */
+		if (length == 3) {
+			if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
+			    (bcc_ptr[2] == 'C')) {
+				cifs_dbg(FYI, "IPC connection\n");
+				tcon->ipc = true;
+				tcon->pipe = true;
+			}
+		} else if (length == 2) {
+			if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
+				/* the most common case */
+				cifs_dbg(FYI, "disk share connection\n");
+			}
+		}
+		bcc_ptr += length + 1;
+		bytes_left -= (length + 1);
+		strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
+
+		/* mostly informational -- no need to fail on error here */
+		kfree(tcon->nativeFileSystem);
+		tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
+						      bytes_left, is_unicode,
+						      nls_codepage);
+
+		cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
+
+		if ((smb_buffer_response->WordCount == 3) ||
+			 (smb_buffer_response->WordCount == 7))
+			/* field is in same location */
+			tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
+		else
+			tcon->Flags = 0;
+		cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
+	}
+
+	cifs_buf_release(smb_buffer);
+	return rc;
+}
+
+/* first calculate 24 bytes ntlm response and then 16 byte session key */
+int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
+{
+	int rc = 0;
+	unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
+	char temp_key[CIFS_SESS_KEY_SIZE];
+
+	if (!ses)
+		return -EINVAL;
+
+	ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
+	if (!ses->auth_key.response)
+		return -ENOMEM;
+
+	ses->auth_key.len = temp_len;
+
+	rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
+			ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
+	if (rc) {
+		cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
+			 __func__, rc);
+		return rc;
+	}
+
+	rc = E_md4hash(ses->password, temp_key, nls_cp);
+	if (rc) {
+		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
+			 __func__, rc);
+		return rc;
+	}
+
+	rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
+	if (rc)
+		cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
+			 __func__, rc);
+
+	return rc;
+}
+
 /*
  * An NT cancel request header looks just like the original request except:
  *
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 39a938443e3e..0c5617427be9 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -18,7 +18,6 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/random.h>
-#include <crypto/des.h>
 #include "cifs_fs_sb.h"
 #include "cifs_unicode.h"
 #include "cifspdu.h"
@@ -38,72 +37,6 @@
 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
 
-static void
-str_to_key(unsigned char *str, unsigned char *key)
-{
-	int i;
-
-	key[0] = str[0] >> 1;
-	key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
-	key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
-	key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
-	key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
-	key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
-	key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
-	key[7] = str[6] & 0x7F;
-	for (i = 0; i < 8; i++)
-		key[i] = (key[i] << 1);
-}
-
-static int
-smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
-{
-	unsigned char key2[8];
-	struct des_ctx ctx;
-
-	str_to_key(key, key2);
-
-	if (fips_enabled) {
-		cifs_dbg(VFS, "FIPS compliance enabled: DES not permitted\n");
-		return -ENOENT;
-	}
-
-	des_expand_key(&ctx, key2, DES_KEY_SIZE);
-	des_encrypt(&ctx, out, in);
-	memzero_explicit(&ctx, sizeof(ctx));
-
-	return 0;
-}
-
-static int
-E_P16(unsigned char *p14, unsigned char *p16)
-{
-	int rc;
-	unsigned char sp8[8] =
-	    { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
-
-	rc = smbhash(p16, sp8, p14);
-	if (rc)
-		return rc;
-	rc = smbhash(p16 + 8, sp8, p14 + 7);
-	return rc;
-}
-
-static int
-E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
-{
-	int rc;
-
-	rc = smbhash(p24, c8, p21);
-	if (rc)
-		return rc;
-	rc = smbhash(p24 + 8, c8, p21 + 7);
-	if (rc)
-		return rc;
-	rc = smbhash(p24 + 16, c8, p21 + 14);
-	return rc;
-}
-
 /* produce a md4 message digest from data of length n bytes */
 int
 mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
@@ -135,32 +68,6 @@ mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
 	return rc;
 }
 
-/*
-   This implements the X/Open SMB password encryption
-   It takes a password, a 8 byte "crypt key" and puts 24 bytes of
-   encrypted password into p24 */
-/* Note that password must be uppercased and null terminated */
-int
-SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
-{
-	int rc;
-	unsigned char p14[14], p16[16], p21[21];
-
-	memset(p14, '\0', 14);
-	memset(p16, '\0', 16);
-	memset(p21, '\0', 21);
-
-	memcpy(p14, passwd, 14);
-	rc = E_P16(p14, p16);
-	if (rc)
-		return rc;
-
-	memcpy(p21, p16, 16);
-	rc = E_P24(p21, c8, p24);
-
-	return rc;
-}
-
 /*
  * Creates the MD4 Hash of the users password in NT UNICODE.
  */
@@ -187,24 +94,3 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16,
 	return rc;
 }
 
-/* Does the NT MD4 hash then des encryption. */
-int
-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
-		const struct nls_table *codepage)
-{
-	int rc;
-	unsigned char p16[16], p21[21];
-
-	memset(p16, '\0', 16);
-	memset(p21, '\0', 21);
-
-	rc = E_md4hash(passwd, p16, codepage);
-	if (rc) {
-		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
-			 __func__, rc);
-		return rc;
-	}
-	memcpy(p21, p16, 16);
-	rc = E_P24(p21, c8, p24);
-	return rc;
-}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] cifs: move functions that depend on DES to smp1ops.c
  2021-08-17  5:24 ` [PATCH 3/3] cifs: move functions that depend on DES to smp1ops.c Ronnie Sahlberg
@ 2021-08-17  5:51   ` Steve French
  0 siblings, 0 replies; 7+ messages in thread
From: Steve French @ 2021-08-17  5:51 UTC (permalink / raw)
  To: Ronnie Sahlberg; +Cc: linux-cifs

Fixed minor typo in patch 1 (<ctype.h>) and tentatively pushed all 3
to cifs-2.6.git for-next pending more testing and review

On Tue, Aug 17, 2021 at 12:25 AM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> Move all dependencies of DES into smb1ops.c
> Make SMB1 support depend on CONFIG_LIB_DES
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/cifs/Kconfig       |   3 +-
>  fs/cifs/cifsencrypt.c |  39 ------
>  fs/cifs/cifsproto.h   |   9 --
>  fs/cifs/connect.c     | 162 ---------------------
>  fs/cifs/ntlmssp.h     |   1 +
>  fs/cifs/sess.c        |   5 +
>  fs/cifs/smb1ops.c     | 319 ++++++++++++++++++++++++++++++++++++++++++
>  fs/cifs/smbencrypt.c  | 114 ---------------
>  8 files changed, 326 insertions(+), 326 deletions(-)
>
> diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
> index 7364950a9ef4..c01464476ba9 100644
> --- a/fs/cifs/Kconfig
> +++ b/fs/cifs/Kconfig
> @@ -16,7 +16,6 @@ config CIFS
>         select CRYPTO_GCM
>         select CRYPTO_ECB
>         select CRYPTO_AES
> -       select CRYPTO_LIB_DES
>         select KEYS
>         select DNS_RESOLVER
>         select ASN1
> @@ -72,7 +71,7 @@ config CIFS_STATS2
>
>  config CIFS_ALLOW_INSECURE_LEGACY
>         bool "Support legacy servers which use less secure dialects"
> -       depends on CIFS
> +       depends on CIFS && CRYPTO_LIB_DES
>         default y
>         help
>           Modern dialects, SMB2.1 and later (including SMB3 and 3.1.1), have
> diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
> index 79572d18ad7a..7680e0a9bea3 100644
> --- a/fs/cifs/cifsencrypt.c
> +++ b/fs/cifs/cifsencrypt.c
> @@ -250,45 +250,6 @@ int cifs_verify_signature(struct smb_rqst *rqst,
>
>  }
>
> -/* first calculate 24 bytes ntlm response and then 16 byte session key */
> -int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
> -{
> -       int rc = 0;
> -       unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
> -       char temp_key[CIFS_SESS_KEY_SIZE];
> -
> -       if (!ses)
> -               return -EINVAL;
> -
> -       ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
> -       if (!ses->auth_key.response)
> -               return -ENOMEM;
> -
> -       ses->auth_key.len = temp_len;
> -
> -       rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
> -                       ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
> -       if (rc) {
> -               cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
> -                        __func__, rc);
> -               return rc;
> -       }
> -
> -       rc = E_md4hash(ses->password, temp_key, nls_cp);
> -       if (rc) {
> -               cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
> -                        __func__, rc);
> -               return rc;
> -       }
> -
> -       rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
> -       if (rc)
> -               cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
> -                        __func__, rc);
> -
> -       return rc;
> -}
> -
>  /* 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/cifs/cifsproto.h b/fs/cifs/cifsproto.h
> index e0def0f0714b..4a686048f1fa 100644
> --- a/fs/cifs/cifsproto.h
> +++ b/fs/cifs/cifsproto.h
> @@ -296,10 +296,6 @@ extern int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
>  extern int cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required);
>  extern int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses);
>
> -extern int CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
> -                   const char *tree, struct cifs_tcon *tcon,
> -                   const struct nls_table *);
> -
>  extern int CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
>                 const char *searchName, struct cifs_sb_info *cifs_sb,
>                 __u16 *searchHandle, __u16 search_flags,
> @@ -498,9 +494,6 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
>  extern int cifs_verify_signature(struct smb_rqst *rqst,
>                                  struct TCP_Server_Info *server,
>                                 __u32 expected_sequence_number);
> -extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *,
> -                       const struct nls_table *);
> -extern int setup_ntlm_response(struct cifs_ses *, const struct nls_table *);
>  extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
>  extern void cifs_crypto_secmech_release(struct TCP_Server_Info *server);
>  extern int calc_seckey(struct cifs_ses *);
> @@ -550,8 +543,6 @@ extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
>  extern int mdfour(unsigned char *, unsigned char *, int);
>  extern int E_md4hash(const unsigned char *passwd, unsigned char *p16,
>                         const struct nls_table *codepage);
> -extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
> -                       unsigned char *p24);
>
>  extern int
>  cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname);
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 3781eee9360a..7dba7b59dd51 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -3642,168 +3642,6 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
>  }
>  #endif
>
> -/*
> - * Issue a TREE_CONNECT request.
> - */
> -int
> -CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
> -        const char *tree, struct cifs_tcon *tcon,
> -        const struct nls_table *nls_codepage)
> -{
> -       struct smb_hdr *smb_buffer;
> -       struct smb_hdr *smb_buffer_response;
> -       TCONX_REQ *pSMB;
> -       TCONX_RSP *pSMBr;
> -       unsigned char *bcc_ptr;
> -       int rc = 0;
> -       int length;
> -       __u16 bytes_left, count;
> -
> -       if (ses == NULL)
> -               return -EIO;
> -
> -       smb_buffer = cifs_buf_get();
> -       if (smb_buffer == NULL)
> -               return -ENOMEM;
> -
> -       smb_buffer_response = smb_buffer;
> -
> -       header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
> -                       NULL /*no tid */ , 4 /*wct */ );
> -
> -       smb_buffer->Mid = get_next_mid(ses->server);
> -       smb_buffer->Uid = ses->Suid;
> -       pSMB = (TCONX_REQ *) smb_buffer;
> -       pSMBr = (TCONX_RSP *) smb_buffer_response;
> -
> -       pSMB->AndXCommand = 0xFF;
> -       pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
> -       bcc_ptr = &pSMB->Password[0];
> -       if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) {
> -               pSMB->PasswordLength = cpu_to_le16(1);  /* minimum */
> -               *bcc_ptr = 0; /* password is null byte */
> -               bcc_ptr++;              /* skip password */
> -               /* already aligned so no need to do it below */
> -       } else {
> -               pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
> -               /* BB FIXME add code to fail this if NTLMv2 or Kerberos
> -                  specified as required (when that support is added to
> -                  the vfs in the future) as only NTLM or the much
> -                  weaker LANMAN (which we do not send by default) is accepted
> -                  by Samba (not sure whether other servers allow
> -                  NTLMv2 password here) */
> -#ifdef CONFIG_CIFS_WEAK_PW_HASH
> -               if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
> -                   (ses->sectype == LANMAN))
> -                       calc_lanman_hash(tcon->password, ses->server->cryptkey,
> -                                        ses->server->sec_mode &
> -                                           SECMODE_PW_ENCRYPT ? true : false,
> -                                        bcc_ptr);
> -               else
> -#endif /* CIFS_WEAK_PW_HASH */
> -               rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
> -                                       bcc_ptr, nls_codepage);
> -               if (rc) {
> -                       cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
> -                                __func__, rc);
> -                       cifs_buf_release(smb_buffer);
> -                       return rc;
> -               }
> -
> -               bcc_ptr += CIFS_AUTH_RESP_SIZE;
> -               if (ses->capabilities & CAP_UNICODE) {
> -                       /* must align unicode strings */
> -                       *bcc_ptr = 0; /* null byte password */
> -                       bcc_ptr++;
> -               }
> -       }
> -
> -       if (ses->server->sign)
> -               smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
> -
> -       if (ses->capabilities & CAP_STATUS32) {
> -               smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
> -       }
> -       if (ses->capabilities & CAP_DFS) {
> -               smb_buffer->Flags2 |= SMBFLG2_DFS;
> -       }
> -       if (ses->capabilities & CAP_UNICODE) {
> -               smb_buffer->Flags2 |= SMBFLG2_UNICODE;
> -               length =
> -                   cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
> -                       6 /* max utf8 char length in bytes */ *
> -                       (/* server len*/ + 256 /* share len */), nls_codepage);
> -               bcc_ptr += 2 * length;  /* convert num 16 bit words to bytes */
> -               bcc_ptr += 2;   /* skip trailing null */
> -       } else {                /* ASCII */
> -               strcpy(bcc_ptr, tree);
> -               bcc_ptr += strlen(tree) + 1;
> -       }
> -       strcpy(bcc_ptr, "?????");
> -       bcc_ptr += strlen("?????");
> -       bcc_ptr += 1;
> -       count = bcc_ptr - &pSMB->Password[0];
> -       be32_add_cpu(&pSMB->hdr.smb_buf_length, count);
> -       pSMB->ByteCount = cpu_to_le16(count);
> -
> -       rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
> -                        0);
> -
> -       /* above now done in SendReceive */
> -       if (rc == 0) {
> -               bool is_unicode;
> -
> -               tcon->tidStatus = CifsGood;
> -               tcon->need_reconnect = false;
> -               tcon->tid = smb_buffer_response->Tid;
> -               bcc_ptr = pByteArea(smb_buffer_response);
> -               bytes_left = get_bcc(smb_buffer_response);
> -               length = strnlen(bcc_ptr, bytes_left - 2);
> -               if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
> -                       is_unicode = true;
> -               else
> -                       is_unicode = false;
> -
> -
> -               /* skip service field (NB: this field is always ASCII) */
> -               if (length == 3) {
> -                       if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
> -                           (bcc_ptr[2] == 'C')) {
> -                               cifs_dbg(FYI, "IPC connection\n");
> -                               tcon->ipc = true;
> -                               tcon->pipe = true;
> -                       }
> -               } else if (length == 2) {
> -                       if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
> -                               /* the most common case */
> -                               cifs_dbg(FYI, "disk share connection\n");
> -                       }
> -               }
> -               bcc_ptr += length + 1;
> -               bytes_left -= (length + 1);
> -               strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
> -
> -               /* mostly informational -- no need to fail on error here */
> -               kfree(tcon->nativeFileSystem);
> -               tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
> -                                                     bytes_left, is_unicode,
> -                                                     nls_codepage);
> -
> -               cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
> -
> -               if ((smb_buffer_response->WordCount == 3) ||
> -                        (smb_buffer_response->WordCount == 7))
> -                       /* field is in same location */
> -                       tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
> -               else
> -                       tcon->Flags = 0;
> -               cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
> -       }
> -
> -       cifs_buf_release(smb_buffer);
> -       return rc;
> -}
> -
>  static void delayed_free(struct rcu_head *p)
>  {
>         struct cifs_sb_info *cifs_sb = container_of(p, struct cifs_sb_info, rcu);
> diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
> index 378133ce8869..54f740c75be6 100644
> --- a/fs/cifs/ntlmssp.h
> +++ b/fs/cifs/ntlmssp.h
> @@ -124,3 +124,4 @@ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, struct cifs_ses *ses);
>  int build_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
>                         struct cifs_ses *ses,
>                         const struct nls_table *nls_cp);
> +int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp);
> diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
> index c5785fd3f52e..34a990e1ae44 100644
> --- a/fs/cifs/sess.c
> +++ b/fs/cifs/sess.c
> @@ -1061,6 +1061,8 @@ sess_auth_lanman(struct sess_data *sess_data)
>
>  #endif
>
> +
> +#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
>  static void
>  sess_auth_ntlm(struct sess_data *sess_data)
>  {
> @@ -1170,6 +1172,7 @@ sess_auth_ntlm(struct sess_data *sess_data)
>         kfree(ses->auth_key.response);
>         ses->auth_key.response = NULL;
>  }
> +#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
>
>  static void
>  sess_auth_ntlmv2(struct sess_data *sess_data)
> @@ -1687,9 +1690,11 @@ static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
>  #else
>                 return -EOPNOTSUPP;
>  #endif
> +#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
>         case NTLM:
>                 sess_data->func = sess_auth_ntlm;
>                 break;
> +#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
>         case NTLMv2:
>                 sess_data->func = sess_auth_ntlmv2;
>                 break;
> diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
> index 5444cbc42043..c79d5bb2440d 100644
> --- a/fs/cifs/smb1ops.c
> +++ b/fs/cifs/smb1ops.c
> @@ -6,6 +6,7 @@
>   */
>
>  #include <ctype.h>
> +#include <linux/fips.h>
>  #include <linux/pagemap.h>
>  #include <linux/vfs.h>
>  #include "cifsglob.h"
> @@ -14,8 +15,103 @@
>  #include "cifspdu.h"
>  #include "cifs_unicode.h"
>  #include "fs_context.h"
> +#include "ntlmssp.h"
> +
> +#include <crypto/des.h>
> +
> +static void
> +str_to_key(unsigned char *str, unsigned char *key)
> +{
> +       int i;
> +
> +       key[0] = str[0] >> 1;
> +       key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
> +       key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
> +       key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
> +       key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
> +       key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
> +       key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
> +       key[7] = str[6] & 0x7F;
> +       for (i = 0; i < 8; i++)
> +               key[i] = (key[i] << 1);
> +}
> +
> +static int
> +smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
> +{
> +       unsigned char key2[8];
> +       struct des_ctx ctx;
> +
> +       str_to_key(key, key2);
> +
> +       if (fips_enabled) {
> +               cifs_dbg(VFS, "FIPS compliance enabled: DES not permitted\n");
> +               return -ENOENT;
> +       }
> +
> +       des_expand_key(&ctx, key2, DES_KEY_SIZE);
> +       des_encrypt(&ctx, out, in);
> +       memzero_explicit(&ctx, sizeof(ctx));
> +
> +       return 0;
> +}
> +
> +static int
> +E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
> +{
> +       int rc;
> +
> +       rc = smbhash(p24, c8, p21);
> +       if (rc)
> +               return rc;
> +       rc = smbhash(p24 + 8, c8, p21 + 7);
> +       if (rc)
> +               return rc;
> +       rc = smbhash(p24 + 16, c8, p21 + 14);
> +       return rc;
> +}
>
>  #ifdef CONFIG_CIFS_WEAK_PW_HASH
> +static int
> +E_P16(unsigned char *p14, unsigned char *p16)
> +{
> +       int rc;
> +       unsigned char sp8[8] =
> +           { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
> +
> +       rc = smbhash(p16, sp8, p14);
> +       if (rc)
> +               return rc;
> +       rc = smbhash(p16 + 8, sp8, p14 + 7);
> +       return rc;
> +}
> +
> +/*
> +   This implements the X/Open SMB password encryption
> +   It takes a password, a 8 byte "crypt key" and puts 24 bytes of
> +   encrypted password into p24 */
> +/* Note that password must be uppercased and null terminated */
> +static int
> +SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
> +{
> +       int rc;
> +       unsigned char p14[14], p16[16], p21[21];
> +
> +       memset(p14, '\0', 14);
> +       memset(p16, '\0', 16);
> +       memset(p21, '\0', 21);
> +
> +       memcpy(p14, passwd, 14);
> +       rc = E_P16(p14, p16);
> +       if (rc)
> +               return rc;
> +
> +       memcpy(p21, p16, 16);
> +       rc = E_P24(p21, c8, p24);
> +
> +       return rc;
> +}
> +
>  int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
>                         char *lnm_session_key)
>  {
> @@ -57,6 +153,229 @@ int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
>  }
>  #endif /* CIFS_WEAK_PW_HASH */
>
> +/* Does the NT MD4 hash then des encryption. */
> +static int
> +SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
> +               const struct nls_table *codepage)
> +{
> +       int rc;
> +       unsigned char p16[16], p21[21];
> +
> +       memset(p16, '\0', 16);
> +       memset(p21, '\0', 21);
> +
> +       rc = E_md4hash(passwd, p16, codepage);
> +       if (rc) {
> +               cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
> +                        __func__, rc);
> +               return rc;
> +       }
> +       memcpy(p21, p16, 16);
> +       rc = E_P24(p21, c8, p24);
> +       return rc;
> +}
> +
> +/*
> + * Issue a TREE_CONNECT request.
> + */
> +static int
> +CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
> +        const char *tree, struct cifs_tcon *tcon,
> +        const struct nls_table *nls_codepage)
> +{
> +       struct smb_hdr *smb_buffer;
> +       struct smb_hdr *smb_buffer_response;
> +       TCONX_REQ *pSMB;
> +       TCONX_RSP *pSMBr;
> +       unsigned char *bcc_ptr;
> +       int rc = 0;
> +       int length;
> +       __u16 bytes_left, count;
> +
> +       if (ses == NULL)
> +               return -EIO;
> +
> +       smb_buffer = cifs_buf_get();
> +       if (smb_buffer == NULL)
> +               return -ENOMEM;
> +
> +       smb_buffer_response = smb_buffer;
> +
> +       header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
> +                       NULL /*no tid */ , 4 /*wct */ );
> +
> +       smb_buffer->Mid = get_next_mid(ses->server);
> +       smb_buffer->Uid = ses->Suid;
> +       pSMB = (TCONX_REQ *) smb_buffer;
> +       pSMBr = (TCONX_RSP *) smb_buffer_response;
> +
> +       pSMB->AndXCommand = 0xFF;
> +       pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
> +       bcc_ptr = &pSMB->Password[0];
> +       if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) {
> +               pSMB->PasswordLength = cpu_to_le16(1);  /* minimum */
> +               *bcc_ptr = 0; /* password is null byte */
> +               bcc_ptr++;              /* skip password */
> +               /* already aligned so no need to do it below */
> +       } else {
> +               pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
> +               /* BB FIXME add code to fail this if NTLMv2 or Kerberos
> +                  specified as required (when that support is added to
> +                  the vfs in the future) as only NTLM or the much
> +                  weaker LANMAN (which we do not send by default) is accepted
> +                  by Samba (not sure whether other servers allow
> +                  NTLMv2 password here) */
> +#ifdef CONFIG_CIFS_WEAK_PW_HASH
> +               if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
> +                   (ses->sectype == LANMAN))
> +                       calc_lanman_hash(tcon->password, ses->server->cryptkey,
> +                                        ses->server->sec_mode &
> +                                           SECMODE_PW_ENCRYPT ? true : false,
> +                                        bcc_ptr);
> +               else
> +#endif /* CIFS_WEAK_PW_HASH */
> +               rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
> +                                       bcc_ptr, nls_codepage);
> +               if (rc) {
> +                       cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
> +                                __func__, rc);
> +                       cifs_buf_release(smb_buffer);
> +                       return rc;
> +               }
> +
> +               bcc_ptr += CIFS_AUTH_RESP_SIZE;
> +               if (ses->capabilities & CAP_UNICODE) {
> +                       /* must align unicode strings */
> +                       *bcc_ptr = 0; /* null byte password */
> +                       bcc_ptr++;
> +               }
> +       }
> +
> +       if (ses->server->sign)
> +               smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
> +
> +       if (ses->capabilities & CAP_STATUS32) {
> +               smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
> +       }
> +       if (ses->capabilities & CAP_DFS) {
> +               smb_buffer->Flags2 |= SMBFLG2_DFS;
> +       }
> +       if (ses->capabilities & CAP_UNICODE) {
> +               smb_buffer->Flags2 |= SMBFLG2_UNICODE;
> +               length =
> +                   cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
> +                       6 /* max utf8 char length in bytes */ *
> +                       (/* server len*/ + 256 /* share len */), nls_codepage);
> +               bcc_ptr += 2 * length;  /* convert num 16 bit words to bytes */
> +               bcc_ptr += 2;   /* skip trailing null */
> +       } else {                /* ASCII */
> +               strcpy(bcc_ptr, tree);
> +               bcc_ptr += strlen(tree) + 1;
> +       }
> +       strcpy(bcc_ptr, "?????");
> +       bcc_ptr += strlen("?????");
> +       bcc_ptr += 1;
> +       count = bcc_ptr - &pSMB->Password[0];
> +       be32_add_cpu(&pSMB->hdr.smb_buf_length, count);
> +       pSMB->ByteCount = cpu_to_le16(count);
> +
> +       rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
> +                        0);
> +
> +       /* above now done in SendReceive */
> +       if (rc == 0) {
> +               bool is_unicode;
> +
> +               tcon->tidStatus = CifsGood;
> +               tcon->need_reconnect = false;
> +               tcon->tid = smb_buffer_response->Tid;
> +               bcc_ptr = pByteArea(smb_buffer_response);
> +               bytes_left = get_bcc(smb_buffer_response);
> +               length = strnlen(bcc_ptr, bytes_left - 2);
> +               if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
> +                       is_unicode = true;
> +               else
> +                       is_unicode = false;
> +
> +
> +               /* skip service field (NB: this field is always ASCII) */
> +               if (length == 3) {
> +                       if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
> +                           (bcc_ptr[2] == 'C')) {
> +                               cifs_dbg(FYI, "IPC connection\n");
> +                               tcon->ipc = true;
> +                               tcon->pipe = true;
> +                       }
> +               } else if (length == 2) {
> +                       if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
> +                               /* the most common case */
> +                               cifs_dbg(FYI, "disk share connection\n");
> +                       }
> +               }
> +               bcc_ptr += length + 1;
> +               bytes_left -= (length + 1);
> +               strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
> +
> +               /* mostly informational -- no need to fail on error here */
> +               kfree(tcon->nativeFileSystem);
> +               tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
> +                                                     bytes_left, is_unicode,
> +                                                     nls_codepage);
> +
> +               cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
> +
> +               if ((smb_buffer_response->WordCount == 3) ||
> +                        (smb_buffer_response->WordCount == 7))
> +                       /* field is in same location */
> +                       tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
> +               else
> +                       tcon->Flags = 0;
> +               cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
> +       }
> +
> +       cifs_buf_release(smb_buffer);
> +       return rc;
> +}
> +
> +/* first calculate 24 bytes ntlm response and then 16 byte session key */
> +int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
> +{
> +       int rc = 0;
> +       unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
> +       char temp_key[CIFS_SESS_KEY_SIZE];
> +
> +       if (!ses)
> +               return -EINVAL;
> +
> +       ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
> +       if (!ses->auth_key.response)
> +               return -ENOMEM;
> +
> +       ses->auth_key.len = temp_len;
> +
> +       rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
> +                       ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
> +       if (rc) {
> +               cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
> +                        __func__, rc);
> +               return rc;
> +       }
> +
> +       rc = E_md4hash(ses->password, temp_key, nls_cp);
> +       if (rc) {
> +               cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
> +                        __func__, rc);
> +               return rc;
> +       }
> +
> +       rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
> +       if (rc)
> +               cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
> +                        __func__, rc);
> +
> +       return rc;
> +}
> +
>  /*
>   * An NT cancel request header looks just like the original request except:
>   *
> diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
> index 39a938443e3e..0c5617427be9 100644
> --- a/fs/cifs/smbencrypt.c
> +++ b/fs/cifs/smbencrypt.c
> @@ -18,7 +18,6 @@
>  #include <linux/string.h>
>  #include <linux/kernel.h>
>  #include <linux/random.h>
> -#include <crypto/des.h>
>  #include "cifs_fs_sb.h"
>  #include "cifs_unicode.h"
>  #include "cifspdu.h"
> @@ -38,72 +37,6 @@
>  #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
>  #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
>
> -static void
> -str_to_key(unsigned char *str, unsigned char *key)
> -{
> -       int i;
> -
> -       key[0] = str[0] >> 1;
> -       key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
> -       key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
> -       key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
> -       key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
> -       key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
> -       key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
> -       key[7] = str[6] & 0x7F;
> -       for (i = 0; i < 8; i++)
> -               key[i] = (key[i] << 1);
> -}
> -
> -static int
> -smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
> -{
> -       unsigned char key2[8];
> -       struct des_ctx ctx;
> -
> -       str_to_key(key, key2);
> -
> -       if (fips_enabled) {
> -               cifs_dbg(VFS, "FIPS compliance enabled: DES not permitted\n");
> -               return -ENOENT;
> -       }
> -
> -       des_expand_key(&ctx, key2, DES_KEY_SIZE);
> -       des_encrypt(&ctx, out, in);
> -       memzero_explicit(&ctx, sizeof(ctx));
> -
> -       return 0;
> -}
> -
> -static int
> -E_P16(unsigned char *p14, unsigned char *p16)
> -{
> -       int rc;
> -       unsigned char sp8[8] =
> -           { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
> -
> -       rc = smbhash(p16, sp8, p14);
> -       if (rc)
> -               return rc;
> -       rc = smbhash(p16 + 8, sp8, p14 + 7);
> -       return rc;
> -}
> -
> -static int
> -E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
> -{
> -       int rc;
> -
> -       rc = smbhash(p24, c8, p21);
> -       if (rc)
> -               return rc;
> -       rc = smbhash(p24 + 8, c8, p21 + 7);
> -       if (rc)
> -               return rc;
> -       rc = smbhash(p24 + 16, c8, p21 + 14);
> -       return rc;
> -}
> -
>  /* produce a md4 message digest from data of length n bytes */
>  int
>  mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
> @@ -135,32 +68,6 @@ mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
>         return rc;
>  }
>
> -/*
> -   This implements the X/Open SMB password encryption
> -   It takes a password, a 8 byte "crypt key" and puts 24 bytes of
> -   encrypted password into p24 */
> -/* Note that password must be uppercased and null terminated */
> -int
> -SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
> -{
> -       int rc;
> -       unsigned char p14[14], p16[16], p21[21];
> -
> -       memset(p14, '\0', 14);
> -       memset(p16, '\0', 16);
> -       memset(p21, '\0', 21);
> -
> -       memcpy(p14, passwd, 14);
> -       rc = E_P16(p14, p16);
> -       if (rc)
> -               return rc;
> -
> -       memcpy(p21, p16, 16);
> -       rc = E_P24(p21, c8, p24);
> -
> -       return rc;
> -}
> -
>  /*
>   * Creates the MD4 Hash of the users password in NT UNICODE.
>   */
> @@ -187,24 +94,3 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16,
>         return rc;
>  }
>
> -/* Does the NT MD4 hash then des encryption. */
> -int
> -SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
> -               const struct nls_table *codepage)
> -{
> -       int rc;
> -       unsigned char p16[16], p21[21];
> -
> -       memset(p16, '\0', 16);
> -       memset(p21, '\0', 21);
> -
> -       rc = E_md4hash(passwd, p16, codepage);
> -       if (rc) {
> -               cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
> -                        __func__, rc);
> -               return rc;
> -       }
> -       memcpy(p21, p16, 16);
> -       rc = E_P24(p21, c8, p24);
> -       return rc;
> -}
> --
> 2.30.2
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY
  2021-08-17  5:24 [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY Ronnie Sahlberg
  2021-08-17  5:24 ` [PATCH 2/3] cifs: move calc_lanman_hash to smb1ops.c Ronnie Sahlberg
  2021-08-17  5:24 ` [PATCH 3/3] cifs: move functions that depend on DES to smp1ops.c Ronnie Sahlberg
@ 2021-08-17  8:02 ` kernel test robot
  2021-08-17 17:19 ` kernel test robot
  3 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2021-08-17  8:02 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1992 bytes --]

Hi Ronnie,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on cifs/for-next]
[also build test ERROR on v5.14-rc6 next-20210816]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Ronnie-Sahlberg/cifs-only-compile-in-smb1ops-c-if-we-configure-CIFS_ALLOW_INSECURE_LEGACY/20210817-132616
base:   git://git.samba.org/sfrench/cifs-2.6.git for-next
config: x86_64-randconfig-m001-20210816 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/baf555d169cb4e93600a23119e9a489aa60edb93
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Ronnie-Sahlberg/cifs-only-compile-in-smb1ops-c-if-we-configure-CIFS_ALLOW_INSECURE_LEGACY/20210817-132616
        git checkout baf555d169cb4e93600a23119e9a489aa60edb93
        # save the attached .config to linux build tree
        mkdir build_dir
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash fs/cifs/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> fs/cifs/smb1ops.c:8:10: fatal error: ctype.h: No such file or directory
       8 | #include <ctype.h>
         |          ^~~~~~~~~
   compilation terminated.


vim +8 fs/cifs/smb1ops.c

   > 8	#include <ctype.h>
     9	#include <linux/pagemap.h>
    10	#include <linux/vfs.h>
    11	#include "cifsglob.h"
    12	#include "cifsproto.h"
    13	#include "cifs_debug.h"
    14	#include "cifspdu.h"
    15	#include "cifs_unicode.h"
    16	#include "fs_context.h"
    17	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 32525 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY
  2021-08-17  5:24 [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY Ronnie Sahlberg
                   ` (2 preceding siblings ...)
  2021-08-17  8:02 ` [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY kernel test robot
@ 2021-08-17 17:19 ` kernel test robot
  3 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2021-08-17 17:19 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2330 bytes --]

Hi Ronnie,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on cifs/for-next]
[also build test ERROR on v5.14-rc6 next-20210817]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Ronnie-Sahlberg/cifs-only-compile-in-smb1ops-c-if-we-configure-CIFS_ALLOW_INSECURE_LEGACY/20210817-132616
base:   git://git.samba.org/sfrench/cifs-2.6.git for-next
config: i386-randconfig-r021-20210816 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 2c6448cdc2f68f8c28fd0bd9404182b81306e6e6)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/baf555d169cb4e93600a23119e9a489aa60edb93
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Ronnie-Sahlberg/cifs-only-compile-in-smb1ops-c-if-we-configure-CIFS_ALLOW_INSECURE_LEGACY/20210817-132616
        git checkout baf555d169cb4e93600a23119e9a489aa60edb93
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=i386 SHELL=/bin/bash fs/cifs/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   clang-14: warning: optimization flag '-falign-jumps=0' is not supported [-Wignored-optimization-argument]
>> fs/cifs/smb1ops.c:8:10: fatal error: 'ctype.h' file not found
   #include <ctype.h>
            ^~~~~~~~~
   1 error generated.


vim +8 fs/cifs/smb1ops.c

   > 8	#include <ctype.h>
     9	#include <linux/pagemap.h>
    10	#include <linux/vfs.h>
    11	#include "cifsglob.h"
    12	#include "cifsproto.h"
    13	#include "cifs_debug.h"
    14	#include "cifspdu.h"
    15	#include "cifs_unicode.h"
    16	#include "fs_context.h"
    17	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 36668 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/3] cifs: move functions that depend on DES to smp1ops.c
  2021-08-13 19:56 cifs: only compile with DES when building with SMB1 support Ronnie Sahlberg
@ 2021-08-13 19:56 ` Ronnie Sahlberg
  0 siblings, 0 replies; 7+ messages in thread
From: Ronnie Sahlberg @ 2021-08-13 19:56 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Move all dependencies of DES into smb1ops.c
Make SMB1 support depend on CONFIG_LIB_DES

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/Kconfig       |   3 +-
 fs/cifs/cifsencrypt.c |  39 ------
 fs/cifs/cifsproto.h   |   9 --
 fs/cifs/connect.c     | 162 ---------------------
 fs/cifs/ntlmssp.h     |   1 +
 fs/cifs/sess.c        |   5 +
 fs/cifs/smb1ops.c     | 319 ++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/smbencrypt.c  | 114 ---------------
 8 files changed, 326 insertions(+), 326 deletions(-)

diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 7364950a9ef4..c01464476ba9 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -16,7 +16,6 @@ config CIFS
 	select CRYPTO_GCM
 	select CRYPTO_ECB
 	select CRYPTO_AES
-	select CRYPTO_LIB_DES
 	select KEYS
 	select DNS_RESOLVER
 	select ASN1
@@ -72,7 +71,7 @@ config CIFS_STATS2
 
 config CIFS_ALLOW_INSECURE_LEGACY
 	bool "Support legacy servers which use less secure dialects"
-	depends on CIFS
+	depends on CIFS && CRYPTO_LIB_DES
 	default y
 	help
 	  Modern dialects, SMB2.1 and later (including SMB3 and 3.1.1), have
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 79572d18ad7a..7680e0a9bea3 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -250,45 +250,6 @@ int cifs_verify_signature(struct smb_rqst *rqst,
 
 }
 
-/* first calculate 24 bytes ntlm response and then 16 byte session key */
-int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
-{
-	int rc = 0;
-	unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
-	char temp_key[CIFS_SESS_KEY_SIZE];
-
-	if (!ses)
-		return -EINVAL;
-
-	ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
-	if (!ses->auth_key.response)
-		return -ENOMEM;
-
-	ses->auth_key.len = temp_len;
-
-	rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
-			ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
-	if (rc) {
-		cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
-			 __func__, rc);
-		return rc;
-	}
-
-	rc = E_md4hash(ses->password, temp_key, nls_cp);
-	if (rc) {
-		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
-			 __func__, rc);
-		return rc;
-	}
-
-	rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
-	if (rc)
-		cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
-			 __func__, rc);
-
-	return rc;
-}
-
 /* 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/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index e0def0f0714b..4a686048f1fa 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -296,10 +296,6 @@ extern int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
 extern int cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required);
 extern int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses);
 
-extern int CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
-		    const char *tree, struct cifs_tcon *tcon,
-		    const struct nls_table *);
-
 extern int CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
 		const char *searchName, struct cifs_sb_info *cifs_sb,
 		__u16 *searchHandle, __u16 search_flags,
@@ -498,9 +494,6 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
 extern int cifs_verify_signature(struct smb_rqst *rqst,
 				 struct TCP_Server_Info *server,
 				__u32 expected_sequence_number);
-extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *,
-			const struct nls_table *);
-extern int setup_ntlm_response(struct cifs_ses *, const struct nls_table *);
 extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
 extern void cifs_crypto_secmech_release(struct TCP_Server_Info *server);
 extern int calc_seckey(struct cifs_ses *);
@@ -550,8 +543,6 @@ extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
 extern int mdfour(unsigned char *, unsigned char *, int);
 extern int E_md4hash(const unsigned char *passwd, unsigned char *p16,
 			const struct nls_table *codepage);
-extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
-			unsigned char *p24);
 
 extern int
 cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 3781eee9360a..7dba7b59dd51 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3642,168 +3642,6 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
 }
 #endif
 
-/*
- * Issue a TREE_CONNECT request.
- */
-int
-CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
-	 const char *tree, struct cifs_tcon *tcon,
-	 const struct nls_table *nls_codepage)
-{
-	struct smb_hdr *smb_buffer;
-	struct smb_hdr *smb_buffer_response;
-	TCONX_REQ *pSMB;
-	TCONX_RSP *pSMBr;
-	unsigned char *bcc_ptr;
-	int rc = 0;
-	int length;
-	__u16 bytes_left, count;
-
-	if (ses == NULL)
-		return -EIO;
-
-	smb_buffer = cifs_buf_get();
-	if (smb_buffer == NULL)
-		return -ENOMEM;
-
-	smb_buffer_response = smb_buffer;
-
-	header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
-			NULL /*no tid */ , 4 /*wct */ );
-
-	smb_buffer->Mid = get_next_mid(ses->server);
-	smb_buffer->Uid = ses->Suid;
-	pSMB = (TCONX_REQ *) smb_buffer;
-	pSMBr = (TCONX_RSP *) smb_buffer_response;
-
-	pSMB->AndXCommand = 0xFF;
-	pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
-	bcc_ptr = &pSMB->Password[0];
-	if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) {
-		pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
-		*bcc_ptr = 0; /* password is null byte */
-		bcc_ptr++;              /* skip password */
-		/* already aligned so no need to do it below */
-	} else {
-		pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-		/* BB FIXME add code to fail this if NTLMv2 or Kerberos
-		   specified as required (when that support is added to
-		   the vfs in the future) as only NTLM or the much
-		   weaker LANMAN (which we do not send by default) is accepted
-		   by Samba (not sure whether other servers allow
-		   NTLMv2 password here) */
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-		if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
-		    (ses->sectype == LANMAN))
-			calc_lanman_hash(tcon->password, ses->server->cryptkey,
-					 ses->server->sec_mode &
-					    SECMODE_PW_ENCRYPT ? true : false,
-					 bcc_ptr);
-		else
-#endif /* CIFS_WEAK_PW_HASH */
-		rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
-					bcc_ptr, nls_codepage);
-		if (rc) {
-			cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
-				 __func__, rc);
-			cifs_buf_release(smb_buffer);
-			return rc;
-		}
-
-		bcc_ptr += CIFS_AUTH_RESP_SIZE;
-		if (ses->capabilities & CAP_UNICODE) {
-			/* must align unicode strings */
-			*bcc_ptr = 0; /* null byte password */
-			bcc_ptr++;
-		}
-	}
-
-	if (ses->server->sign)
-		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
-	if (ses->capabilities & CAP_STATUS32) {
-		smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
-	}
-	if (ses->capabilities & CAP_DFS) {
-		smb_buffer->Flags2 |= SMBFLG2_DFS;
-	}
-	if (ses->capabilities & CAP_UNICODE) {
-		smb_buffer->Flags2 |= SMBFLG2_UNICODE;
-		length =
-		    cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
-			6 /* max utf8 char length in bytes */ *
-			(/* server len*/ + 256 /* share len */), nls_codepage);
-		bcc_ptr += 2 * length;	/* convert num 16 bit words to bytes */
-		bcc_ptr += 2;	/* skip trailing null */
-	} else {		/* ASCII */
-		strcpy(bcc_ptr, tree);
-		bcc_ptr += strlen(tree) + 1;
-	}
-	strcpy(bcc_ptr, "?????");
-	bcc_ptr += strlen("?????");
-	bcc_ptr += 1;
-	count = bcc_ptr - &pSMB->Password[0];
-	be32_add_cpu(&pSMB->hdr.smb_buf_length, count);
-	pSMB->ByteCount = cpu_to_le16(count);
-
-	rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
-			 0);
-
-	/* above now done in SendReceive */
-	if (rc == 0) {
-		bool is_unicode;
-
-		tcon->tidStatus = CifsGood;
-		tcon->need_reconnect = false;
-		tcon->tid = smb_buffer_response->Tid;
-		bcc_ptr = pByteArea(smb_buffer_response);
-		bytes_left = get_bcc(smb_buffer_response);
-		length = strnlen(bcc_ptr, bytes_left - 2);
-		if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
-			is_unicode = true;
-		else
-			is_unicode = false;
-
-
-		/* skip service field (NB: this field is always ASCII) */
-		if (length == 3) {
-			if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
-			    (bcc_ptr[2] == 'C')) {
-				cifs_dbg(FYI, "IPC connection\n");
-				tcon->ipc = true;
-				tcon->pipe = true;
-			}
-		} else if (length == 2) {
-			if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
-				/* the most common case */
-				cifs_dbg(FYI, "disk share connection\n");
-			}
-		}
-		bcc_ptr += length + 1;
-		bytes_left -= (length + 1);
-		strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
-
-		/* mostly informational -- no need to fail on error here */
-		kfree(tcon->nativeFileSystem);
-		tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
-						      bytes_left, is_unicode,
-						      nls_codepage);
-
-		cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
-
-		if ((smb_buffer_response->WordCount == 3) ||
-			 (smb_buffer_response->WordCount == 7))
-			/* field is in same location */
-			tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
-		else
-			tcon->Flags = 0;
-		cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
-	}
-
-	cifs_buf_release(smb_buffer);
-	return rc;
-}
-
 static void delayed_free(struct rcu_head *p)
 {
 	struct cifs_sb_info *cifs_sb = container_of(p, struct cifs_sb_info, rcu);
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 378133ce8869..54f740c75be6 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -124,3 +124,4 @@ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, struct cifs_ses *ses);
 int build_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
 			struct cifs_ses *ses,
 			const struct nls_table *nls_cp);
+int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp);
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index c5785fd3f52e..34a990e1ae44 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -1061,6 +1061,8 @@ sess_auth_lanman(struct sess_data *sess_data)
 
 #endif
 
+
+#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
 static void
 sess_auth_ntlm(struct sess_data *sess_data)
 {
@@ -1170,6 +1172,7 @@ sess_auth_ntlm(struct sess_data *sess_data)
 	kfree(ses->auth_key.response);
 	ses->auth_key.response = NULL;
 }
+#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 
 static void
 sess_auth_ntlmv2(struct sess_data *sess_data)
@@ -1687,9 +1690,11 @@ static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
 #else
 		return -EOPNOTSUPP;
 #endif
+#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
 	case NTLM:
 		sess_data->func = sess_auth_ntlm;
 		break;
+#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 	case NTLMv2:
 		sess_data->func = sess_auth_ntlmv2;
 		break;
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index eef378055a24..5d29d3a16301 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -5,6 +5,7 @@
  *  Copyright (c) 2012, Jeff Layton <jlayton@redhat.com>
  */
 
+#include <linux/fips.h>
 #include <linux/pagemap.h>
 #include <linux/vfs.h>
 #include "cifsglob.h"
@@ -13,8 +14,103 @@
 #include "cifspdu.h"
 #include "cifs_unicode.h"
 #include "fs_context.h"
+#include "ntlmssp.h"
+
+#include <crypto/des.h>
+
+static void
+str_to_key(unsigned char *str, unsigned char *key)
+{
+	int i;
+
+	key[0] = str[0] >> 1;
+	key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
+	key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
+	key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
+	key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
+	key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
+	key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
+	key[7] = str[6] & 0x7F;
+	for (i = 0; i < 8; i++)
+		key[i] = (key[i] << 1);
+}
+
+static int
+smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
+{
+	unsigned char key2[8];
+	struct des_ctx ctx;
+
+	str_to_key(key, key2);
+
+	if (fips_enabled) {
+		cifs_dbg(VFS, "FIPS compliance enabled: DES not permitted\n");
+		return -ENOENT;
+	}
+
+	des_expand_key(&ctx, key2, DES_KEY_SIZE);
+	des_encrypt(&ctx, out, in);
+	memzero_explicit(&ctx, sizeof(ctx));
+
+	return 0;
+}
+
+static int
+E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
+{
+	int rc;
+
+	rc = smbhash(p24, c8, p21);
+	if (rc)
+		return rc;
+	rc = smbhash(p24 + 8, c8, p21 + 7);
+	if (rc)
+		return rc;
+	rc = smbhash(p24 + 16, c8, p21 + 14);
+	return rc;
+}
 
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
+static int
+E_P16(unsigned char *p14, unsigned char *p16)
+{
+	int rc;
+	unsigned char sp8[8] =
+	    { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+
+	rc = smbhash(p16, sp8, p14);
+	if (rc)
+		return rc;
+	rc = smbhash(p16 + 8, sp8, p14 + 7);
+	return rc;
+}
+
+/*
+   This implements the X/Open SMB password encryption
+   It takes a password, a 8 byte "crypt key" and puts 24 bytes of
+   encrypted password into p24 */
+/* Note that password must be uppercased and null terminated */
+static int
+SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
+{
+	int rc;
+	unsigned char p14[14], p16[16], p21[21];
+
+	memset(p14, '\0', 14);
+	memset(p16, '\0', 16);
+	memset(p21, '\0', 21);
+
+	memcpy(p14, passwd, 14);
+	rc = E_P16(p14, p16);
+	if (rc)
+		return rc;
+
+	memcpy(p21, p16, 16);
+	rc = E_P24(p21, c8, p24);
+
+	return rc;
+}
+
 int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
 			char *lnm_session_key)
 {
@@ -56,6 +152,229 @@ int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
 }
 #endif /* CIFS_WEAK_PW_HASH */
 
+/* Does the NT MD4 hash then des encryption. */
+static int
+SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
+		const struct nls_table *codepage)
+{
+	int rc;
+	unsigned char p16[16], p21[21];
+
+	memset(p16, '\0', 16);
+	memset(p21, '\0', 21);
+
+	rc = E_md4hash(passwd, p16, codepage);
+	if (rc) {
+		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
+			 __func__, rc);
+		return rc;
+	}
+	memcpy(p21, p16, 16);
+	rc = E_P24(p21, c8, p24);
+	return rc;
+}
+
+/*
+ * Issue a TREE_CONNECT request.
+ */
+static int
+CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
+	 const char *tree, struct cifs_tcon *tcon,
+	 const struct nls_table *nls_codepage)
+{
+	struct smb_hdr *smb_buffer;
+	struct smb_hdr *smb_buffer_response;
+	TCONX_REQ *pSMB;
+	TCONX_RSP *pSMBr;
+	unsigned char *bcc_ptr;
+	int rc = 0;
+	int length;
+	__u16 bytes_left, count;
+
+	if (ses == NULL)
+		return -EIO;
+
+	smb_buffer = cifs_buf_get();
+	if (smb_buffer == NULL)
+		return -ENOMEM;
+
+	smb_buffer_response = smb_buffer;
+
+	header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
+			NULL /*no tid */ , 4 /*wct */ );
+
+	smb_buffer->Mid = get_next_mid(ses->server);
+	smb_buffer->Uid = ses->Suid;
+	pSMB = (TCONX_REQ *) smb_buffer;
+	pSMBr = (TCONX_RSP *) smb_buffer_response;
+
+	pSMB->AndXCommand = 0xFF;
+	pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
+	bcc_ptr = &pSMB->Password[0];
+	if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) {
+		pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
+		*bcc_ptr = 0; /* password is null byte */
+		bcc_ptr++;              /* skip password */
+		/* already aligned so no need to do it below */
+	} else {
+		pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
+		/* BB FIXME add code to fail this if NTLMv2 or Kerberos
+		   specified as required (when that support is added to
+		   the vfs in the future) as only NTLM or the much
+		   weaker LANMAN (which we do not send by default) is accepted
+		   by Samba (not sure whether other servers allow
+		   NTLMv2 password here) */
+#ifdef CONFIG_CIFS_WEAK_PW_HASH
+		if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
+		    (ses->sectype == LANMAN))
+			calc_lanman_hash(tcon->password, ses->server->cryptkey,
+					 ses->server->sec_mode &
+					    SECMODE_PW_ENCRYPT ? true : false,
+					 bcc_ptr);
+		else
+#endif /* CIFS_WEAK_PW_HASH */
+		rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
+					bcc_ptr, nls_codepage);
+		if (rc) {
+			cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
+				 __func__, rc);
+			cifs_buf_release(smb_buffer);
+			return rc;
+		}
+
+		bcc_ptr += CIFS_AUTH_RESP_SIZE;
+		if (ses->capabilities & CAP_UNICODE) {
+			/* must align unicode strings */
+			*bcc_ptr = 0; /* null byte password */
+			bcc_ptr++;
+		}
+	}
+
+	if (ses->server->sign)
+		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+
+	if (ses->capabilities & CAP_STATUS32) {
+		smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
+	}
+	if (ses->capabilities & CAP_DFS) {
+		smb_buffer->Flags2 |= SMBFLG2_DFS;
+	}
+	if (ses->capabilities & CAP_UNICODE) {
+		smb_buffer->Flags2 |= SMBFLG2_UNICODE;
+		length =
+		    cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
+			6 /* max utf8 char length in bytes */ *
+			(/* server len*/ + 256 /* share len */), nls_codepage);
+		bcc_ptr += 2 * length;	/* convert num 16 bit words to bytes */
+		bcc_ptr += 2;	/* skip trailing null */
+	} else {		/* ASCII */
+		strcpy(bcc_ptr, tree);
+		bcc_ptr += strlen(tree) + 1;
+	}
+	strcpy(bcc_ptr, "?????");
+	bcc_ptr += strlen("?????");
+	bcc_ptr += 1;
+	count = bcc_ptr - &pSMB->Password[0];
+	be32_add_cpu(&pSMB->hdr.smb_buf_length, count);
+	pSMB->ByteCount = cpu_to_le16(count);
+
+	rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
+			 0);
+
+	/* above now done in SendReceive */
+	if (rc == 0) {
+		bool is_unicode;
+
+		tcon->tidStatus = CifsGood;
+		tcon->need_reconnect = false;
+		tcon->tid = smb_buffer_response->Tid;
+		bcc_ptr = pByteArea(smb_buffer_response);
+		bytes_left = get_bcc(smb_buffer_response);
+		length = strnlen(bcc_ptr, bytes_left - 2);
+		if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
+			is_unicode = true;
+		else
+			is_unicode = false;
+
+
+		/* skip service field (NB: this field is always ASCII) */
+		if (length == 3) {
+			if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
+			    (bcc_ptr[2] == 'C')) {
+				cifs_dbg(FYI, "IPC connection\n");
+				tcon->ipc = true;
+				tcon->pipe = true;
+			}
+		} else if (length == 2) {
+			if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
+				/* the most common case */
+				cifs_dbg(FYI, "disk share connection\n");
+			}
+		}
+		bcc_ptr += length + 1;
+		bytes_left -= (length + 1);
+		strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
+
+		/* mostly informational -- no need to fail on error here */
+		kfree(tcon->nativeFileSystem);
+		tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
+						      bytes_left, is_unicode,
+						      nls_codepage);
+
+		cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
+
+		if ((smb_buffer_response->WordCount == 3) ||
+			 (smb_buffer_response->WordCount == 7))
+			/* field is in same location */
+			tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
+		else
+			tcon->Flags = 0;
+		cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
+	}
+
+	cifs_buf_release(smb_buffer);
+	return rc;
+}
+
+/* first calculate 24 bytes ntlm response and then 16 byte session key */
+int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
+{
+	int rc = 0;
+	unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
+	char temp_key[CIFS_SESS_KEY_SIZE];
+
+	if (!ses)
+		return -EINVAL;
+
+	ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
+	if (!ses->auth_key.response)
+		return -ENOMEM;
+
+	ses->auth_key.len = temp_len;
+
+	rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
+			ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
+	if (rc) {
+		cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
+			 __func__, rc);
+		return rc;
+	}
+
+	rc = E_md4hash(ses->password, temp_key, nls_cp);
+	if (rc) {
+		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
+			 __func__, rc);
+		return rc;
+	}
+
+	rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
+	if (rc)
+		cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
+			 __func__, rc);
+
+	return rc;
+}
+
 /*
  * An NT cancel request header looks just like the original request except:
  *
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 39a938443e3e..0c5617427be9 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -18,7 +18,6 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/random.h>
-#include <crypto/des.h>
 #include "cifs_fs_sb.h"
 #include "cifs_unicode.h"
 #include "cifspdu.h"
@@ -38,72 +37,6 @@
 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
 
-static void
-str_to_key(unsigned char *str, unsigned char *key)
-{
-	int i;
-
-	key[0] = str[0] >> 1;
-	key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
-	key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
-	key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
-	key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
-	key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
-	key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
-	key[7] = str[6] & 0x7F;
-	for (i = 0; i < 8; i++)
-		key[i] = (key[i] << 1);
-}
-
-static int
-smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
-{
-	unsigned char key2[8];
-	struct des_ctx ctx;
-
-	str_to_key(key, key2);
-
-	if (fips_enabled) {
-		cifs_dbg(VFS, "FIPS compliance enabled: DES not permitted\n");
-		return -ENOENT;
-	}
-
-	des_expand_key(&ctx, key2, DES_KEY_SIZE);
-	des_encrypt(&ctx, out, in);
-	memzero_explicit(&ctx, sizeof(ctx));
-
-	return 0;
-}
-
-static int
-E_P16(unsigned char *p14, unsigned char *p16)
-{
-	int rc;
-	unsigned char sp8[8] =
-	    { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
-
-	rc = smbhash(p16, sp8, p14);
-	if (rc)
-		return rc;
-	rc = smbhash(p16 + 8, sp8, p14 + 7);
-	return rc;
-}
-
-static int
-E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
-{
-	int rc;
-
-	rc = smbhash(p24, c8, p21);
-	if (rc)
-		return rc;
-	rc = smbhash(p24 + 8, c8, p21 + 7);
-	if (rc)
-		return rc;
-	rc = smbhash(p24 + 16, c8, p21 + 14);
-	return rc;
-}
-
 /* produce a md4 message digest from data of length n bytes */
 int
 mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
@@ -135,32 +68,6 @@ mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
 	return rc;
 }
 
-/*
-   This implements the X/Open SMB password encryption
-   It takes a password, a 8 byte "crypt key" and puts 24 bytes of
-   encrypted password into p24 */
-/* Note that password must be uppercased and null terminated */
-int
-SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
-{
-	int rc;
-	unsigned char p14[14], p16[16], p21[21];
-
-	memset(p14, '\0', 14);
-	memset(p16, '\0', 16);
-	memset(p21, '\0', 21);
-
-	memcpy(p14, passwd, 14);
-	rc = E_P16(p14, p16);
-	if (rc)
-		return rc;
-
-	memcpy(p21, p16, 16);
-	rc = E_P24(p21, c8, p24);
-
-	return rc;
-}
-
 /*
  * Creates the MD4 Hash of the users password in NT UNICODE.
  */
@@ -187,24 +94,3 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16,
 	return rc;
 }
 
-/* Does the NT MD4 hash then des encryption. */
-int
-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
-		const struct nls_table *codepage)
-{
-	int rc;
-	unsigned char p16[16], p21[21];
-
-	memset(p16, '\0', 16);
-	memset(p21, '\0', 21);
-
-	rc = E_md4hash(passwd, p16, codepage);
-	if (rc) {
-		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
-			 __func__, rc);
-		return rc;
-	}
-	memcpy(p21, p16, 16);
-	rc = E_P24(p21, c8, p24);
-	return rc;
-}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-08-17 17:19 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-17  5:24 [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY Ronnie Sahlberg
2021-08-17  5:24 ` [PATCH 2/3] cifs: move calc_lanman_hash to smb1ops.c Ronnie Sahlberg
2021-08-17  5:24 ` [PATCH 3/3] cifs: move functions that depend on DES to smp1ops.c Ronnie Sahlberg
2021-08-17  5:51   ` Steve French
2021-08-17  8:02 ` [PATCH 1/3] cifs: only compile in smb1ops.c if we configure CIFS_ALLOW_INSECURE_LEGACY kernel test robot
2021-08-17 17:19 ` kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2021-08-13 19:56 cifs: only compile with DES when building with SMB1 support Ronnie Sahlberg
2021-08-13 19:56 ` [PATCH 3/3] cifs: move functions that depend on DES to smp1ops.c Ronnie Sahlberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.