aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/smb2transport.c')
-rw-r--r--fs/cifs/smb2transport.c70
1 files changed, 52 insertions, 18 deletions
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
index 4f2300d020c7..340abca3aa52 100644
--- a/fs/cifs/smb2transport.c
+++ b/fs/cifs/smb2transport.c
@@ -114,6 +114,23 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
114 return 0; 114 return 0;
115} 115}
116 116
117static struct cifs_ses *
118smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server)
119{
120 struct cifs_ses *ses;
121
122 spin_lock(&cifs_tcp_ses_lock);
123 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
124 if (ses->Suid != smb2hdr->SessionId)
125 continue;
126 spin_unlock(&cifs_tcp_ses_lock);
127 return ses;
128 }
129 spin_unlock(&cifs_tcp_ses_lock);
130
131 return NULL;
132}
133
117 134
118int 135int
119smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) 136smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
@@ -124,6 +141,13 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
124 struct kvec *iov = rqst->rq_iov; 141 struct kvec *iov = rqst->rq_iov;
125 int n_vec = rqst->rq_nvec; 142 int n_vec = rqst->rq_nvec;
126 struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base; 143 struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
144 struct cifs_ses *ses;
145
146 ses = smb2_find_smb_ses(smb2_pdu, server);
147 if (!ses) {
148 cifs_dbg(VFS, "%s: Could not find session\n", __func__);
149 return 0;
150 }
127 151
128 memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE); 152 memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
129 memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE); 153 memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
@@ -135,7 +159,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
135 } 159 }
136 160
137 rc = crypto_shash_setkey(server->secmech.hmacsha256, 161 rc = crypto_shash_setkey(server->secmech.hmacsha256,
138 server->session_key.response, SMB2_NTLMV2_SESSKEY_SIZE); 162 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
139 if (rc) { 163 if (rc) {
140 cifs_dbg(VFS, "%s: Could not update with response\n", __func__); 164 cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
141 return rc; 165 return rc;
@@ -198,8 +222,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
198 return rc; 222 return rc;
199} 223}
200 224
201void 225int
202generate_smb3signingkey(struct TCP_Server_Info *server) 226generate_smb3signingkey(struct cifs_ses *ses)
203{ 227{
204 unsigned char zero = 0x0; 228 unsigned char zero = 0x0;
205 __u8 i[4] = {0, 0, 0, 1}; 229 __u8 i[4] = {0, 0, 0, 1};
@@ -209,90 +233,99 @@ generate_smb3signingkey(struct TCP_Server_Info *server)
209 unsigned char *hashptr = prfhash; 233 unsigned char *hashptr = prfhash;
210 234
211 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE); 235 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
212 memset(server->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE); 236 memset(ses->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE);
213 237
214 rc = smb3_crypto_shash_allocate(server); 238 rc = smb3_crypto_shash_allocate(ses->server);
215 if (rc) { 239 if (rc) {
216 cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__); 240 cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
217 goto smb3signkey_ret; 241 goto smb3signkey_ret;
218 } 242 }
219 243
220 rc = crypto_shash_setkey(server->secmech.hmacsha256, 244 rc = crypto_shash_setkey(ses->server->secmech.hmacsha256,
221 server->session_key.response, SMB2_NTLMV2_SESSKEY_SIZE); 245 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
222 if (rc) { 246 if (rc) {
223 cifs_dbg(VFS, "%s: Could not set with session key\n", __func__); 247 cifs_dbg(VFS, "%s: Could not set with session key\n", __func__);
224 goto smb3signkey_ret; 248 goto smb3signkey_ret;
225 } 249 }
226 250
227 rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash); 251 rc = crypto_shash_init(&ses->server->secmech.sdeschmacsha256->shash);
228 if (rc) { 252 if (rc) {
229 cifs_dbg(VFS, "%s: Could not init sign hmac\n", __func__); 253 cifs_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
230 goto smb3signkey_ret; 254 goto smb3signkey_ret;
231 } 255 }
232 256
233 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, 257 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
234 i, 4); 258 i, 4);
235 if (rc) { 259 if (rc) {
236 cifs_dbg(VFS, "%s: Could not update with n\n", __func__); 260 cifs_dbg(VFS, "%s: Could not update with n\n", __func__);
237 goto smb3signkey_ret; 261 goto smb3signkey_ret;
238 } 262 }
239 263
240 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, 264 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
241 "SMB2AESCMAC", 12); 265 "SMB2AESCMAC", 12);
242 if (rc) { 266 if (rc) {
243 cifs_dbg(VFS, "%s: Could not update with label\n", __func__); 267 cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
244 goto smb3signkey_ret; 268 goto smb3signkey_ret;
245 } 269 }
246 270
247 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, 271 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
248 &zero, 1); 272 &zero, 1);
249 if (rc) { 273 if (rc) {
250 cifs_dbg(VFS, "%s: Could not update with zero\n", __func__); 274 cifs_dbg(VFS, "%s: Could not update with zero\n", __func__);
251 goto smb3signkey_ret; 275 goto smb3signkey_ret;
252 } 276 }
253 277
254 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, 278 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
255 "SmbSign", 8); 279 "SmbSign", 8);
256 if (rc) { 280 if (rc) {
257 cifs_dbg(VFS, "%s: Could not update with context\n", __func__); 281 cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
258 goto smb3signkey_ret; 282 goto smb3signkey_ret;
259 } 283 }
260 284
261 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, 285 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
262 L, 4); 286 L, 4);
263 if (rc) { 287 if (rc) {
264 cifs_dbg(VFS, "%s: Could not update with L\n", __func__); 288 cifs_dbg(VFS, "%s: Could not update with L\n", __func__);
265 goto smb3signkey_ret; 289 goto smb3signkey_ret;
266 } 290 }
267 291
268 rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash, 292 rc = crypto_shash_final(&ses->server->secmech.sdeschmacsha256->shash,
269 hashptr); 293 hashptr);
270 if (rc) { 294 if (rc) {
271 cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__); 295 cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
272 goto smb3signkey_ret; 296 goto smb3signkey_ret;
273 } 297 }
274 298
275 memcpy(server->smb3signingkey, hashptr, SMB3_SIGNKEY_SIZE); 299 memcpy(ses->smb3signingkey, hashptr, SMB3_SIGNKEY_SIZE);
276 300
277smb3signkey_ret: 301smb3signkey_ret:
278 return; 302 return rc;
279} 303}
280 304
281int 305int
282smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) 306smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
283{ 307{
284 int i, rc; 308 int i;
309 int rc = 0;
285 unsigned char smb3_signature[SMB2_CMACAES_SIZE]; 310 unsigned char smb3_signature[SMB2_CMACAES_SIZE];
286 unsigned char *sigptr = smb3_signature; 311 unsigned char *sigptr = smb3_signature;
287 struct kvec *iov = rqst->rq_iov; 312 struct kvec *iov = rqst->rq_iov;
288 int n_vec = rqst->rq_nvec; 313 int n_vec = rqst->rq_nvec;
289 struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base; 314 struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
315 struct cifs_ses *ses;
316
317 ses = smb2_find_smb_ses(smb2_pdu, server);
318 if (!ses) {
319 cifs_dbg(VFS, "%s: Could not find session\n", __func__);
320 return 0;
321 }
290 322
291 memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE); 323 memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
292 memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE); 324 memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
293 325
294 rc = crypto_shash_setkey(server->secmech.cmacaes, 326 rc = crypto_shash_setkey(server->secmech.cmacaes,
295 server->smb3signingkey, SMB2_CMACAES_SIZE); 327 ses->smb3signingkey, SMB2_CMACAES_SIZE);
328
296 if (rc) { 329 if (rc) {
297 cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__); 330 cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
298 return rc; 331 return rc;
@@ -389,6 +422,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
389 struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)rqst->rq_iov[0].iov_base; 422 struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
390 423
391 if ((smb2_pdu->Command == SMB2_NEGOTIATE) || 424 if ((smb2_pdu->Command == SMB2_NEGOTIATE) ||
425 (smb2_pdu->Command == SMB2_SESSION_SETUP) ||
392 (smb2_pdu->Command == SMB2_OPLOCK_BREAK) || 426 (smb2_pdu->Command == SMB2_OPLOCK_BREAK) ||
393 (!server->session_estab)) 427 (!server->session_estab))
394 return 0; 428 return 0;