SMB3: Fix 3.11 encryption to Windows and handle encrypted smb3 tcon
authorSteve French <stfrench@microsoft.com>
Sun, 22 Apr 2018 20:14:58 +0000 (15:14 -0500)
committerSteve French <stfrench@microsoft.com>
Tue, 24 Apr 2018 15:07:14 +0000 (10:07 -0500)
Temporarily disable AES-GCM, as AES-CCM is only currently
enabled mechanism on client side.  This fixes SMB3.11
encrypted mounts to Windows.

Also the tree connect request itself should be encrypted if
requested encryption ("seal" on mount), in addition we should be
enabling encryption in 3.11 based on whether we got any valid
encryption ciphers back in negprot (the corresponding session flag is
not set as it is in 3.0 and 3.02)

Signed-off-by: Steve French <smfrench@gmail.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
CC: Stable <stable@vger.kernel.org>
fs/cifs/connect.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h

index e8830f076a7f16a056f7eec3cf025e0e30bff9e8..a5aa158d535a70a2247419152d01b64d553c1596 100644 (file)
@@ -2959,6 +2959,22 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
                }
        }
 
+       if (volume_info->seal) {
+               if (ses->server->vals->protocol_id == 0) {
+                       cifs_dbg(VFS,
+                                "SMB3 or later required for encryption\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+               } else if (tcon->ses->server->capabilities &
+                                       SMB2_GLOBAL_CAP_ENCRYPTION)
+                       tcon->seal = true;
+               else {
+                       cifs_dbg(VFS, "Encryption is not supported on share\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+               }
+       }
+
        /*
         * BB Do we need to wrap session_mutex around this TCon call and Unix
         * SetFS as we do on SessSetup and reconnect?
@@ -3007,22 +3023,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
                tcon->use_resilient = true;
        }
 
-       if (volume_info->seal) {
-               if (ses->server->vals->protocol_id == 0) {
-                       cifs_dbg(VFS,
-                                "SMB3 or later required for encryption\n");
-                       rc = -EOPNOTSUPP;
-                       goto out_fail;
-               } else if (tcon->ses->server->capabilities &
-                                       SMB2_GLOBAL_CAP_ENCRYPTION)
-                       tcon->seal = true;
-               else {
-                       cifs_dbg(VFS, "Encryption is not supported on share\n");
-                       rc = -EOPNOTSUPP;
-                       goto out_fail;
-               }
-       }
-
        /*
         * We can have only one retry value for a connection to a share so for
         * resources mounted more than once to the same server share the last
index 0f044c4a2dc9b5b625e9cae21d34344692b76d23..9aea138dd71fb1d57d89e5f9cd744f3460bf6f51 100644 (file)
@@ -383,10 +383,10 @@ static void
 build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt)
 {
        pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
-       pneg_ctxt->DataLength = cpu_to_le16(6);
-       pneg_ctxt->CipherCount = cpu_to_le16(2);
-       pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;
-       pneg_ctxt->Ciphers[1] = SMB2_ENCRYPTION_AES128_CCM;
+       pneg_ctxt->DataLength = cpu_to_le16(4); /* Cipher Count + le16 cipher */
+       pneg_ctxt->CipherCount = cpu_to_le16(1);
+/* pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;*/ /* not supported yet */
+       pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_CCM;
 }
 
 static void
@@ -444,6 +444,7 @@ static int decode_encrypt_ctx(struct TCP_Server_Info *server,
                return -EINVAL;
        }
        server->cipher_type = ctxt->Ciphers[0];
+       server->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
        return 0;
 }
 
index 6093e5142b2bc3792cf40afb7f7abbc02b60bbb4..d28f358022c507cc0dc55dbebb382ed29dec708d 100644 (file)
@@ -297,7 +297,7 @@ struct smb2_encryption_neg_context {
        __le16  DataLength;
        __le32  Reserved;
        __le16  CipherCount; /* AES-128-GCM and AES-128-CCM */
-       __le16  Ciphers[2]; /* Ciphers[0] since only one used now */
+       __le16  Ciphers[1]; /* Ciphers[0] since only one used now */
 } __packed;
 
 struct smb2_negotiate_rsp {