aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2transport.c
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2013-07-04 11:35:21 -0400
committerSteve French <smfrench@gmail.com>2013-07-04 15:38:08 -0400
commit95dc8dd14e2e84cc3adabc8310768c13758e7d96 (patch)
treea0c0bb7bd46fd3d527011bb14b53972decf6a818 /fs/cifs/smb2transport.c
parent80cc38b16389849a6e06441ace4530f6b2497c3c (diff)
Limit allocation of crypto mechanisms to dialect which requires
Updated patch to try to prevent allocation of cifs, smb2 or smb3 crypto secmech structures unless needed. Currently cifs allocates all crypto mechanisms when the first session is established (4 functions and 4 contexts), rather than only allocating these when needed (smb3 needs two, the rest of the dialects only need one). Acked-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/smb2transport.c')
-rw-r--r--fs/cifs/smb2transport.c90
1 files changed, 89 insertions, 1 deletions
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
index 09b4fbaadeb6..301b191270b9 100644
--- a/fs/cifs/smb2transport.c
+++ b/fs/cifs/smb2transport.c
@@ -39,6 +39,77 @@
39#include "smb2status.h" 39#include "smb2status.h"
40#include "smb2glob.h" 40#include "smb2glob.h"
41 41
42static int
43smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
44{
45 unsigned int size;
46
47 if (server->secmech.sdeschmacsha256 != NULL)
48 return 0; /* already allocated */
49
50 server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
51 if (IS_ERR(server->secmech.hmacsha256)) {
52 cifs_dbg(VFS, "could not allocate crypto hmacsha256\n");
53 return PTR_ERR(server->secmech.hmacsha256);
54 }
55
56 size = sizeof(struct shash_desc) +
57 crypto_shash_descsize(server->secmech.hmacsha256);
58 server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
59 if (!server->secmech.sdeschmacsha256) {
60 crypto_free_shash(server->secmech.hmacsha256);
61 server->secmech.hmacsha256 = NULL;
62 return -ENOMEM;
63 }
64 server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
65 server->secmech.sdeschmacsha256->shash.flags = 0x0;
66
67 return 0;
68}
69
70static int
71smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
72{
73 unsigned int size;
74 int rc;
75
76 if (server->secmech.sdesccmacaes != NULL)
77 return 0; /* already allocated */
78
79 rc = smb2_crypto_shash_allocate(server);
80 if (rc)
81 return rc;
82
83 server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
84 if (IS_ERR(server->secmech.cmacaes)) {
85 cifs_dbg(VFS, "could not allocate crypto cmac-aes");
86 kfree(server->secmech.sdeschmacsha256);
87 server->secmech.sdeschmacsha256 = NULL;
88 crypto_free_shash(server->secmech.hmacsha256);
89 server->secmech.hmacsha256 = NULL;
90 return PTR_ERR(server->secmech.cmacaes);
91 }
92
93 size = sizeof(struct shash_desc) +
94 crypto_shash_descsize(server->secmech.cmacaes);
95 server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
96 if (!server->secmech.sdesccmacaes) {
97 cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
98 kfree(server->secmech.sdeschmacsha256);
99 server->secmech.sdeschmacsha256 = NULL;
100 crypto_free_shash(server->secmech.hmacsha256);
101 crypto_free_shash(server->secmech.cmacaes);
102 server->secmech.hmacsha256 = NULL;
103 server->secmech.cmacaes = NULL;
104 return -ENOMEM;
105 }
106 server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
107 server->secmech.sdesccmacaes->shash.flags = 0x0;
108
109 return 0;
110}
111
112
42int 113int
43smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) 114smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
44{ 115{
@@ -52,6 +123,12 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
52 memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE); 123 memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
53 memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE); 124 memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
54 125
126 rc = smb2_crypto_shash_allocate(server);
127 if (rc) {
128 cifs_dbg(VFS, "%s: shah256 alloc failed\n", __func__);
129 return rc;
130 }
131
55 rc = crypto_shash_setkey(server->secmech.hmacsha256, 132 rc = crypto_shash_setkey(server->secmech.hmacsha256,
56 server->session_key.response, SMB2_NTLMV2_SESSKEY_SIZE); 133 server->session_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
57 if (rc) { 134 if (rc) {
@@ -61,7 +138,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
61 138
62 rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash); 139 rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
63 if (rc) { 140 if (rc) {
64 cifs_dbg(VFS, "%s: Could not init md5\n", __func__); 141 cifs_dbg(VFS, "%s: Could not init sha256", __func__);
65 return rc; 142 return rc;
66 } 143 }
67 144
@@ -129,6 +206,12 @@ generate_smb3signingkey(struct TCP_Server_Info *server)
129 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE); 206 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
130 memset(server->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE); 207 memset(server->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE);
131 208
209 rc = smb3_crypto_shash_allocate(server);
210 if (rc) {
211 cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
212 goto smb3signkey_ret;
213 }
214
132 rc = crypto_shash_setkey(server->secmech.hmacsha256, 215 rc = crypto_shash_setkey(server->secmech.hmacsha256,
133 server->session_key.response, SMB2_NTLMV2_SESSKEY_SIZE); 216 server->session_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
134 if (rc) { 217 if (rc) {
@@ -210,6 +293,11 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
210 return rc; 293 return rc;
211 } 294 }
212 295
296 /*
297 * we already allocate sdesccmacaes when we init smb3 signing key,
298 * so unlike smb2 case we do not have to check here if secmech are
299 * initialized
300 */
213 rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash); 301 rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash);
214 if (rc) { 302 if (rc) {
215 cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__); 303 cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);