]> git.ipfire.org Git - thirdparty/linux.git/blame - fs/smb/client/smb2transport.c
cifs: log session id when a matching ses is not found
[thirdparty/linux.git] / fs / smb / client / smb2transport.c
CommitLineData
929be906 1// SPDX-License-Identifier: LGPL-2.1
2dc7e1c0 2/*
2dc7e1c0
PS
3 *
4 * Copyright (C) International Business Machines Corp., 2002, 2011
5 * Etersoft, 2012
6 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Jeremy Allison (jra@samba.org) 2006
8 * Pavel Shilovsky (pshilovsky@samba.org) 2012
9 *
2dc7e1c0
PS
10 */
11
12#include <linux/fs.h>
13#include <linux/list.h>
14#include <linux/wait.h>
15#include <linux/net.h>
16#include <linux/delay.h>
17#include <linux/uaccess.h>
18#include <asm/processor.h>
19#include <linux/mempool.h>
fb308a6f 20#include <linux/highmem.h>
026e93dc 21#include <crypto/aead.h>
2dc7e1c0
PS
22#include "cifsglob.h"
23#include "cifsproto.h"
24#include "smb2proto.h"
25#include "cifs_debug.h"
26#include "smb2status.h"
3c1bf7e4
PS
27#include "smb2glob.h"
28
95dc8dd1
SF
29static int
30smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
31{
82fb82be 32 struct cifs_secmech *p = &server->secmech;
95dc8dd1
SF
33 int rc;
34
1f3d5477 35 rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256);
95dc8dd1 36 if (rc)
82fb82be 37 goto err;
95dc8dd1 38
1f3d5477 39 rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
82fb82be
AA
40 if (rc)
41 goto err;
95dc8dd1
SF
42
43 return 0;
82fb82be 44err:
1f3d5477 45 cifs_free_hash(&p->hmacsha256);
82fb82be 46 return rc;
95dc8dd1
SF
47}
48
5fcd7f3f
AA
49int
50smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
51{
52 struct cifs_secmech *p = &server->secmech;
53 int rc = 0;
54
1f3d5477 55 rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256);
5fcd7f3f
AA
56 if (rc)
57 return rc;
58
1f3d5477 59 rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
5fcd7f3f
AA
60 if (rc)
61 goto err;
62
1f3d5477 63 rc = cifs_alloc_hash("sha512", &p->sha512);
5fcd7f3f
AA
64 if (rc)
65 goto err;
66
67 return 0;
68
69err:
1f3d5477
EM
70 cifs_free_hash(&p->aes_cmac);
71 cifs_free_hash(&p->hmacsha256);
5fcd7f3f
AA
72 return rc;
73}
5fcd7f3f 74
d70e9fa5
AA
75
76static
77int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
78{
79 struct cifs_chan *chan;
23d9b9b7 80 struct TCP_Server_Info *pserver;
d70e9fa5
AA
81 struct cifs_ses *ses = NULL;
82 int i;
83 int rc = 0;
bc962159 84 bool is_binding = false;
d70e9fa5
AA
85
86 spin_lock(&cifs_tcp_ses_lock);
87
23d9b9b7
SP
88 /* If server is a channel, select the primary channel */
89 pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
90
91 list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
92 if (ses->Suid == ses_id)
93 goto found;
d70e9fa5 94 }
ac615db0 95 cifs_server_dbg(FYI, "%s: Could not find session 0x%llx\n",
d70e9fa5
AA
96 __func__, ses_id);
97 rc = -ENOENT;
98 goto out;
99
100found:
bc962159 101 spin_lock(&ses->ses_lock);
88b024f5 102 spin_lock(&ses->chan_lock);
bc962159
SP
103
104 is_binding = (cifs_chan_needs_reconnect(ses, server) &&
105 ses->ses_status == SES_GOOD);
106 if (is_binding) {
d70e9fa5
AA
107 /*
108 * If we are in the process of binding a new channel
109 * to an existing session, use the master connection
110 * session key
111 */
112 memcpy(key, ses->smb3signingkey, SMB3_SIGN_KEY_SIZE);
88b024f5 113 spin_unlock(&ses->chan_lock);
bc962159 114 spin_unlock(&ses->ses_lock);
d70e9fa5
AA
115 goto out;
116 }
117
118 /*
119 * Otherwise, use the channel key.
120 */
121
122 for (i = 0; i < ses->chan_count; i++) {
123 chan = ses->chans + i;
124 if (chan->server == server) {
125 memcpy(key, chan->signkey, SMB3_SIGN_KEY_SIZE);
88b024f5 126 spin_unlock(&ses->chan_lock);
bc962159 127 spin_unlock(&ses->ses_lock);
d70e9fa5
AA
128 goto out;
129 }
130 }
88b024f5 131 spin_unlock(&ses->chan_lock);
bc962159 132 spin_unlock(&ses->ses_lock);
d70e9fa5
AA
133
134 cifs_dbg(VFS,
135 "%s: Could not find channel signing key for session 0x%llx\n",
136 __func__, ses_id);
137 rc = -ENOENT;
138
139out:
140 spin_unlock(&cifs_tcp_ses_lock);
141 return rc;
142}
143
38bd4906
SP
144static struct cifs_ses *
145smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
32811d24 146{
8abcaeae 147 struct TCP_Server_Info *pserver;
32811d24
SP
148 struct cifs_ses *ses;
149
8abcaeae
SP
150 /* If server is a channel, select the primary channel */
151 pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
152
153 list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
026e93dc 154 if (ses->Suid != ses_id)
32811d24 155 continue;
66be5c48
WW
156
157 spin_lock(&ses->ses_lock);
158 if (ses->ses_status == SES_EXITING) {
159 spin_unlock(&ses->ses_lock);
160 continue;
161 }
e695a9ad 162 ++ses->ses_count;
66be5c48 163 spin_unlock(&ses->ses_lock);
32811d24
SP
164 return ses;
165 }
38bd4906
SP
166
167 return NULL;
168}
169
170struct cifs_ses *
171smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
172{
173 struct cifs_ses *ses;
174
175 spin_lock(&cifs_tcp_ses_lock);
176 ses = smb2_find_smb_ses_unlocked(server, ses_id);
32811d24
SP
177 spin_unlock(&cifs_tcp_ses_lock);
178
38bd4906
SP
179 return ses;
180}
181
182static struct cifs_tcon *
183smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32 tid)
184{
185 struct cifs_tcon *tcon;
186
187 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
188 if (tcon->tid != tid)
189 continue;
190 ++tcon->tc_count;
191 return tcon;
192 }
193
32811d24
SP
194 return NULL;
195}
196
38bd4906
SP
197/*
198 * Obtain tcon corresponding to the tid in the given
199 * cifs_ses
200 */
201
202struct cifs_tcon *
203smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid)
204{
205 struct cifs_ses *ses;
206 struct cifs_tcon *tcon;
207
208 spin_lock(&cifs_tcp_ses_lock);
209 ses = smb2_find_smb_ses_unlocked(server, ses_id);
210 if (!ses) {
211 spin_unlock(&cifs_tcp_ses_lock);
212 return NULL;
213 }
214 tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
e695a9ad
SP
215 if (!tcon) {
216 cifs_put_smb_ses(ses);
217 spin_unlock(&cifs_tcp_ses_lock);
218 return NULL;
219 }
38bd4906 220 spin_unlock(&cifs_tcp_ses_lock);
e695a9ad
SP
221 /* tcon already has a ref to ses, so we don't need ses anymore */
222 cifs_put_smb_ses(ses);
38bd4906
SP
223
224 return tcon;
225}
226
38107d45 227int
eda1c54f
LL
228smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
229 bool allocate_crypto)
3c1bf7e4 230{
16c568ef 231 int rc;
3c1bf7e4
PS
232 unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
233 unsigned char *sigptr = smb2_signature;
0b688cfc 234 struct kvec *iov = rqst->rq_iov;
0d35e382 235 struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
32811d24 236 struct cifs_ses *ses;
958553d1 237 struct shash_desc *shash = NULL;
8de8c460 238 struct smb_rqst drqst;
32811d24 239
0d35e382 240 ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId));
09a1f9a1 241 if (unlikely(!ses)) {
afe6f653 242 cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
09a1f9a1 243 return -ENOENT;
32811d24 244 }
3c1bf7e4
PS
245
246 memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
31473fc4 247 memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
3c1bf7e4 248
eda1c54f 249 if (allocate_crypto) {
1f3d5477 250 rc = cifs_alloc_hash("hmac(sha256)", &shash);
eda1c54f
LL
251 if (rc) {
252 cifs_server_dbg(VFS,
253 "%s: sha256 alloc failed\n", __func__);
e695a9ad 254 goto out;
eda1c54f 255 }
eda1c54f 256 } else {
1f3d5477 257 shash = server->secmech.hmacsha256;
95dc8dd1
SF
258 }
259
1f3d5477 260 rc = crypto_shash_setkey(shash->tfm, ses->auth_key.response,
eda1c54f 261 SMB2_NTLMV2_SESSKEY_SIZE);
3c1bf7e4 262 if (rc) {
eda1c54f
LL
263 cifs_server_dbg(VFS,
264 "%s: Could not update with response\n",
265 __func__);
266 goto out;
3c1bf7e4
PS
267 }
268
8de8c460 269 rc = crypto_shash_init(shash);
3c1bf7e4 270 if (rc) {
afe6f653 271 cifs_server_dbg(VFS, "%s: Could not init sha256", __func__);
eda1c54f 272 goto out;
3c1bf7e4
PS
273 }
274
8de8c460
PA
275 /*
276 * For SMB2+, __cifs_calc_signature() expects to sign only the actual
277 * data, that is, iov[0] should not contain a rfc1002 length.
278 *
279 * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
280 * __cifs_calc_signature().
281 */
282 drqst = *rqst;
283 if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
284 rc = crypto_shash_update(shash, iov[0].iov_base,
285 iov[0].iov_len);
286 if (rc) {
eda1c54f
LL
287 cifs_server_dbg(VFS,
288 "%s: Could not update with payload\n",
289 __func__);
290 goto out;
8de8c460
PA
291 }
292 drqst.rq_iov++;
293 drqst.rq_nvec--;
294 }
3c1bf7e4 295
8de8c460 296 rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
16c568ef 297 if (!rc)
31473fc4 298 memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
3c1bf7e4 299
eda1c54f
LL
300out:
301 if (allocate_crypto)
1f3d5477 302 cifs_free_hash(&shash);
e695a9ad
SP
303 if (ses)
304 cifs_put_smb_ses(ses);
3c1bf7e4
PS
305 return rc;
306}
307
373512ec
SF
308static int generate_key(struct cifs_ses *ses, struct kvec label,
309 struct kvec context, __u8 *key, unsigned int key_size)
429b46f4
SF
310{
311 unsigned char zero = 0x0;
312 __u8 i[4] = {0, 0, 0, 1};
45a4546c
SP
313 __u8 L128[4] = {0, 0, 0, 128};
314 __u8 L256[4] = {0, 0, 1, 0};
429b46f4
SF
315 int rc = 0;
316 unsigned char prfhash[SMB2_HMACSHA256_SIZE];
317 unsigned char *hashptr = prfhash;
afe6f653 318 struct TCP_Server_Info *server = ses->server;
429b46f4
SF
319
320 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
373512ec 321 memset(key, 0x0, key_size);
429b46f4 322
afe6f653 323 rc = smb3_crypto_shash_allocate(server);
95dc8dd1 324 if (rc) {
afe6f653 325 cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__);
95dc8dd1
SF
326 goto smb3signkey_ret;
327 }
328
1f3d5477 329 rc = crypto_shash_setkey(server->secmech.hmacsha256->tfm,
32811d24 330 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
429b46f4 331 if (rc) {
afe6f653 332 cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__);
429b46f4
SF
333 goto smb3signkey_ret;
334 }
335
1f3d5477 336 rc = crypto_shash_init(server->secmech.hmacsha256);
429b46f4 337 if (rc) {
afe6f653 338 cifs_server_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
429b46f4
SF
339 goto smb3signkey_ret;
340 }
341
1f3d5477 342 rc = crypto_shash_update(server->secmech.hmacsha256, i, 4);
429b46f4 343 if (rc) {
afe6f653 344 cifs_server_dbg(VFS, "%s: Could not update with n\n", __func__);
429b46f4
SF
345 goto smb3signkey_ret;
346 }
347
1f3d5477 348 rc = crypto_shash_update(server->secmech.hmacsha256, label.iov_base, label.iov_len);
429b46f4 349 if (rc) {
afe6f653 350 cifs_server_dbg(VFS, "%s: Could not update with label\n", __func__);
429b46f4
SF
351 goto smb3signkey_ret;
352 }
353
1f3d5477 354 rc = crypto_shash_update(server->secmech.hmacsha256, &zero, 1);
429b46f4 355 if (rc) {
afe6f653 356 cifs_server_dbg(VFS, "%s: Could not update with zero\n", __func__);
429b46f4
SF
357 goto smb3signkey_ret;
358 }
359
1f3d5477 360 rc = crypto_shash_update(server->secmech.hmacsha256, context.iov_base, context.iov_len);
429b46f4 361 if (rc) {
afe6f653 362 cifs_server_dbg(VFS, "%s: Could not update with context\n", __func__);
429b46f4
SF
363 goto smb3signkey_ret;
364 }
365
45a4546c
SP
366 if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
367 (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
1f3d5477 368 rc = crypto_shash_update(server->secmech.hmacsha256, L256, 4);
45a4546c 369 } else {
1f3d5477 370 rc = crypto_shash_update(server->secmech.hmacsha256, L128, 4);
45a4546c 371 }
429b46f4 372 if (rc) {
afe6f653 373 cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__);
429b46f4
SF
374 goto smb3signkey_ret;
375 }
376
1f3d5477 377 rc = crypto_shash_final(server->secmech.hmacsha256, hashptr);
429b46f4 378 if (rc) {
afe6f653 379 cifs_server_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
429b46f4
SF
380 goto smb3signkey_ret;
381 }
382
373512ec 383 memcpy(key, hashptr, key_size);
429b46f4
SF
384
385smb3signkey_ret:
32811d24 386 return rc;
429b46f4
SF
387}
388
373512ec
SF
389struct derivation {
390 struct kvec label;
391 struct kvec context;
392};
393
394struct derivation_triplet {
395 struct derivation signing;
396 struct derivation encryption;
397 struct derivation decryption;
398};
399
400static int
401generate_smb3signingkey(struct cifs_ses *ses,
f486ef8e 402 struct TCP_Server_Info *server,
373512ec
SF
403 const struct derivation_triplet *ptriplet)
404{
405 int rc;
f486ef8e
SP
406 bool is_binding = false;
407 int chan_index = 0;
408
bc962159 409 spin_lock(&ses->ses_lock);
f486ef8e 410 spin_lock(&ses->chan_lock);
bc962159
SP
411 is_binding = (cifs_chan_needs_reconnect(ses, server) &&
412 ses->ses_status == SES_GOOD);
413
f486ef8e
SP
414 chan_index = cifs_ses_get_chan_index(ses, server);
415 /* TODO: introduce ref counting for channels when the can be freed */
416 spin_unlock(&ses->chan_lock);
bc962159 417 spin_unlock(&ses->ses_lock);
373512ec 418
d70e9fa5
AA
419 /*
420 * All channels use the same encryption/decryption keys but
421 * they have their own signing key.
422 *
423 * When we generate the keys, check if it is for a new channel
424 * (binding) in which case we only need to generate a signing
425 * key and store it in the channel as to not overwrite the
426 * master connection signing key stored in the session
427 */
373512ec 428
f486ef8e 429 if (is_binding) {
d70e9fa5
AA
430 rc = generate_key(ses, ptriplet->signing.label,
431 ptriplet->signing.context,
f486ef8e 432 ses->chans[chan_index].signkey,
d70e9fa5
AA
433 SMB3_SIGN_KEY_SIZE);
434 if (rc)
435 return rc;
436 } else {
437 rc = generate_key(ses, ptriplet->signing.label,
438 ptriplet->signing.context,
439 ses->smb3signingkey,
440 SMB3_SIGN_KEY_SIZE);
441 if (rc)
442 return rc;
ff6b6f3f 443
f486ef8e 444 /* safe to access primary channel, since it will never go away */
88b024f5 445 spin_lock(&ses->chan_lock);
05ce0448 446 memcpy(ses->chans[chan_index].signkey, ses->smb3signingkey,
ff6b6f3f 447 SMB3_SIGN_KEY_SIZE);
88b024f5 448 spin_unlock(&ses->chan_lock);
ff6b6f3f 449
d70e9fa5
AA
450 rc = generate_key(ses, ptriplet->encryption.label,
451 ptriplet->encryption.context,
452 ses->smb3encryptionkey,
45a4546c 453 SMB3_ENC_DEC_KEY_SIZE);
d70e9fa5
AA
454 rc = generate_key(ses, ptriplet->decryption.label,
455 ptriplet->decryption.context,
456 ses->smb3decryptionkey,
45a4546c 457 SMB3_ENC_DEC_KEY_SIZE);
d70e9fa5
AA
458 if (rc)
459 return rc;
460 }
d38de3c6
AA
461
462 if (rc)
463 return rc;
464
465#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
466 cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__);
467 /*
468 * The session id is opaque in terms of endianness, so we can't
469 * print it as a long long. we dump it as we got it on the wire
470 */
471 cifs_dbg(VFS, "Session Id %*ph\n", (int)sizeof(ses->Suid),
472 &ses->Suid);
45a4546c 473 cifs_dbg(VFS, "Cipher type %d\n", server->cipher_type);
d38de3c6
AA
474 cifs_dbg(VFS, "Session Key %*ph\n",
475 SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
476 cifs_dbg(VFS, "Signing Key %*ph\n",
477 SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
45a4546c
SP
478 if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
479 (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
480 cifs_dbg(VFS, "ServerIn Key %*ph\n",
481 SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3encryptionkey);
482 cifs_dbg(VFS, "ServerOut Key %*ph\n",
483 SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3decryptionkey);
484 } else {
485 cifs_dbg(VFS, "ServerIn Key %*ph\n",
486 SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3encryptionkey);
487 cifs_dbg(VFS, "ServerOut Key %*ph\n",
488 SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3decryptionkey);
489 }
d38de3c6
AA
490#endif
491 return rc;
373512ec
SF
492}
493
494int
f486ef8e
SP
495generate_smb30signingkey(struct cifs_ses *ses,
496 struct TCP_Server_Info *server)
373512ec
SF
497
498{
499 struct derivation_triplet triplet;
500 struct derivation *d;
501
502 d = &triplet.signing;
503 d->label.iov_base = "SMB2AESCMAC";
504 d->label.iov_len = 12;
505 d->context.iov_base = "SmbSign";
506 d->context.iov_len = 8;
507
508 d = &triplet.encryption;
509 d->label.iov_base = "SMB2AESCCM";
510 d->label.iov_len = 11;
511 d->context.iov_base = "ServerIn ";
512 d->context.iov_len = 10;
513
514 d = &triplet.decryption;
515 d->label.iov_base = "SMB2AESCCM";
516 d->label.iov_len = 11;
517 d->context.iov_base = "ServerOut";
518 d->context.iov_len = 10;
519
f486ef8e 520 return generate_smb3signingkey(ses, server, &triplet);
373512ec
SF
521}
522
523int
f486ef8e
SP
524generate_smb311signingkey(struct cifs_ses *ses,
525 struct TCP_Server_Info *server)
373512ec
SF
526
527{
528 struct derivation_triplet triplet;
529 struct derivation *d;
530
531 d = &triplet.signing;
06e22908
SF
532 d->label.iov_base = "SMBSigningKey";
533 d->label.iov_len = 14;
534 d->context.iov_base = ses->preauth_sha_hash;
535 d->context.iov_len = 64;
373512ec
SF
536
537 d = &triplet.encryption;
06e22908
SF
538 d->label.iov_base = "SMBC2SCipherKey";
539 d->label.iov_len = 16;
540 d->context.iov_base = ses->preauth_sha_hash;
541 d->context.iov_len = 64;
373512ec
SF
542
543 d = &triplet.decryption;
06e22908
SF
544 d->label.iov_base = "SMBS2CCipherKey";
545 d->label.iov_len = 16;
546 d->context.iov_base = ses->preauth_sha_hash;
547 d->context.iov_len = 64;
373512ec 548
f486ef8e 549 return generate_smb3signingkey(ses, server, &triplet);
373512ec
SF
550}
551
38107d45 552int
eda1c54f
LL
553smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
554 bool allocate_crypto)
38107d45 555{
27c32b49 556 int rc;
429b46f4
SF
557 unsigned char smb3_signature[SMB2_CMACAES_SIZE];
558 unsigned char *sigptr = smb3_signature;
559 struct kvec *iov = rqst->rq_iov;
0d35e382 560 struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
958553d1 561 struct shash_desc *shash = NULL;
27c32b49 562 struct smb_rqst drqst;
d70e9fa5 563 u8 key[SMB3_SIGN_KEY_SIZE];
32811d24 564
0d35e382 565 rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
09a1f9a1 566 if (unlikely(rc)) {
ac615db0 567 cifs_server_dbg(FYI, "%s: Could not get signing key\n", __func__);
09a1f9a1
EM
568 return rc;
569 }
429b46f4 570
eda1c54f 571 if (allocate_crypto) {
1f3d5477 572 rc = cifs_alloc_hash("cmac(aes)", &shash);
eda1c54f
LL
573 if (rc)
574 return rc;
eda1c54f 575 } else {
1f3d5477 576 shash = server->secmech.aes_cmac;
eda1c54f
LL
577 }
578
429b46f4 579 memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
31473fc4 580 memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
429b46f4 581
1f3d5477 582 rc = crypto_shash_setkey(shash->tfm, key, SMB2_CMACAES_SIZE);
429b46f4 583 if (rc) {
afe6f653 584 cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
eda1c54f 585 goto out;
429b46f4
SF
586 }
587
95dc8dd1 588 /*
1f3d5477 589 * we already allocate aes_cmac when we init smb3 signing key,
95dc8dd1
SF
590 * so unlike smb2 case we do not have to check here if secmech are
591 * initialized
592 */
27c32b49 593 rc = crypto_shash_init(shash);
429b46f4 594 if (rc) {
afe6f653 595 cifs_server_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
eda1c54f 596 goto out;
429b46f4 597 }
82fb82be 598
27c32b49
PA
599 /*
600 * For SMB2+, __cifs_calc_signature() expects to sign only the actual
601 * data, that is, iov[0] should not contain a rfc1002 length.
602 *
603 * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
604 * __cifs_calc_signature().
605 */
606 drqst = *rqst;
607 if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
608 rc = crypto_shash_update(shash, iov[0].iov_base,
609 iov[0].iov_len);
610 if (rc) {
afe6f653 611 cifs_server_dbg(VFS, "%s: Could not update with payload\n",
27c32b49 612 __func__);
eda1c54f 613 goto out;
27c32b49
PA
614 }
615 drqst.rq_iov++;
616 drqst.rq_nvec--;
617 }
429b46f4 618
27c32b49 619 rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
16c568ef 620 if (!rc)
31473fc4 621 memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
429b46f4 622
eda1c54f
LL
623out:
624 if (allocate_crypto)
1f3d5477 625 cifs_free_hash(&shash);
429b46f4 626 return rc;
38107d45
SF
627}
628
3c1bf7e4
PS
629/* must be called with server->srv_mutex held */
630static int
0b688cfc 631smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
3c1bf7e4
PS
632{
633 int rc = 0;
0d35e382 634 struct smb2_hdr *shdr;
d70e9fa5
AA
635 struct smb2_sess_setup_req *ssr;
636 bool is_binding;
637 bool is_signed;
3c1bf7e4 638
0d35e382 639 shdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
d70e9fa5 640 ssr = (struct smb2_sess_setup_req *)shdr;
3c1bf7e4 641
d70e9fa5
AA
642 is_binding = shdr->Command == SMB2_SESSION_SETUP &&
643 (ssr->Flags & SMB2_SESSION_REQ_FLAG_BINDING);
644 is_signed = shdr->Flags & SMB2_FLAGS_SIGNED;
645
646 if (!is_signed)
647 return 0;
d7d7a66a 648 spin_lock(&server->srv_lock);
1a6a41d4
SP
649 if (server->ops->need_neg &&
650 server->ops->need_neg(server)) {
d7d7a66a 651 spin_unlock(&server->srv_lock);
d70e9fa5 652 return 0;
080dc5e5 653 }
d7d7a66a 654 spin_unlock(&server->srv_lock);
d70e9fa5 655 if (!is_binding && !server->session_estab) {
31473fc4 656 strncpy(shdr->Signature, "BSRSPYL", 8);
d70e9fa5 657 return 0;
3c1bf7e4
PS
658 }
659
eda1c54f 660 rc = server->ops->calc_signature(rqst, server, false);
3c1bf7e4
PS
661
662 return rc;
663}
664
665int
0b688cfc 666smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
3c1bf7e4
PS
667{
668 unsigned int rc;
edad734c 669 char server_response_sig[SMB2_SIGNATURE_SIZE];
0d35e382
RS
670 struct smb2_hdr *shdr =
671 (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
3c1bf7e4 672
31473fc4
PS
673 if ((shdr->Command == SMB2_NEGOTIATE) ||
674 (shdr->Command == SMB2_SESSION_SETUP) ||
675 (shdr->Command == SMB2_OPLOCK_BREAK) ||
4f5c10f1 676 server->ignore_signature ||
3c1bf7e4
PS
677 (!server->session_estab))
678 return 0;
679
680 /*
681 * BB what if signatures are supposed to be on for session but
682 * server does not send one? BB
683 */
684
685 /* Do not need to verify session setups with signature "BSRSPYL " */
31473fc4 686 if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
f96637be 687 cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
31473fc4 688 shdr->Command);
3c1bf7e4
PS
689
690 /*
691 * Save off the origiginal signature so we can modify the smb and check
692 * our calculated signature against what the server sent.
693 */
31473fc4 694 memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
3c1bf7e4 695
31473fc4 696 memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
3c1bf7e4 697
eda1c54f 698 rc = server->ops->calc_signature(rqst, server, true);
3c1bf7e4
PS
699
700 if (rc)
701 return rc;
702
f460c502 703 if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE)) {
9692ea9d
SF
704 cifs_dbg(VFS, "sign fail cmd 0x%x message id 0x%llx\n",
705 shdr->Command, shdr->MessageId);
3c1bf7e4 706 return -EACCES;
f460c502 707 } else
3c1bf7e4
PS
708 return 0;
709}
710
2dc7e1c0
PS
711/*
712 * Set message id for the request. Should be called after wait_for_free_request
713 * and when srv_mutex is held.
714 */
715static inline void
31473fc4 716smb2_seq_num_into_buf(struct TCP_Server_Info *server,
0d35e382 717 struct smb2_hdr *shdr)
2dc7e1c0 718{
31473fc4 719 unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
cb7e9eab 720
31473fc4 721 shdr->MessageId = get_next_mid64(server);
cb7e9eab
PS
722 /* skip message numbers according to CreditCharge field */
723 for (i = 1; i < num; i++)
724 get_next_mid(server);
2dc7e1c0
PS
725}
726
727static struct mid_q_entry *
0d35e382 728smb2_mid_entry_alloc(const struct smb2_hdr *shdr,
2dc7e1c0
PS
729 struct TCP_Server_Info *server)
730{
731 struct mid_q_entry *temp;
c781af7e 732 unsigned int credits = le16_to_cpu(shdr->CreditCharge);
2dc7e1c0
PS
733
734 if (server == NULL) {
f96637be 735 cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
2dc7e1c0
PS
736 return NULL;
737 }
738
739 temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
a6f74e80 740 memset(temp, 0, sizeof(struct mid_q_entry));
696e420b 741 kref_init(&temp->refcount);
a6f74e80 742 temp->mid = le64_to_cpu(shdr->MessageId);
c781af7e 743 temp->credits = credits > 0 ? credits : 1;
a6f74e80
N
744 temp->pid = current->pid;
745 temp->command = shdr->Command; /* Always LE */
746 temp->when_alloc = jiffies;
747 temp->server = server;
748
749 /*
750 * The default is for the mid to be synchronous, so the
751 * default callback just wakes up the current task.
752 */
f1f27ad7
VW
753 get_task_struct(current);
754 temp->creator = current;
a6f74e80
N
755 temp->callback = cifs_wake_up_task;
756 temp->callback_data = current;
2dc7e1c0 757
c2c17ddb 758 atomic_inc(&mid_count);
2dc7e1c0 759 temp->mid_state = MID_REQUEST_ALLOCATED;
0d35e382
RS
760 trace_smb3_cmd_enter(le32_to_cpu(shdr->Id.SyncId.TreeId),
761 le64_to_cpu(shdr->SessionId),
762 le16_to_cpu(shdr->Command), temp->mid);
2dc7e1c0
PS
763 return temp;
764}
765
766static int
f780bd3f 767smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
0d35e382 768 struct smb2_hdr *shdr, struct mid_q_entry **mid)
2dc7e1c0 769{
d7d7a66a 770 spin_lock(&server->srv_lock);
080dc5e5 771 if (server->tcpStatus == CifsExiting) {
d7d7a66a 772 spin_unlock(&server->srv_lock);
2dc7e1c0 773 return -ENOENT;
080dc5e5 774 }
2dc7e1c0 775
f780bd3f 776 if (server->tcpStatus == CifsNeedReconnect) {
d7d7a66a 777 spin_unlock(&server->srv_lock);
f96637be 778 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
2dc7e1c0
PS
779 return -EAGAIN;
780 }
781
f780bd3f 782 if (server->tcpStatus == CifsNeedNegotiate &&
080dc5e5 783 shdr->Command != SMB2_NEGOTIATE) {
d7d7a66a 784 spin_unlock(&server->srv_lock);
2084ed57 785 return -EAGAIN;
080dc5e5 786 }
d7d7a66a 787 spin_unlock(&server->srv_lock);
2084ed57 788
d7d7a66a 789 spin_lock(&ses->ses_lock);
dd3cd870 790 if (ses->ses_status == SES_NEW) {
31473fc4 791 if ((shdr->Command != SMB2_SESSION_SETUP) &&
080dc5e5 792 (shdr->Command != SMB2_NEGOTIATE)) {
d7d7a66a 793 spin_unlock(&ses->ses_lock);
2dc7e1c0 794 return -EAGAIN;
080dc5e5 795 }
2dc7e1c0
PS
796 /* else ok - we are setting up session */
797 }
7f48558e 798
dd3cd870 799 if (ses->ses_status == SES_EXITING) {
080dc5e5 800 if (shdr->Command != SMB2_LOGOFF) {
d7d7a66a 801 spin_unlock(&ses->ses_lock);
7f48558e 802 return -EAGAIN;
080dc5e5 803 }
7f48558e
SP
804 /* else ok - we are shutting down the session */
805 }
d7d7a66a 806 spin_unlock(&ses->ses_lock);
7f48558e 807
f780bd3f 808 *mid = smb2_mid_entry_alloc(shdr, server);
2dc7e1c0
PS
809 if (*mid == NULL)
810 return -ENOMEM;
d7d7a66a 811 spin_lock(&server->mid_lock);
f780bd3f 812 list_add_tail(&(*mid)->qhead, &server->pending_mid_q);
d7d7a66a 813 spin_unlock(&server->mid_lock);
53a3e0d9 814
2dc7e1c0
PS
815 return 0;
816}
817
818int
819smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
820 bool log_error)
821{
e19b2bc0 822 unsigned int len = mid->resp_buf_size;
977b6170 823 struct kvec iov[1];
738f9de5 824 struct smb_rqst rqst = { .rq_iov = iov,
977b6170 825 .rq_nvec = 1 };
0b688cfc 826
738f9de5 827 iov[0].iov_base = (char *)mid->resp_buf;
977b6170 828 iov[0].iov_len = len;
2dc7e1c0
PS
829
830 dump_smb(mid->resp_buf, min_t(u32, 80, len));
831 /* convert the length into a more usable form */
4326ed2f 832 if (len > 24 && server->sign && !mid->decrypted) {
3c1bf7e4
PS
833 int rc;
834
0b688cfc 835 rc = smb2_verify_signature(&rqst, server);
3c1bf7e4 836 if (rc)
afe6f653 837 cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n",
f96637be 838 rc);
3c1bf7e4 839 }
2dc7e1c0
PS
840
841 return map_smb2_to_linux_error(mid->resp_buf, log_error);
842}
843
fec344e3 844struct mid_q_entry *
f780bd3f
AA
845smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
846 struct smb_rqst *rqst)
2dc7e1c0
PS
847{
848 int rc;
0d35e382
RS
849 struct smb2_hdr *shdr =
850 (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
2dc7e1c0
PS
851 struct mid_q_entry *mid;
852
f780bd3f 853 smb2_seq_num_into_buf(server, shdr);
2dc7e1c0 854
f780bd3f 855 rc = smb2_get_mid_entry(ses, server, shdr, &mid);
c781af7e 856 if (rc) {
f780bd3f 857 revert_current_mid_from_hdr(server, shdr);
fec344e3 858 return ERR_PTR(rc);
c781af7e
PS
859 }
860
f780bd3f 861 rc = smb2_sign_rqst(rqst, server);
fec344e3 862 if (rc) {
f780bd3f 863 revert_current_mid_from_hdr(server, shdr);
70f08f91 864 delete_mid(mid);
fec344e3
JL
865 return ERR_PTR(rc);
866 }
c781af7e 867
fec344e3 868 return mid;
2dc7e1c0
PS
869}
870
fec344e3
JL
871struct mid_q_entry *
872smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
c95b8eed 873{
fec344e3 874 int rc;
0d35e382
RS
875 struct smb2_hdr *shdr =
876 (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
c95b8eed
PS
877 struct mid_q_entry *mid;
878
d7d7a66a 879 spin_lock(&server->srv_lock);
2084ed57 880 if (server->tcpStatus == CifsNeedNegotiate &&
080dc5e5 881 shdr->Command != SMB2_NEGOTIATE) {
d7d7a66a 882 spin_unlock(&server->srv_lock);
2084ed57 883 return ERR_PTR(-EAGAIN);
080dc5e5 884 }
d7d7a66a 885 spin_unlock(&server->srv_lock);
2084ed57 886
31473fc4 887 smb2_seq_num_into_buf(server, shdr);
c95b8eed 888
31473fc4 889 mid = smb2_mid_entry_alloc(shdr, server);
c781af7e
PS
890 if (mid == NULL) {
891 revert_current_mid_from_hdr(server, shdr);
fec344e3 892 return ERR_PTR(-ENOMEM);
c781af7e 893 }
c95b8eed 894
fec344e3 895 rc = smb2_sign_rqst(rqst, server);
c95b8eed 896 if (rc) {
c781af7e 897 revert_current_mid_from_hdr(server, shdr);
70f08f91 898 release_mid(mid);
fec344e3 899 return ERR_PTR(rc);
3c1bf7e4
PS
900 }
901
fec344e3 902 return mid;
c95b8eed 903}
026e93dc
PS
904
905int
906smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
907{
908 struct crypto_aead *tfm;
909
8698baa1 910 if (!server->secmech.enc) {
63ca5656
SF
911 if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
912 (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
2b2f7548
SF
913 tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
914 else
915 tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
026e93dc 916 if (IS_ERR(tfm)) {
63ca5656 917 cifs_server_dbg(VFS, "%s: Failed alloc encrypt aead\n",
026e93dc
PS
918 __func__);
919 return PTR_ERR(tfm);
920 }
8698baa1 921 server->secmech.enc = tfm;
026e93dc
PS
922 }
923
8698baa1 924 if (!server->secmech.dec) {
63ca5656
SF
925 if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
926 (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
2b2f7548
SF
927 tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
928 else
929 tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
026e93dc 930 if (IS_ERR(tfm)) {
8698baa1
EM
931 crypto_free_aead(server->secmech.enc);
932 server->secmech.enc = NULL;
afe6f653 933 cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n",
026e93dc
PS
934 __func__);
935 return PTR_ERR(tfm);
936 }
8698baa1 937 server->secmech.dec = tfm;
026e93dc
PS
938 }
939
940 return 0;
941}