diff options
author | Pavel Shilovsky <pshilov@microsoft.com> | 2016-11-03 16:47:37 -0700 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2017-02-01 16:46:36 -0600 |
commit | 026e93dc0a3eefb0be060bcb9ecd8d7a7fd5c398 (patch) | |
tree | 1816fb41fc8a99d0d967a3ebb324f341b5eaee3e /fs/cifs/smb2transport.c | |
parent | cabfb3680f78981d26c078a26e5c748531257ebb (diff) |
CIFS: Encrypt SMB3 requests before sending
This change allows to encrypt packets if it is required by a server
for SMB sessions or tree connections.
Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
Diffstat (limited to 'fs/cifs/smb2transport.c')
-rw-r--r-- | fs/cifs/smb2transport.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index 93b27752b634..3caa11dd957a 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -31,6 +31,7 @@ #include <asm/processor.h> #include <linux/mempool.h> #include <linux/highmem.h> +#include <crypto/aead.h> #include "smb2pdu.h" #include "cifsglob.h" #include "cifsproto.h" @@ -114,14 +115,14 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server) return 0; } -static struct cifs_ses * -smb2_find_smb_ses(struct smb2_sync_hdr *shdr, struct TCP_Server_Info *server) +struct cifs_ses * +smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id) { struct cifs_ses *ses; spin_lock(&cifs_tcp_ses_lock); list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { - if (ses->Suid != shdr->SessionId) + if (ses->Suid != ses_id) continue; spin_unlock(&cifs_tcp_ses_lock); return ses; @@ -141,7 +142,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[1].iov_base; struct cifs_ses *ses; - ses = smb2_find_smb_ses(shdr, server); + ses = smb2_find_smb_ses(server, shdr->SessionId); if (!ses) { cifs_dbg(VFS, "%s: Could not find session\n", __func__); return 0; @@ -358,7 +359,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[1].iov_base; struct cifs_ses *ses; - ses = smb2_find_smb_ses(shdr, server); + ses = smb2_find_smb_ses(server, shdr->SessionId); if (!ses) { cifs_dbg(VFS, "%s: Could not find session\n", __func__); return 0; @@ -618,3 +619,33 @@ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst) return mid; } + +int +smb3_crypto_aead_allocate(struct TCP_Server_Info *server) +{ + struct crypto_aead *tfm; + + if (!server->secmech.ccmaesencrypt) { + tfm = crypto_alloc_aead("ccm(aes)", 0, 0); + if (IS_ERR(tfm)) { + cifs_dbg(VFS, "%s: Failed to alloc encrypt aead\n", + __func__); + return PTR_ERR(tfm); + } + server->secmech.ccmaesencrypt = tfm; + } + + if (!server->secmech.ccmaesdecrypt) { + tfm = crypto_alloc_aead("ccm(aes)", 0, 0); + if (IS_ERR(tfm)) { + crypto_free_aead(server->secmech.ccmaesencrypt); + server->secmech.ccmaesencrypt = NULL; + cifs_dbg(VFS, "%s: Failed to alloc decrypt aead\n", + __func__); + return PTR_ERR(tfm); + } + server->secmech.ccmaesdecrypt = tfm; + } + + return 0; +} |